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/common/appcache_interfaces.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_job_factory.h"
49 #include "net/url_request/url_request_simple_job.h"
50 #include "net/url_request/url_request_test_job.h"
51 #include "net/url_request/url_request_test_util.h"
52 #include "testing/gtest/include/gtest/gtest.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) {
81 ResourceDispatcherHostImpl::Get()->OnMessageReceived(
82 *message, filter.get());
85 // On Windows, ResourceMsg_SetDataBuffer supplies a HANDLE which is not
86 // automatically released.
88 // See ResourceDispatcher::ReleaseResourcesInDataMessage.
90 // TODO(davidben): It would be nice if the behavior for base::SharedMemoryHandle
91 // were more like it is in POSIX where the received fds are tracked in a
92 // ref-counted core that closes them if not extracted.
93 void ReleaseHandlesInMessage(const IPC::Message& message) {
94 if (message.type() == ResourceMsg_SetDataBuffer::ID) {
95 PickleIterator iter(message);
97 CHECK(message.ReadInt(&iter, &request_id));
98 base::SharedMemoryHandle shm_handle;
99 if (IPC::ParamTraits<base::SharedMemoryHandle>::Read(&message,
102 if (base::SharedMemory::IsHandleValid(shm_handle))
103 base::SharedMemory::CloseHandle(shm_handle);
110 static int RequestIDForMessage(const IPC::Message& msg) {
112 switch (msg.type()) {
113 case ResourceMsg_UploadProgress::ID:
114 case ResourceMsg_ReceivedResponse::ID:
115 case ResourceMsg_ReceivedRedirect::ID:
116 case ResourceMsg_SetDataBuffer::ID:
117 case ResourceMsg_DataReceived::ID:
118 case ResourceMsg_DataDownloaded::ID:
119 case ResourceMsg_RequestComplete::ID: {
120 bool result = PickleIterator(msg).ReadInt(&request_id);
128 static ResourceHostMsg_Request CreateResourceRequest(const char* method,
131 ResourceHostMsg_Request request;
132 request.method = std::string(method);
134 request.first_party_for_cookies = url; // bypass third-party cookie blocking
135 request.referrer_policy = blink::WebReferrerPolicyDefault;
136 request.load_flags = 0;
137 request.origin_pid = 0;
138 request.resource_type = type;
139 request.request_context = 0;
140 request.appcache_host_id = kAppCacheNoHostId;
141 request.download_to_file = false;
142 request.is_main_frame = true;
143 request.parent_is_main_frame = false;
144 request.parent_render_frame_id = -1;
145 request.transition_type = PAGE_TRANSITION_LINK;
146 request.allow_download = true;
150 // Spin up the message loop to kick off the request.
151 static void KickOffRequest() {
152 base::MessageLoop::current()->RunUntilIdle();
155 // We may want to move this to a shared space if it is useful for something else
156 class ResourceIPCAccumulator {
158 ~ResourceIPCAccumulator() {
159 for (size_t i = 0; i < messages_.size(); i++) {
160 ReleaseHandlesInMessage(messages_[i]);
164 // On Windows, takes ownership of SharedMemoryHandles in |msg|.
165 void AddMessage(const IPC::Message& msg) {
166 messages_.push_back(msg);
169 // This groups the messages by their request ID. The groups will be in order
170 // that the first message for each request ID was received, and the messages
171 // within the groups will be in the order that they appeared.
172 // Note that this clears messages_. The caller takes ownership of any
173 // SharedMemoryHandles in messages placed into |msgs|.
174 typedef std::vector< std::vector<IPC::Message> > ClassifiedMessages;
175 void GetClassifiedMessages(ClassifiedMessages* msgs);
178 std::vector<IPC::Message> messages_;
181 // This is very inefficient as a result of repeatedly extracting the ID, use
183 void ResourceIPCAccumulator::GetClassifiedMessages(ClassifiedMessages* msgs) {
184 while (!messages_.empty()) {
185 // Ignore unknown message types as it is valid for code to generated other
186 // IPCs as side-effects that we are not testing here.
187 int cur_id = RequestIDForMessage(messages_[0]);
189 std::vector<IPC::Message> cur_requests;
190 cur_requests.push_back(messages_[0]);
191 // find all other messages with this ID
192 for (int i = 1; i < static_cast<int>(messages_.size()); i++) {
193 int id = RequestIDForMessage(messages_[i]);
195 cur_requests.push_back(messages_[i]);
196 messages_.erase(messages_.begin() + i);
200 msgs->push_back(cur_requests);
202 messages_.erase(messages_.begin());
206 // This is used to emulate different sub-processes, since this filter will
207 // have a different ID than the original.
208 class TestFilter : public ResourceMessageFilter {
210 explicit TestFilter(ResourceContext* resource_context)
211 : ResourceMessageFilter(
212 ChildProcessHostImpl::GenerateChildProcessUniqueId(),
213 PROCESS_TYPE_RENDERER, NULL, NULL, NULL, NULL,
214 base::Bind(&TestFilter::GetContexts, base::Unretained(this))),
215 resource_context_(resource_context),
217 received_after_canceled_(0) {
218 ChildProcessSecurityPolicyImpl::GetInstance()->Add(child_id());
219 set_peer_pid_for_testing(base::GetCurrentProcId());
222 void set_canceled(bool canceled) { canceled_ = canceled; }
223 int received_after_canceled() const { return received_after_canceled_; }
225 // ResourceMessageFilter override
226 virtual bool Send(IPC::Message* msg) OVERRIDE {
227 // No messages should be received when the process has been canceled.
229 received_after_canceled_++;
230 ReleaseHandlesInMessage(*msg);
235 ResourceContext* resource_context() { return resource_context_; }
238 virtual ~TestFilter() {}
241 void GetContexts(const ResourceHostMsg_Request& request,
242 ResourceContext** resource_context,
243 net::URLRequestContext** request_context) {
244 *resource_context = resource_context_;
245 *request_context = resource_context_->GetRequestContext();
248 ResourceContext* resource_context_;
250 int received_after_canceled_;
252 DISALLOW_COPY_AND_ASSIGN(TestFilter);
256 // This class forwards the incoming messages to the ResourceDispatcherHostTest.
257 // For the test, we want all the incoming messages to go to the same place,
258 // which is why this forwards.
259 class ForwardingFilter : public TestFilter {
261 explicit ForwardingFilter(IPC::Sender* dest,
262 ResourceContext* resource_context)
263 : TestFilter(resource_context),
267 // TestFilter override
268 virtual bool Send(IPC::Message* msg) OVERRIDE {
269 return dest_->Send(msg);
273 virtual ~ForwardingFilter() {}
277 DISALLOW_COPY_AND_ASSIGN(ForwardingFilter);
280 // This class is a variation on URLRequestTestJob that will call
281 // URLRequest::WillStartUsingNetwork before starting.
282 class URLRequestTestDelayedNetworkJob : public net::URLRequestTestJob {
284 URLRequestTestDelayedNetworkJob(net::URLRequest* request,
285 net::NetworkDelegate* network_delegate)
286 : net::URLRequestTestJob(request, network_delegate) {}
288 // Only start if not deferred for network start.
289 virtual void Start() OVERRIDE {
291 NotifyBeforeNetworkStart(&defer);
294 net::URLRequestTestJob::Start();
297 virtual void ResumeNetworkStart() OVERRIDE {
298 net::URLRequestTestJob::StartAsync();
302 virtual ~URLRequestTestDelayedNetworkJob() {}
304 DISALLOW_COPY_AND_ASSIGN(URLRequestTestDelayedNetworkJob);
307 // This class is a variation on URLRequestTestJob in that it does
308 // not complete start upon entry, only when specifically told to.
309 class URLRequestTestDelayedStartJob : public net::URLRequestTestJob {
311 URLRequestTestDelayedStartJob(net::URLRequest* request,
312 net::NetworkDelegate* network_delegate)
313 : net::URLRequestTestJob(request, network_delegate) {
316 URLRequestTestDelayedStartJob(net::URLRequest* request,
317 net::NetworkDelegate* network_delegate,
319 : net::URLRequestTestJob(request, network_delegate, auto_advance) {
322 URLRequestTestDelayedStartJob(net::URLRequest* request,
323 net::NetworkDelegate* network_delegate,
324 const std::string& response_headers,
325 const std::string& response_data,
327 : net::URLRequestTestJob(request,
335 // Do nothing until you're told to.
336 virtual void Start() OVERRIDE {}
338 // Finish starting a URL request whose job is an instance of
339 // URLRequestTestDelayedStartJob. It is illegal to call this routine
340 // with a URLRequest that does not use URLRequestTestDelayedStartJob.
341 static void CompleteStart(net::URLRequest* request) {
342 for (URLRequestTestDelayedStartJob* job = list_head_;
345 if (job->request() == request) {
346 job->net::URLRequestTestJob::Start();
353 static bool DelayedStartQueueEmpty() {
357 static void ClearQueue() {
360 << "Unreleased entries on URLRequestTestDelayedStartJob delay queue"
361 << "; may result in leaks.";
367 virtual ~URLRequestTestDelayedStartJob() {
368 for (URLRequestTestDelayedStartJob** job = &list_head_; *job;
369 job = &(*job)->next_) {
371 *job = (*job)->next_;
384 static URLRequestTestDelayedStartJob* list_head_;
385 URLRequestTestDelayedStartJob* next_;
388 URLRequestTestDelayedStartJob*
389 URLRequestTestDelayedStartJob::list_head_ = NULL;
391 // This class is a variation on URLRequestTestJob in that it
392 // returns IO_pending errors before every read, not just the first one.
393 class URLRequestTestDelayedCompletionJob : public net::URLRequestTestJob {
395 URLRequestTestDelayedCompletionJob(net::URLRequest* request,
396 net::NetworkDelegate* network_delegate)
397 : net::URLRequestTestJob(request, network_delegate) {}
398 URLRequestTestDelayedCompletionJob(net::URLRequest* request,
399 net::NetworkDelegate* network_delegate,
401 : net::URLRequestTestJob(request, network_delegate, auto_advance) {}
402 URLRequestTestDelayedCompletionJob(net::URLRequest* request,
403 net::NetworkDelegate* network_delegate,
404 const std::string& response_headers,
405 const std::string& response_data,
407 : net::URLRequestTestJob(request,
414 virtual ~URLRequestTestDelayedCompletionJob() {}
417 virtual bool NextReadAsync() OVERRIDE { return true; }
420 class URLRequestBigJob : public net::URLRequestSimpleJob {
422 URLRequestBigJob(net::URLRequest* request,
423 net::NetworkDelegate* network_delegate)
424 : net::URLRequestSimpleJob(request, network_delegate) {
427 virtual int GetData(std::string* mime_type,
428 std::string* charset,
430 const net::CompletionCallback& callback) const OVERRIDE {
431 *mime_type = "text/plain";
436 if (!ParseURL(request_->url(), &text, &count))
437 return net::ERR_INVALID_URL;
439 data->reserve(text.size() * count);
440 for (int i = 0; i < count; ++i)
447 virtual ~URLRequestBigJob() {}
449 // big-job:substring,N
450 static bool ParseURL(const GURL& url, std::string* text, int* count) {
451 std::vector<std::string> parts;
452 base::SplitString(url.path(), ',', &parts);
454 if (parts.size() != 2)
458 return base::StringToInt(parts[1], count);
462 class ResourceDispatcherHostTest;
464 class TestURLRequestJobFactory : public net::URLRequestJobFactory {
466 explicit TestURLRequestJobFactory(ResourceDispatcherHostTest* test_fixture)
467 : test_fixture_(test_fixture),
469 delay_complete_(false),
470 network_start_notification_(false),
471 url_request_jobs_created_count_(0) {
474 void HandleScheme(const std::string& scheme) {
475 supported_schemes_.insert(scheme);
478 int url_request_jobs_created_count() const {
479 return url_request_jobs_created_count_;
482 void SetDelayedStartJobGeneration(bool delay_job_start) {
483 delay_start_ = delay_job_start;
486 void SetDelayedCompleteJobGeneration(bool delay_job_complete) {
487 delay_complete_ = delay_job_complete;
490 void SetNetworkStartNotificationJobGeneration(bool notification) {
491 network_start_notification_ = notification;
494 virtual net::URLRequestJob* MaybeCreateJobWithProtocolHandler(
495 const std::string& scheme,
496 net::URLRequest* request,
497 net::NetworkDelegate* network_delegate) const OVERRIDE;
499 virtual bool IsHandledProtocol(const std::string& scheme) const OVERRIDE {
500 return supported_schemes_.count(scheme) > 0;
503 virtual bool IsHandledURL(const GURL& url) const OVERRIDE {
504 return supported_schemes_.count(url.scheme()) > 0;
507 virtual bool IsSafeRedirectTarget(const GURL& location) const OVERRIDE {
512 ResourceDispatcherHostTest* test_fixture_;
514 bool delay_complete_;
515 bool network_start_notification_;
516 mutable int url_request_jobs_created_count_;
517 std::set<std::string> supported_schemes_;
519 DISALLOW_COPY_AND_ASSIGN(TestURLRequestJobFactory);
522 // Associated with an URLRequest to determine if the URLRequest gets deleted.
523 class TestUserData : public base::SupportsUserData::Data {
525 explicit TestUserData(bool* was_deleted)
526 : was_deleted_(was_deleted) {
529 virtual ~TestUserData() {
530 *was_deleted_ = true;
537 class TransfersAllNavigationsContentBrowserClient
538 : public TestContentBrowserClient {
540 virtual bool ShouldSwapProcessesForRedirect(ResourceContext* resource_context,
541 const GURL& current_url,
542 const GURL& new_url) OVERRIDE {
547 enum GenericResourceThrottleFlags {
549 DEFER_STARTING_REQUEST = 1 << 0,
550 DEFER_PROCESSING_RESPONSE = 1 << 1,
551 CANCEL_BEFORE_START = 1 << 2,
552 DEFER_NETWORK_START = 1 << 3
555 // Throttle that tracks the current throttle blocking a request. Only one
556 // can throttle any request at a time.
557 class GenericResourceThrottle : public ResourceThrottle {
559 // The value is used to indicate that the throttle should not provide
560 // a error code when cancelling a request. net::OK is used, because this
561 // is not an error code.
562 static const int USE_DEFAULT_CANCEL_ERROR_CODE = net::OK;
564 GenericResourceThrottle(int flags, int code)
566 error_code_for_cancellation_(code) {
569 virtual ~GenericResourceThrottle() {
570 if (active_throttle_ == this)
571 active_throttle_ = NULL;
574 // ResourceThrottle implementation:
575 virtual void WillStartRequest(bool* defer) OVERRIDE {
576 ASSERT_EQ(NULL, active_throttle_);
577 if (flags_ & DEFER_STARTING_REQUEST) {
578 active_throttle_ = this;
582 if (flags_ & CANCEL_BEFORE_START) {
583 if (error_code_for_cancellation_ == USE_DEFAULT_CANCEL_ERROR_CODE) {
584 controller()->Cancel();
586 controller()->CancelWithError(error_code_for_cancellation_);
591 virtual void WillProcessResponse(bool* defer) OVERRIDE {
592 ASSERT_EQ(NULL, active_throttle_);
593 if (flags_ & DEFER_PROCESSING_RESPONSE) {
594 active_throttle_ = this;
599 virtual void WillStartUsingNetwork(bool* defer) OVERRIDE {
600 ASSERT_EQ(NULL, active_throttle_);
602 if (flags_ & DEFER_NETWORK_START) {
603 active_throttle_ = this;
608 virtual const char* GetNameForLogging() const OVERRIDE {
609 return "GenericResourceThrottle";
613 ASSERT_TRUE(this == active_throttle_);
614 active_throttle_ = NULL;
615 controller()->Resume();
618 static GenericResourceThrottle* active_throttle() {
619 return active_throttle_;
623 int flags_; // bit-wise union of GenericResourceThrottleFlags.
624 int error_code_for_cancellation_;
626 // The currently active throttle, if any.
627 static GenericResourceThrottle* active_throttle_;
630 GenericResourceThrottle* GenericResourceThrottle::active_throttle_ = NULL;
632 class TestResourceDispatcherHostDelegate
633 : public ResourceDispatcherHostDelegate {
635 TestResourceDispatcherHostDelegate()
636 : create_two_throttles_(false),
638 error_code_for_cancellation_(
639 GenericResourceThrottle::USE_DEFAULT_CANCEL_ERROR_CODE) {
642 void set_url_request_user_data(base::SupportsUserData::Data* user_data) {
643 user_data_.reset(user_data);
646 void set_flags(int value) {
650 void set_error_code_for_cancellation(int code) {
651 error_code_for_cancellation_ = code;
654 void set_create_two_throttles(bool create_two_throttles) {
655 create_two_throttles_ = create_two_throttles;
658 // ResourceDispatcherHostDelegate implementation:
660 virtual void RequestBeginning(
661 net::URLRequest* request,
662 ResourceContext* resource_context,
663 AppCacheService* appcache_service,
664 ResourceType resource_type,
667 ScopedVector<ResourceThrottle>* throttles) OVERRIDE {
669 const void* key = user_data_.get();
670 request->SetUserData(key, user_data_.release());
673 if (flags_ != NONE) {
674 throttles->push_back(new GenericResourceThrottle(
675 flags_, error_code_for_cancellation_));
676 if (create_two_throttles_)
677 throttles->push_back(new GenericResourceThrottle(
678 flags_, error_code_for_cancellation_));
683 bool create_two_throttles_;
685 int error_code_for_cancellation_;
686 scoped_ptr<base::SupportsUserData::Data> user_data_;
689 // Waits for a ShareableFileReference to be released.
690 class ShareableFileReleaseWaiter {
692 ShareableFileReleaseWaiter(const base::FilePath& path) {
693 scoped_refptr<ShareableFileReference> file =
694 ShareableFileReference::Get(path);
695 file->AddFinalReleaseCallback(
696 base::Bind(&ShareableFileReleaseWaiter::Released,
697 base::Unretained(this)));
705 void Released(const base::FilePath& path) {
711 DISALLOW_COPY_AND_ASSIGN(ShareableFileReleaseWaiter);
714 class ResourceDispatcherHostTest : public testing::Test,
717 ResourceDispatcherHostTest()
718 : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP),
720 send_data_received_acks_(false) {
721 browser_context_.reset(new TestBrowserContext());
722 BrowserContext::EnsureResourceContextInitialized(browser_context_.get());
723 base::RunLoop().RunUntilIdle();
724 filter_ = MakeForwardingFilter();
725 // TODO(cbentzel): Better way to get URLRequestContext?
726 net::URLRequestContext* request_context =
727 browser_context_->GetResourceContext()->GetRequestContext();
728 job_factory_.reset(new TestURLRequestJobFactory(this));
729 request_context->set_job_factory(job_factory_.get());
730 request_context->set_network_delegate(&network_delegate_);
733 // IPC::Sender implementation
734 virtual bool Send(IPC::Message* msg) OVERRIDE {
735 accum_.AddMessage(*msg);
737 if (send_data_received_acks_ &&
738 msg->type() == ResourceMsg_DataReceived::ID) {
739 GenerateDataReceivedACK(*msg);
742 if (wait_for_request_complete_loop_ &&
743 msg->type() == ResourceMsg_RequestComplete::ID) {
744 wait_for_request_complete_loop_->Quit();
747 // Do not release handles in it yet; the accumulator owns them now.
753 friend class TestURLRequestJobFactory;
756 virtual void SetUp() OVERRIDE {
757 ChildProcessSecurityPolicyImpl::GetInstance()->Add(0);
758 HandleScheme("test");
761 virtual void TearDown() {
762 EXPECT_TRUE(URLRequestTestDelayedStartJob::DelayedStartQueueEmpty());
763 URLRequestTestDelayedStartJob::ClearQueue();
765 for (std::set<int>::iterator it = child_ids_.begin();
766 it != child_ids_.end(); ++it) {
767 host_.CancelRequestsForProcess(*it);
772 ChildProcessSecurityPolicyImpl::GetInstance()->Remove(0);
774 // Flush the message loop to make application verifiers happy.
775 if (ResourceDispatcherHostImpl::Get())
776 ResourceDispatcherHostImpl::Get()->CancelRequestsForContext(
777 browser_context_->GetResourceContext());
779 browser_context_.reset();
780 base::RunLoop().RunUntilIdle();
783 // Creates a new ForwardingFilter and registers it with |child_ids_| so as not
784 // to leak per-child state on test shutdown.
785 ForwardingFilter* MakeForwardingFilter() {
786 ForwardingFilter* filter =
787 new ForwardingFilter(this, browser_context_->GetResourceContext());
788 child_ids_.insert(filter->child_id());
792 // Creates a request using the current test object as the filter and
793 // SubResource as the resource type.
794 void MakeTestRequest(int render_view_id,
798 // Generates a request using the given filter and resource type.
799 void MakeTestRequestWithResourceType(ResourceMessageFilter* filter,
805 void CancelRequest(int request_id);
806 void RendererCancelRequest(int request_id) {
807 ResourceMessageFilter* old_filter = SetFilter(filter_.get());
808 host_.OnCancelRequest(request_id);
809 SetFilter(old_filter);
812 void CompleteStartRequest(int request_id);
813 void CompleteStartRequest(ResourceMessageFilter* filter, int request_id);
815 net::TestNetworkDelegate* network_delegate() { return &network_delegate_; }
817 void EnsureSchemeIsAllowed(const std::string& scheme) {
818 ChildProcessSecurityPolicyImpl* policy =
819 ChildProcessSecurityPolicyImpl::GetInstance();
820 if (!policy->IsWebSafeScheme(scheme))
821 policy->RegisterWebSafeScheme(scheme);
824 // Sets a particular response for any request from now on. To switch back to
825 // the default bahavior, pass an empty |headers|. |headers| should be raw-
826 // formatted (NULLs instead of EOLs).
827 void SetResponse(const std::string& headers, const std::string& data) {
828 response_headers_ = net::HttpUtil::AssembleRawHeaders(headers.data(),
830 response_data_ = data;
832 void SetResponse(const std::string& headers) {
833 SetResponse(headers, std::string());
836 void SendDataReceivedACKs(bool send_acks) {
837 send_data_received_acks_ = send_acks;
840 // Intercepts requests for the given protocol.
841 void HandleScheme(const std::string& scheme) {
842 job_factory_->HandleScheme(scheme);
843 EnsureSchemeIsAllowed(scheme);
846 void GenerateDataReceivedACK(const IPC::Message& msg) {
847 EXPECT_EQ(ResourceMsg_DataReceived::ID, msg.type());
850 bool result = PickleIterator(msg).ReadInt(&request_id);
852 scoped_ptr<IPC::Message> ack(
853 new ResourceHostMsg_DataReceived_ACK(request_id));
855 base::MessageLoop::current()->PostTask(
857 base::Bind(&GenerateIPCMessage, filter_, base::Passed(&ack)));
860 // Setting filters for testing renderer messages.
861 // Returns the previous filter.
862 ResourceMessageFilter* SetFilter(ResourceMessageFilter* new_filter) {
863 ResourceMessageFilter* old_filter = host_.filter_;
864 host_.filter_ = new_filter;
868 void WaitForRequestComplete() {
869 DCHECK(!wait_for_request_complete_loop_);
870 wait_for_request_complete_loop_.reset(new base::RunLoop);
871 wait_for_request_complete_loop_->Run();
872 wait_for_request_complete_loop_.reset();
875 content::TestBrowserThreadBundle thread_bundle_;
876 scoped_ptr<TestBrowserContext> browser_context_;
877 scoped_ptr<TestURLRequestJobFactory> job_factory_;
878 scoped_refptr<ForwardingFilter> filter_;
879 net::TestNetworkDelegate network_delegate_;
880 ResourceDispatcherHostImpl host_;
881 ResourceIPCAccumulator accum_;
882 std::string response_headers_;
883 std::string response_data_;
885 net::URLRequest::ProtocolFactory* old_factory_;
886 bool send_data_received_acks_;
887 std::set<int> child_ids_;
888 scoped_ptr<base::RunLoop> wait_for_request_complete_loop_;
891 void ResourceDispatcherHostTest::MakeTestRequest(int render_view_id,
894 MakeTestRequestWithResourceType(filter_.get(), render_view_id, request_id,
895 url, RESOURCE_TYPE_SUB_RESOURCE);
898 void ResourceDispatcherHostTest::MakeTestRequestWithResourceType(
899 ResourceMessageFilter* filter,
904 ResourceHostMsg_Request request =
905 CreateResourceRequest("GET", type, url);
906 ResourceHostMsg_RequestResource msg(render_view_id, request_id, request);
907 host_.OnMessageReceived(msg, filter);
911 void ResourceDispatcherHostTest::CancelRequest(int request_id) {
912 host_.CancelRequest(filter_->child_id(), request_id);
915 void ResourceDispatcherHostTest::CompleteStartRequest(int request_id) {
916 CompleteStartRequest(filter_.get(), request_id);
919 void ResourceDispatcherHostTest::CompleteStartRequest(
920 ResourceMessageFilter* filter,
922 GlobalRequestID gid(filter->child_id(), request_id);
923 net::URLRequest* req = host_.GetURLRequest(gid);
926 URLRequestTestDelayedStartJob::CompleteStart(req);
929 void CheckRequestCompleteErrorCode(const IPC::Message& message,
930 int expected_error_code) {
931 // Verify the expected error code was received.
935 ASSERT_EQ(ResourceMsg_RequestComplete::ID, message.type());
937 PickleIterator iter(message);
938 ASSERT_TRUE(IPC::ReadParam(&message, &iter, &request_id));
939 ASSERT_TRUE(IPC::ReadParam(&message, &iter, &error_code));
940 ASSERT_EQ(expected_error_code, error_code);
943 testing::AssertionResult ExtractDataOffsetAndLength(const IPC::Message& message,
946 PickleIterator iter(message);
948 if (!IPC::ReadParam(&message, &iter, &request_id))
949 return testing::AssertionFailure() << "Could not read request_id";
950 if (!IPC::ReadParam(&message, &iter, data_offset))
951 return testing::AssertionFailure() << "Could not read data_offset";
952 if (!IPC::ReadParam(&message, &iter, data_length))
953 return testing::AssertionFailure() << "Could not read data_length";
954 return testing::AssertionSuccess();
957 void CheckSuccessfulRequestWithErrorCode(
958 const std::vector<IPC::Message>& messages,
959 const std::string& reference_data,
960 int expected_error) {
961 // A successful request will have received 4 messages:
962 // ReceivedResponse (indicates headers received)
963 // SetDataBuffer (contains shared memory handle)
964 // DataReceived (data offset and length into shared memory)
965 // RequestComplete (request is done)
967 // This function verifies that we received 4 messages and that they are
968 // appropriate. It allows for an error code other than net::OK if the request
969 // should successfully receive data and then abort, e.g., on cancel.
970 ASSERT_EQ(4U, messages.size());
972 // The first messages should be received response
973 ASSERT_EQ(ResourceMsg_ReceivedResponse::ID, messages[0].type());
975 ASSERT_EQ(ResourceMsg_SetDataBuffer::ID, messages[1].type());
977 PickleIterator iter(messages[1]);
979 ASSERT_TRUE(IPC::ReadParam(&messages[1], &iter, &request_id));
980 base::SharedMemoryHandle shm_handle;
981 ASSERT_TRUE(IPC::ReadParam(&messages[1], &iter, &shm_handle));
983 ASSERT_TRUE(IPC::ReadParam(&messages[1], &iter, &shm_size));
985 // Followed by the data, currently we only do the data in one chunk, but
986 // should probably test multiple chunks later
987 ASSERT_EQ(ResourceMsg_DataReceived::ID, messages[2].type());
992 ExtractDataOffsetAndLength(messages[2], &data_offset, &data_length));
994 ASSERT_EQ(reference_data.size(), static_cast<size_t>(data_length));
995 ASSERT_GE(shm_size, data_length);
997 base::SharedMemory shared_mem(shm_handle, true); // read only
998 shared_mem.Map(data_length);
999 const char* data = static_cast<char*>(shared_mem.memory()) + data_offset;
1000 ASSERT_EQ(0, memcmp(reference_data.c_str(), data, data_length));
1002 // The last message should be all data received.
1003 CheckRequestCompleteErrorCode(messages[3], expected_error);
1006 void CheckSuccessfulRequest(const std::vector<IPC::Message>& messages,
1007 const std::string& reference_data) {
1008 CheckSuccessfulRequestWithErrorCode(messages, reference_data, net::OK);
1011 void CheckSuccessfulRedirect(const std::vector<IPC::Message>& messages,
1012 const std::string& reference_data) {
1013 ASSERT_EQ(5U, messages.size());
1014 ASSERT_EQ(ResourceMsg_ReceivedRedirect::ID, messages[0].type());
1016 const std::vector<IPC::Message> second_req_msgs =
1017 std::vector<IPC::Message>(messages.begin() + 1, messages.end());
1018 CheckSuccessfulRequest(second_req_msgs, reference_data);
1021 void CheckFailedRequest(const std::vector<IPC::Message>& messages,
1022 const std::string& reference_data,
1023 int expected_error) {
1024 ASSERT_LT(0U, messages.size());
1025 ASSERT_GE(2U, messages.size());
1026 size_t failure_index = messages.size() - 1;
1028 if (messages.size() == 2) {
1029 EXPECT_EQ(ResourceMsg_ReceivedResponse::ID, messages[0].type());
1032 CheckRequestCompleteErrorCode(messages[failure_index], expected_error);
1035 // Tests whether many messages get dispatched properly.
1036 TEST_F(ResourceDispatcherHostTest, TestMany) {
1037 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
1038 MakeTestRequest(0, 2, net::URLRequestTestJob::test_url_2());
1039 MakeTestRequest(0, 3, net::URLRequestTestJob::test_url_3());
1040 MakeTestRequestWithResourceType(filter_.get(), 0, 4,
1041 net::URLRequestTestJob::test_url_4(),
1042 RESOURCE_TYPE_PREFETCH); // detachable type
1043 MakeTestRequest(0, 5, net::URLRequestTestJob::test_url_redirect_to_url_2());
1045 // Finish the redirection
1046 ResourceHostMsg_FollowRedirect redirect_msg(5);
1047 host_.OnMessageReceived(redirect_msg, filter_.get());
1048 base::MessageLoop::current()->RunUntilIdle();
1050 // flush all the pending requests
1051 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1053 // sorts out all the messages we saw by request
1054 ResourceIPCAccumulator::ClassifiedMessages msgs;
1055 accum_.GetClassifiedMessages(&msgs);
1057 // there are five requests, so we should have gotten them classified as such
1058 ASSERT_EQ(5U, msgs.size());
1060 CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_1());
1061 CheckSuccessfulRequest(msgs[1], net::URLRequestTestJob::test_data_2());
1062 CheckSuccessfulRequest(msgs[2], net::URLRequestTestJob::test_data_3());
1063 CheckSuccessfulRequest(msgs[3], net::URLRequestTestJob::test_data_4());
1064 CheckSuccessfulRedirect(msgs[4], net::URLRequestTestJob::test_data_2());
1067 // Tests whether messages get canceled properly. We issue four requests,
1068 // cancel two of them, and make sure that each sent the proper notifications.
1069 TEST_F(ResourceDispatcherHostTest, Cancel) {
1070 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
1071 MakeTestRequest(0, 2, net::URLRequestTestJob::test_url_2());
1072 MakeTestRequest(0, 3, net::URLRequestTestJob::test_url_3());
1074 MakeTestRequestWithResourceType(filter_.get(), 0, 4,
1075 net::URLRequestTestJob::test_url_4(),
1076 RESOURCE_TYPE_PREFETCH); // detachable type
1080 // Cancel request must come from the renderer for a detachable resource to
1082 RendererCancelRequest(4);
1084 // The handler should have been detached now.
1085 GlobalRequestID global_request_id(filter_->child_id(), 4);
1086 ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest(
1087 host_.GetURLRequest(global_request_id));
1088 ASSERT_TRUE(info->detachable_handler()->is_detached());
1090 // flush all the pending requests
1091 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1092 base::MessageLoop::current()->RunUntilIdle();
1094 // Everything should be out now.
1095 EXPECT_EQ(0, host_.pending_requests());
1097 ResourceIPCAccumulator::ClassifiedMessages msgs;
1098 accum_.GetClassifiedMessages(&msgs);
1100 // there are four requests, so we should have gotten them classified as such
1101 ASSERT_EQ(4U, msgs.size());
1103 CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_1());
1104 CheckSuccessfulRequest(msgs[2], net::URLRequestTestJob::test_data_3());
1106 // Check that request 2 and 4 got canceled, as far as the renderer is
1107 // concerned. Request 2 will have been deleted.
1108 ASSERT_EQ(1U, msgs[1].size());
1109 ASSERT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[1][0].type());
1111 ASSERT_EQ(2U, msgs[3].size());
1112 ASSERT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[3][0].type());
1113 CheckRequestCompleteErrorCode(msgs[3][1], net::ERR_ABORTED);
1115 // However, request 4 should have actually gone to completion. (Only request 2
1117 EXPECT_EQ(4, network_delegate()->completed_requests());
1118 EXPECT_EQ(1, network_delegate()->canceled_requests());
1119 EXPECT_EQ(0, network_delegate()->error_count());
1122 // Shows that detachable requests will timeout if the request takes too long to
1124 TEST_F(ResourceDispatcherHostTest, DetachedResourceTimesOut) {
1125 MakeTestRequestWithResourceType(filter_.get(), 0, 1,
1126 net::URLRequestTestJob::test_url_2(),
1127 RESOURCE_TYPE_PREFETCH); // detachable type
1128 GlobalRequestID global_request_id(filter_->child_id(), 1);
1129 ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest(
1130 host_.GetURLRequest(global_request_id));
1131 ASSERT_TRUE(info->detachable_handler());
1132 info->detachable_handler()->set_cancel_delay(
1133 base::TimeDelta::FromMilliseconds(200));
1134 base::MessageLoop::current()->RunUntilIdle();
1136 RendererCancelRequest(1);
1138 // From the renderer's perspective, the request was cancelled.
1139 ResourceIPCAccumulator::ClassifiedMessages msgs;
1140 accum_.GetClassifiedMessages(&msgs);
1141 ASSERT_EQ(1U, msgs.size());
1142 ASSERT_EQ(2U, msgs[0].size());
1143 ASSERT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[0][0].type());
1144 CheckRequestCompleteErrorCode(msgs[0][1], net::ERR_ABORTED);
1146 // But it continues detached.
1147 EXPECT_EQ(1, host_.pending_requests());
1148 EXPECT_TRUE(info->detachable_handler()->is_detached());
1150 // Wait until after the delay timer times out before we start processing any
1152 base::OneShotTimer<base::MessageLoop> timer;
1153 timer.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(210),
1154 base::MessageLoop::current(), &base::MessageLoop::QuitWhenIdle);
1155 base::MessageLoop::current()->Run();
1157 // The prefetch should be cancelled by now.
1158 EXPECT_EQ(0, host_.pending_requests());
1159 EXPECT_EQ(1, network_delegate()->completed_requests());
1160 EXPECT_EQ(1, network_delegate()->canceled_requests());
1161 EXPECT_EQ(0, network_delegate()->error_count());
1164 // If the filter has disappeared then detachable resources should continue to
1166 TEST_F(ResourceDispatcherHostTest, DeletedFilterDetached) {
1167 // test_url_1's data is available synchronously, so use 2 and 3.
1168 ResourceHostMsg_Request request_prefetch = CreateResourceRequest(
1169 "GET", RESOURCE_TYPE_PREFETCH, net::URLRequestTestJob::test_url_2());
1170 ResourceHostMsg_Request request_ping = CreateResourceRequest(
1171 "GET", RESOURCE_TYPE_PING, net::URLRequestTestJob::test_url_3());
1173 ResourceHostMsg_RequestResource msg_prefetch(0, 1, request_prefetch);
1174 host_.OnMessageReceived(msg_prefetch, filter_);
1175 ResourceHostMsg_RequestResource msg_ping(0, 2, request_ping);
1176 host_.OnMessageReceived(msg_ping, filter_);
1178 // Remove the filter before processing the requests by simulating channel
1180 ResourceRequestInfoImpl* info_prefetch = ResourceRequestInfoImpl::ForRequest(
1181 host_.GetURLRequest(GlobalRequestID(filter_->child_id(), 1)));
1182 ResourceRequestInfoImpl* info_ping = ResourceRequestInfoImpl::ForRequest(
1183 host_.GetURLRequest(GlobalRequestID(filter_->child_id(), 2)));
1184 DCHECK_EQ(filter_.get(), info_prefetch->filter());
1185 DCHECK_EQ(filter_.get(), info_ping->filter());
1186 filter_->OnChannelClosing();
1187 info_prefetch->filter_.reset();
1188 info_ping->filter_.reset();
1190 // From the renderer's perspective, the requests were cancelled.
1191 ResourceIPCAccumulator::ClassifiedMessages msgs;
1192 accum_.GetClassifiedMessages(&msgs);
1193 ASSERT_EQ(2U, msgs.size());
1194 CheckRequestCompleteErrorCode(msgs[0][0], net::ERR_ABORTED);
1195 CheckRequestCompleteErrorCode(msgs[1][0], net::ERR_ABORTED);
1197 // But it continues detached.
1198 EXPECT_EQ(2, host_.pending_requests());
1199 EXPECT_TRUE(info_prefetch->detachable_handler()->is_detached());
1200 EXPECT_TRUE(info_ping->detachable_handler()->is_detached());
1204 // Make sure the requests weren't canceled early.
1205 EXPECT_EQ(2, host_.pending_requests());
1207 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1208 base::MessageLoop::current()->RunUntilIdle();
1210 EXPECT_EQ(0, host_.pending_requests());
1211 EXPECT_EQ(2, network_delegate()->completed_requests());
1212 EXPECT_EQ(0, network_delegate()->canceled_requests());
1213 EXPECT_EQ(0, network_delegate()->error_count());
1216 // If the filter has disappeared (original process dies) then detachable
1217 // resources should continue to load, even when redirected.
1218 TEST_F(ResourceDispatcherHostTest, DeletedFilterDetachedRedirect) {
1219 ResourceHostMsg_Request request = CreateResourceRequest(
1220 "GET", RESOURCE_TYPE_PREFETCH,
1221 net::URLRequestTestJob::test_url_redirect_to_url_2());
1223 ResourceHostMsg_RequestResource msg(0, 1, request);
1224 host_.OnMessageReceived(msg, filter_);
1226 // Remove the filter before processing the request by simulating channel
1228 GlobalRequestID global_request_id(filter_->child_id(), 1);
1229 ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest(
1230 host_.GetURLRequest(global_request_id));
1231 info->filter_->OnChannelClosing();
1232 info->filter_.reset();
1234 // From the renderer's perspective, the request was cancelled.
1235 ResourceIPCAccumulator::ClassifiedMessages msgs;
1236 accum_.GetClassifiedMessages(&msgs);
1237 ASSERT_EQ(1U, msgs.size());
1238 CheckRequestCompleteErrorCode(msgs[0][0], net::ERR_ABORTED);
1240 // But it continues detached.
1241 EXPECT_EQ(1, host_.pending_requests());
1242 EXPECT_TRUE(info->detachable_handler()->is_detached());
1244 // Verify no redirects before resetting the filter.
1245 net::URLRequest* url_request = host_.GetURLRequest(global_request_id);
1246 EXPECT_EQ(1u, url_request->url_chain().size());
1249 // Verify that a redirect was followed.
1250 EXPECT_EQ(2u, url_request->url_chain().size());
1252 // Make sure the request wasn't canceled early.
1253 EXPECT_EQ(1, host_.pending_requests());
1255 // Finish up the request.
1256 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1257 base::MessageLoop::current()->RunUntilIdle();
1259 EXPECT_EQ(0, host_.pending_requests());
1260 EXPECT_EQ(1, network_delegate()->completed_requests());
1261 EXPECT_EQ(0, network_delegate()->canceled_requests());
1262 EXPECT_EQ(0, network_delegate()->error_count());
1265 TEST_F(ResourceDispatcherHostTest, CancelWhileStartIsDeferred) {
1266 bool was_deleted = false;
1268 // Arrange to have requests deferred before starting.
1269 TestResourceDispatcherHostDelegate delegate;
1270 delegate.set_flags(DEFER_STARTING_REQUEST);
1271 delegate.set_url_request_user_data(new TestUserData(&was_deleted));
1272 host_.SetDelegate(&delegate);
1274 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
1275 // We cancel from the renderer because all non-renderer cancels delete
1276 // the request synchronously.
1277 RendererCancelRequest(1);
1279 // Our TestResourceThrottle should not have been deleted yet. This is to
1280 // ensure that destruction of the URLRequest happens asynchronously to
1281 // calling CancelRequest.
1282 EXPECT_FALSE(was_deleted);
1284 base::MessageLoop::current()->RunUntilIdle();
1286 EXPECT_TRUE(was_deleted);
1289 TEST_F(ResourceDispatcherHostTest, DetachWhileStartIsDeferred) {
1290 bool was_deleted = false;
1292 // Arrange to have requests deferred before starting.
1293 TestResourceDispatcherHostDelegate delegate;
1294 delegate.set_flags(DEFER_STARTING_REQUEST);
1295 delegate.set_url_request_user_data(new TestUserData(&was_deleted));
1296 host_.SetDelegate(&delegate);
1298 MakeTestRequestWithResourceType(filter_.get(), 0, 1,
1299 net::URLRequestTestJob::test_url_1(),
1300 RESOURCE_TYPE_PREFETCH); // detachable type
1301 // Cancel request must come from the renderer for a detachable resource to
1303 RendererCancelRequest(1);
1305 // Even after driving the event loop, the request has not been deleted.
1306 EXPECT_FALSE(was_deleted);
1308 // However, it is still throttled because the defer happened above the
1309 // DetachableResourceHandler.
1310 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1311 base::MessageLoop::current()->RunUntilIdle();
1312 EXPECT_FALSE(was_deleted);
1314 // Resume the request.
1315 GenericResourceThrottle* throttle =
1316 GenericResourceThrottle::active_throttle();
1317 ASSERT_TRUE(throttle);
1320 // Now, the request completes.
1321 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1322 base::MessageLoop::current()->RunUntilIdle();
1323 EXPECT_TRUE(was_deleted);
1324 EXPECT_EQ(1, network_delegate()->completed_requests());
1325 EXPECT_EQ(0, network_delegate()->canceled_requests());
1326 EXPECT_EQ(0, network_delegate()->error_count());
1329 // Tests if cancel is called in ResourceThrottle::WillStartRequest, then the
1330 // URLRequest will not be started.
1331 TEST_F(ResourceDispatcherHostTest, CancelInResourceThrottleWillStartRequest) {
1332 TestResourceDispatcherHostDelegate delegate;
1333 delegate.set_flags(CANCEL_BEFORE_START);
1334 host_.SetDelegate(&delegate);
1336 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
1338 // flush all the pending requests
1339 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1340 base::MessageLoop::current()->RunUntilIdle();
1342 ResourceIPCAccumulator::ClassifiedMessages msgs;
1343 accum_.GetClassifiedMessages(&msgs);
1345 // Check that request got canceled.
1346 ASSERT_EQ(1U, msgs[0].size());
1347 CheckRequestCompleteErrorCode(msgs[0][0], net::ERR_ABORTED);
1349 // Make sure URLRequest is never started.
1350 EXPECT_EQ(0, job_factory_->url_request_jobs_created_count());
1353 TEST_F(ResourceDispatcherHostTest, PausedStartError) {
1354 // Arrange to have requests deferred before processing response headers.
1355 TestResourceDispatcherHostDelegate delegate;
1356 delegate.set_flags(DEFER_PROCESSING_RESPONSE);
1357 host_.SetDelegate(&delegate);
1359 job_factory_->SetDelayedStartJobGeneration(true);
1360 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_error());
1361 CompleteStartRequest(1);
1363 // flush all the pending requests
1364 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1365 base::MessageLoop::current()->RunUntilIdle();
1367 EXPECT_EQ(0, host_.pending_requests());
1370 // Test the WillStartUsingNetwork throttle.
1371 TEST_F(ResourceDispatcherHostTest, ThrottleNetworkStart) {
1372 // Arrange to have requests deferred before processing response headers.
1373 TestResourceDispatcherHostDelegate delegate;
1374 delegate.set_flags(DEFER_NETWORK_START);
1375 host_.SetDelegate(&delegate);
1377 job_factory_->SetNetworkStartNotificationJobGeneration(true);
1378 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_2());
1380 // Should have deferred for network start.
1381 GenericResourceThrottle* first_throttle =
1382 GenericResourceThrottle::active_throttle();
1383 ASSERT_TRUE(first_throttle);
1384 EXPECT_EQ(0, network_delegate()->completed_requests());
1385 EXPECT_EQ(1, host_.pending_requests());
1387 first_throttle->Resume();
1389 // Flush all the pending requests.
1390 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1391 base::MessageLoop::current()->RunUntilIdle();
1393 EXPECT_EQ(1, network_delegate()->completed_requests());
1394 EXPECT_EQ(0, host_.pending_requests());
1397 TEST_F(ResourceDispatcherHostTest, ThrottleAndResumeTwice) {
1398 // Arrange to have requests deferred before starting.
1399 TestResourceDispatcherHostDelegate delegate;
1400 delegate.set_flags(DEFER_STARTING_REQUEST);
1401 delegate.set_create_two_throttles(true);
1402 host_.SetDelegate(&delegate);
1404 // Make sure the first throttle blocked the request, and then resume.
1405 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
1406 GenericResourceThrottle* first_throttle =
1407 GenericResourceThrottle::active_throttle();
1408 ASSERT_TRUE(first_throttle);
1409 first_throttle->Resume();
1411 // Make sure the second throttle blocked the request, and then resume.
1412 ASSERT_TRUE(GenericResourceThrottle::active_throttle());
1413 ASSERT_NE(first_throttle, GenericResourceThrottle::active_throttle());
1414 GenericResourceThrottle::active_throttle()->Resume();
1416 ASSERT_FALSE(GenericResourceThrottle::active_throttle());
1418 // The request is started asynchronously.
1419 base::MessageLoop::current()->RunUntilIdle();
1421 // Flush all the pending requests.
1422 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1424 EXPECT_EQ(0, host_.pending_requests());
1426 // Make sure the request completed successfully.
1427 ResourceIPCAccumulator::ClassifiedMessages msgs;
1428 accum_.GetClassifiedMessages(&msgs);
1429 ASSERT_EQ(1U, msgs.size());
1430 CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_1());
1434 // Tests that the delegate can cancel a request and provide a error code.
1435 TEST_F(ResourceDispatcherHostTest, CancelInDelegate) {
1436 TestResourceDispatcherHostDelegate delegate;
1437 delegate.set_flags(CANCEL_BEFORE_START);
1438 delegate.set_error_code_for_cancellation(net::ERR_ACCESS_DENIED);
1439 host_.SetDelegate(&delegate);
1441 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
1442 // The request will get cancelled by the throttle.
1444 // flush all the pending requests
1445 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1446 base::MessageLoop::current()->RunUntilIdle();
1448 ResourceIPCAccumulator::ClassifiedMessages msgs;
1449 accum_.GetClassifiedMessages(&msgs);
1451 // Check the cancellation
1452 ASSERT_EQ(1U, msgs.size());
1453 ASSERT_EQ(1U, msgs[0].size());
1455 CheckRequestCompleteErrorCode(msgs[0][0], net::ERR_ACCESS_DENIED);
1458 // Tests CancelRequestsForProcess
1459 TEST_F(ResourceDispatcherHostTest, TestProcessCancel) {
1460 scoped_refptr<TestFilter> test_filter = new TestFilter(
1461 browser_context_->GetResourceContext());
1462 child_ids_.insert(test_filter->child_id());
1464 // request 1 goes to the test delegate
1465 ResourceHostMsg_Request request = CreateResourceRequest(
1466 "GET", RESOURCE_TYPE_SUB_RESOURCE, net::URLRequestTestJob::test_url_1());
1468 MakeTestRequestWithResourceType(test_filter.get(), 0, 1,
1469 net::URLRequestTestJob::test_url_1(),
1470 RESOURCE_TYPE_SUB_RESOURCE);
1472 // request 2 goes to us
1473 MakeTestRequest(0, 2, net::URLRequestTestJob::test_url_2());
1475 // request 3 goes to the test delegate
1476 MakeTestRequestWithResourceType(test_filter.get(), 0, 3,
1477 net::URLRequestTestJob::test_url_3(),
1478 RESOURCE_TYPE_SUB_RESOURCE);
1480 // request 4 goes to us
1481 MakeTestRequestWithResourceType(filter_.get(), 0, 4,
1482 net::URLRequestTestJob::test_url_4(),
1483 RESOURCE_TYPE_PREFETCH); // detachable type
1486 // Make sure all requests have finished stage one. test_url_1 will have
1488 base::MessageLoop::current()->RunUntilIdle();
1491 // Now that the async IO path is in place, the IO always completes on the
1492 // initial call; so the requests have already completed. This basically
1493 // breaks the whole test.
1494 //EXPECT_EQ(3, host_.pending_requests());
1496 // Process test_url_2 and test_url_3 for one level so one callback is called.
1497 // We'll cancel test_url_4 (detachable) before processing it to verify that it
1498 // delays the cancel.
1499 for (int i = 0; i < 2; i++)
1500 EXPECT_TRUE(net::URLRequestTestJob::ProcessOnePendingMessage());
1502 // Cancel the requests to the test process.
1503 host_.CancelRequestsForProcess(filter_->child_id());
1504 test_filter->set_canceled(true);
1506 // The requests should all be cancelled, except request 4, which is detached.
1507 EXPECT_EQ(1, host_.pending_requests());
1508 GlobalRequestID global_request_id(filter_->child_id(), 4);
1509 ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest(
1510 host_.GetURLRequest(global_request_id));
1511 ASSERT_TRUE(info->detachable_handler()->is_detached());
1513 // Flush all the pending requests.
1514 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1516 EXPECT_EQ(0, host_.pending_requests());
1518 // The test delegate should not have gotten any messages after being canceled.
1519 ASSERT_EQ(0, test_filter->received_after_canceled());
1521 // There should be two results.
1522 ResourceIPCAccumulator::ClassifiedMessages msgs;
1523 accum_.GetClassifiedMessages(&msgs);
1524 ASSERT_EQ(2U, msgs.size());
1525 CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_2());
1526 // The detachable request was cancelled by the renderer before it
1527 // finished. From the perspective of the renderer, it should have cancelled.
1528 ASSERT_EQ(2U, msgs[1].size());
1529 ASSERT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[1][0].type());
1530 CheckRequestCompleteErrorCode(msgs[1][1], net::ERR_ABORTED);
1531 // But it completed anyway. For the network stack, no requests were canceled.
1532 EXPECT_EQ(4, network_delegate()->completed_requests());
1533 EXPECT_EQ(0, network_delegate()->canceled_requests());
1534 EXPECT_EQ(0, network_delegate()->error_count());
1537 TEST_F(ResourceDispatcherHostTest, TestProcessCancelDetachedTimesOut) {
1538 MakeTestRequestWithResourceType(filter_.get(), 0, 1,
1539 net::URLRequestTestJob::test_url_4(),
1540 RESOURCE_TYPE_PREFETCH); // detachable type
1541 GlobalRequestID global_request_id(filter_->child_id(), 1);
1542 ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest(
1543 host_.GetURLRequest(global_request_id));
1544 ASSERT_TRUE(info->detachable_handler());
1545 info->detachable_handler()->set_cancel_delay(
1546 base::TimeDelta::FromMilliseconds(200));
1547 base::MessageLoop::current()->RunUntilIdle();
1549 // Cancel the requests to the test process.
1550 host_.CancelRequestsForProcess(filter_->child_id());
1551 EXPECT_EQ(1, host_.pending_requests());
1553 // Wait until after the delay timer times out before we start processing any
1555 base::OneShotTimer<base::MessageLoop> timer;
1556 timer.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(210),
1557 base::MessageLoop::current(), &base::MessageLoop::QuitWhenIdle);
1558 base::MessageLoop::current()->Run();
1560 // The prefetch should be cancelled by now.
1561 EXPECT_EQ(0, host_.pending_requests());
1563 // In case any messages are still to be processed.
1564 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1565 base::MessageLoop::current()->RunUntilIdle();
1567 ResourceIPCAccumulator::ClassifiedMessages msgs;
1568 accum_.GetClassifiedMessages(&msgs);
1570 ASSERT_EQ(1U, msgs.size());
1572 // The request should have cancelled.
1573 ASSERT_EQ(2U, msgs[0].size());
1574 ASSERT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[0][0].type());
1575 CheckRequestCompleteErrorCode(msgs[0][1], net::ERR_ABORTED);
1576 // And not run to completion.
1577 EXPECT_EQ(1, network_delegate()->completed_requests());
1578 EXPECT_EQ(1, network_delegate()->canceled_requests());
1579 EXPECT_EQ(0, network_delegate()->error_count());
1582 // Tests blocking and resuming requests.
1583 TEST_F(ResourceDispatcherHostTest, TestBlockingResumingRequests) {
1584 host_.BlockRequestsForRoute(filter_->child_id(), 1);
1585 host_.BlockRequestsForRoute(filter_->child_id(), 2);
1586 host_.BlockRequestsForRoute(filter_->child_id(), 3);
1588 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
1589 MakeTestRequest(1, 2, net::URLRequestTestJob::test_url_2());
1590 MakeTestRequest(0, 3, net::URLRequestTestJob::test_url_3());
1591 MakeTestRequest(1, 4, net::URLRequestTestJob::test_url_1());
1592 MakeTestRequest(2, 5, net::URLRequestTestJob::test_url_2());
1593 MakeTestRequest(3, 6, net::URLRequestTestJob::test_url_3());
1595 // Flush all the pending requests
1596 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1598 // Sort out all the messages we saw by request
1599 ResourceIPCAccumulator::ClassifiedMessages msgs;
1600 accum_.GetClassifiedMessages(&msgs);
1602 // All requests but the 2 for the RVH 0 should have been blocked.
1603 ASSERT_EQ(2U, msgs.size());
1605 CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_1());
1606 CheckSuccessfulRequest(msgs[1], net::URLRequestTestJob::test_data_3());
1608 // Resume requests for RVH 1 and flush pending requests.
1609 host_.ResumeBlockedRequestsForRoute(filter_->child_id(), 1);
1611 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1614 accum_.GetClassifiedMessages(&msgs);
1615 ASSERT_EQ(2U, msgs.size());
1616 CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_2());
1617 CheckSuccessfulRequest(msgs[1], net::URLRequestTestJob::test_data_1());
1619 // Test that new requests are not blocked for RVH 1.
1620 MakeTestRequest(1, 7, net::URLRequestTestJob::test_url_1());
1621 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1623 accum_.GetClassifiedMessages(&msgs);
1624 ASSERT_EQ(1U, msgs.size());
1625 CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_1());
1627 // Now resumes requests for all RVH (2 and 3).
1628 host_.ResumeBlockedRequestsForRoute(filter_->child_id(), 2);
1629 host_.ResumeBlockedRequestsForRoute(filter_->child_id(), 3);
1631 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1634 accum_.GetClassifiedMessages(&msgs);
1635 ASSERT_EQ(2U, msgs.size());
1636 CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_2());
1637 CheckSuccessfulRequest(msgs[1], net::URLRequestTestJob::test_data_3());
1640 // Tests blocking and canceling requests.
1641 TEST_F(ResourceDispatcherHostTest, TestBlockingCancelingRequests) {
1642 host_.BlockRequestsForRoute(filter_->child_id(), 1);
1644 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
1645 MakeTestRequest(1, 2, net::URLRequestTestJob::test_url_2());
1646 MakeTestRequest(0, 3, net::URLRequestTestJob::test_url_3());
1647 MakeTestRequest(1, 4, net::URLRequestTestJob::test_url_1());
1648 // Blocked detachable resources should not delay cancellation.
1649 MakeTestRequestWithResourceType(filter_.get(), 1, 5,
1650 net::URLRequestTestJob::test_url_4(),
1651 RESOURCE_TYPE_PREFETCH); // detachable type
1653 // Flush all the pending requests.
1654 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1656 // Sort out all the messages we saw by request.
1657 ResourceIPCAccumulator::ClassifiedMessages msgs;
1658 accum_.GetClassifiedMessages(&msgs);
1660 // The 2 requests for the RVH 0 should have been processed.
1661 ASSERT_EQ(2U, msgs.size());
1663 CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_1());
1664 CheckSuccessfulRequest(msgs[1], net::URLRequestTestJob::test_data_3());
1666 // Cancel requests for RVH 1.
1667 host_.CancelBlockedRequestsForRoute(filter_->child_id(), 1);
1669 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1672 accum_.GetClassifiedMessages(&msgs);
1673 ASSERT_EQ(0U, msgs.size());
1676 // Tests that blocked requests are canceled if their associated process dies.
1677 TEST_F(ResourceDispatcherHostTest, TestBlockedRequestsProcessDies) {
1678 // This second filter is used to emulate a second process.
1679 scoped_refptr<ForwardingFilter> second_filter = MakeForwardingFilter();
1681 host_.BlockRequestsForRoute(second_filter->child_id(), 0);
1683 MakeTestRequestWithResourceType(filter_.get(), 0, 1,
1684 net::URLRequestTestJob::test_url_1(),
1685 RESOURCE_TYPE_SUB_RESOURCE);
1686 MakeTestRequestWithResourceType(second_filter.get(), 0, 2,
1687 net::URLRequestTestJob::test_url_2(),
1688 RESOURCE_TYPE_SUB_RESOURCE);
1689 MakeTestRequestWithResourceType(filter_.get(), 0, 3,
1690 net::URLRequestTestJob::test_url_3(),
1691 RESOURCE_TYPE_SUB_RESOURCE);
1692 MakeTestRequestWithResourceType(second_filter.get(), 0, 4,
1693 net::URLRequestTestJob::test_url_1(),
1694 RESOURCE_TYPE_SUB_RESOURCE);
1695 MakeTestRequestWithResourceType(second_filter.get(), 0, 5,
1696 net::URLRequestTestJob::test_url_4(),
1697 RESOURCE_TYPE_PREFETCH); // detachable type
1699 // Simulate process death.
1700 host_.CancelRequestsForProcess(second_filter->child_id());
1702 // Flush all the pending requests.
1703 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1705 // Sort out all the messages we saw by request.
1706 ResourceIPCAccumulator::ClassifiedMessages msgs;
1707 accum_.GetClassifiedMessages(&msgs);
1709 // The 2 requests for the RVH 0 should have been processed. Note that
1710 // blocked detachable requests are canceled without delay.
1711 ASSERT_EQ(2U, msgs.size());
1713 CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_1());
1714 CheckSuccessfulRequest(msgs[1], net::URLRequestTestJob::test_data_3());
1716 EXPECT_TRUE(host_.blocked_loaders_map_.empty());
1719 // Tests that blocked requests don't leak when the ResourceDispatcherHost goes
1720 // away. Note that we rely on Purify for finding the leaks if any.
1721 // If this test turns the Purify bot red, check the ResourceDispatcherHost
1722 // destructor to make sure the blocked requests are deleted.
1723 TEST_F(ResourceDispatcherHostTest, TestBlockedRequestsDontLeak) {
1724 // This second filter is used to emulate a second process.
1725 scoped_refptr<ForwardingFilter> second_filter = MakeForwardingFilter();
1727 host_.BlockRequestsForRoute(filter_->child_id(), 1);
1728 host_.BlockRequestsForRoute(filter_->child_id(), 2);
1729 host_.BlockRequestsForRoute(second_filter->child_id(), 1);
1731 MakeTestRequestWithResourceType(filter_.get(), 0, 1,
1732 net::URLRequestTestJob::test_url_1(),
1733 RESOURCE_TYPE_SUB_RESOURCE);
1734 MakeTestRequestWithResourceType(filter_.get(), 1, 2,
1735 net::URLRequestTestJob::test_url_2(),
1736 RESOURCE_TYPE_SUB_RESOURCE);
1737 MakeTestRequestWithResourceType(filter_.get(), 0, 3,
1738 net::URLRequestTestJob::test_url_3(),
1739 RESOURCE_TYPE_SUB_RESOURCE);
1740 MakeTestRequestWithResourceType(second_filter.get(), 1, 4,
1741 net::URLRequestTestJob::test_url_1(),
1742 RESOURCE_TYPE_SUB_RESOURCE);
1743 MakeTestRequestWithResourceType(filter_.get(), 2, 5,
1744 net::URLRequestTestJob::test_url_2(),
1745 RESOURCE_TYPE_SUB_RESOURCE);
1746 MakeTestRequestWithResourceType(filter_.get(), 2, 6,
1747 net::URLRequestTestJob::test_url_3(),
1748 RESOURCE_TYPE_SUB_RESOURCE);
1749 MakeTestRequestWithResourceType(filter_.get(), 0, 7,
1750 net::URLRequestTestJob::test_url_4(),
1751 RESOURCE_TYPE_PREFETCH); // detachable type
1752 MakeTestRequestWithResourceType(second_filter.get(), 1, 8,
1753 net::URLRequestTestJob::test_url_4(),
1754 RESOURCE_TYPE_PREFETCH); // detachable type
1756 host_.CancelRequestsForProcess(filter_->child_id());
1757 host_.CancelRequestsForProcess(second_filter->child_id());
1759 // Flush all the pending requests.
1760 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1763 // Test the private helper method "CalculateApproximateMemoryCost()".
1764 TEST_F(ResourceDispatcherHostTest, CalculateApproximateMemoryCost) {
1765 net::URLRequestContext context;
1766 net::URLRequest req(
1767 GURL("http://www.google.com"), net::DEFAULT_PRIORITY, NULL, &context);
1769 ResourceDispatcherHostImpl::CalculateApproximateMemoryCost(&req));
1771 // Add 9 bytes of referrer.
1772 req.SetReferrer("123456789");
1774 ResourceDispatcherHostImpl::CalculateApproximateMemoryCost(&req));
1776 // Add 33 bytes of upload content.
1777 std::string upload_content;
1778 upload_content.resize(33);
1779 std::fill(upload_content.begin(), upload_content.end(), 'x');
1780 scoped_ptr<net::UploadElementReader> reader(new net::UploadBytesElementReader(
1781 upload_content.data(), upload_content.size()));
1782 req.set_upload(make_scoped_ptr(
1783 net::UploadDataStream::CreateWithReader(reader.Pass(), 0)));
1785 // Since the upload throttling is disabled, this has no effect on the cost.
1787 ResourceDispatcherHostImpl::CalculateApproximateMemoryCost(&req));
1790 // Test that too much memory for outstanding requests for a particular
1791 // render_process_host_id causes requests to fail.
1792 TEST_F(ResourceDispatcherHostTest, TooMuchOutstandingRequestsMemory) {
1793 // Expected cost of each request as measured by
1794 // ResourceDispatcherHost::CalculateApproximateMemoryCost().
1795 int kMemoryCostOfTest2Req =
1796 ResourceDispatcherHostImpl::kAvgBytesPerOutstandingRequest +
1797 std::string("GET").size() +
1798 net::URLRequestTestJob::test_url_2().spec().size();
1800 // Tighten the bound on the ResourceDispatcherHost, to speed things up.
1801 int kMaxCostPerProcess = 440000;
1802 host_.set_max_outstanding_requests_cost_per_process(kMaxCostPerProcess);
1804 // Determine how many instance of test_url_2() we can request before
1805 // throttling kicks in.
1806 size_t kMaxRequests = kMaxCostPerProcess / kMemoryCostOfTest2Req;
1808 // This second filter is used to emulate a second process.
1809 scoped_refptr<ForwardingFilter> second_filter = MakeForwardingFilter();
1811 // Saturate the number of outstanding requests for our process.
1812 for (size_t i = 0; i < kMaxRequests; ++i) {
1813 MakeTestRequestWithResourceType(filter_.get(), 0, i + 1,
1814 net::URLRequestTestJob::test_url_2(),
1815 RESOURCE_TYPE_SUB_RESOURCE);
1818 // Issue two more requests for our process -- these should fail immediately.
1819 MakeTestRequestWithResourceType(filter_.get(), 0, kMaxRequests + 1,
1820 net::URLRequestTestJob::test_url_2(),
1821 RESOURCE_TYPE_SUB_RESOURCE);
1822 MakeTestRequestWithResourceType(filter_.get(), 0, kMaxRequests + 2,
1823 net::URLRequestTestJob::test_url_2(),
1824 RESOURCE_TYPE_SUB_RESOURCE);
1826 // Issue two requests for the second process -- these should succeed since
1827 // it is just process 0 that is saturated.
1828 MakeTestRequestWithResourceType(second_filter.get(), 0, kMaxRequests + 3,
1829 net::URLRequestTestJob::test_url_2(),
1830 RESOURCE_TYPE_SUB_RESOURCE);
1831 MakeTestRequestWithResourceType(second_filter.get(), 0, kMaxRequests + 4,
1832 net::URLRequestTestJob::test_url_2(),
1833 RESOURCE_TYPE_SUB_RESOURCE);
1835 // Flush all the pending requests.
1836 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1837 base::MessageLoop::current()->RunUntilIdle();
1839 // Sorts out all the messages we saw by request.
1840 ResourceIPCAccumulator::ClassifiedMessages msgs;
1841 accum_.GetClassifiedMessages(&msgs);
1843 // We issued (kMaxRequests + 4) total requests.
1844 ASSERT_EQ(kMaxRequests + 4, msgs.size());
1846 // Check that the first kMaxRequests succeeded.
1847 for (size_t i = 0; i < kMaxRequests; ++i)
1848 CheckSuccessfulRequest(msgs[i], net::URLRequestTestJob::test_data_2());
1850 // Check that the subsequent two requests (kMaxRequests + 1) and
1851 // (kMaxRequests + 2) were failed, since the per-process bound was reached.
1852 for (int i = 0; i < 2; ++i) {
1853 // Should have sent a single RequestComplete message.
1854 int index = kMaxRequests + i;
1855 CheckFailedRequest(msgs[index], net::URLRequestTestJob::test_data_2(),
1856 net::ERR_INSUFFICIENT_RESOURCES);
1859 // The final 2 requests should have succeeded.
1860 CheckSuccessfulRequest(msgs[kMaxRequests + 2],
1861 net::URLRequestTestJob::test_data_2());
1862 CheckSuccessfulRequest(msgs[kMaxRequests + 3],
1863 net::URLRequestTestJob::test_data_2());
1866 // Test that when too many requests are outstanding for a particular
1867 // render_process_host_id, any subsequent request from it fails. Also verify
1868 // that the global limit is honored.
1869 TEST_F(ResourceDispatcherHostTest, TooManyOutstandingRequests) {
1870 // Tighten the bound on the ResourceDispatcherHost, to speed things up.
1871 const size_t kMaxRequestsPerProcess = 2;
1872 host_.set_max_num_in_flight_requests_per_process(kMaxRequestsPerProcess);
1873 const size_t kMaxRequests = 3;
1874 host_.set_max_num_in_flight_requests(kMaxRequests);
1876 // Needed to emulate additional processes.
1877 scoped_refptr<ForwardingFilter> second_filter = MakeForwardingFilter();
1878 scoped_refptr<ForwardingFilter> third_filter = MakeForwardingFilter();
1880 // Saturate the number of outstanding requests for our process.
1881 for (size_t i = 0; i < kMaxRequestsPerProcess; ++i) {
1882 MakeTestRequestWithResourceType(filter_.get(), 0, i + 1,
1883 net::URLRequestTestJob::test_url_2(),
1884 RESOURCE_TYPE_SUB_RESOURCE);
1887 // Issue another request for our process -- this should fail immediately.
1888 MakeTestRequestWithResourceType(filter_.get(), 0, kMaxRequestsPerProcess + 1,
1889 net::URLRequestTestJob::test_url_2(),
1890 RESOURCE_TYPE_SUB_RESOURCE);
1892 // Issue a request for the second process -- this should succeed, because it
1893 // is just process 0 that is saturated.
1894 MakeTestRequestWithResourceType(
1895 second_filter.get(), 0, kMaxRequestsPerProcess + 2,
1896 net::URLRequestTestJob::test_url_2(), RESOURCE_TYPE_SUB_RESOURCE);
1898 // Issue a request for the third process -- this should fail, because the
1899 // global limit has been reached.
1900 MakeTestRequestWithResourceType(
1901 third_filter.get(), 0, kMaxRequestsPerProcess + 3,
1902 net::URLRequestTestJob::test_url_2(), RESOURCE_TYPE_SUB_RESOURCE);
1904 // Flush all the pending requests.
1905 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1906 base::MessageLoop::current()->RunUntilIdle();
1908 // Sorts out all the messages we saw by request.
1909 ResourceIPCAccumulator::ClassifiedMessages msgs;
1910 accum_.GetClassifiedMessages(&msgs);
1912 // The processes issued the following requests:
1913 // #1 issued kMaxRequestsPerProcess that passed + 1 that failed
1914 // #2 issued 1 request that passed
1915 // #3 issued 1 request that failed
1916 ASSERT_EQ((kMaxRequestsPerProcess + 1) + 1 + 1, msgs.size());
1918 for (size_t i = 0; i < kMaxRequestsPerProcess; ++i)
1919 CheckSuccessfulRequest(msgs[i], net::URLRequestTestJob::test_data_2());
1921 CheckFailedRequest(msgs[kMaxRequestsPerProcess + 0],
1922 net::URLRequestTestJob::test_data_2(),
1923 net::ERR_INSUFFICIENT_RESOURCES);
1924 CheckSuccessfulRequest(msgs[kMaxRequestsPerProcess + 1],
1925 net::URLRequestTestJob::test_data_2());
1926 CheckFailedRequest(msgs[kMaxRequestsPerProcess + 2],
1927 net::URLRequestTestJob::test_data_2(),
1928 net::ERR_INSUFFICIENT_RESOURCES);
1931 // Tests that we sniff the mime type for a simple request.
1932 TEST_F(ResourceDispatcherHostTest, MimeSniffed) {
1933 std::string raw_headers("HTTP/1.1 200 OK\n\n");
1934 std::string response_data("<html><title>Test One</title></html>");
1935 SetResponse(raw_headers, response_data);
1937 HandleScheme("http");
1938 MakeTestRequest(0, 1, GURL("http:bla"));
1940 // Flush all pending requests.
1941 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1943 // Sorts out all the messages we saw by request.
1944 ResourceIPCAccumulator::ClassifiedMessages msgs;
1945 accum_.GetClassifiedMessages(&msgs);
1946 ASSERT_EQ(1U, msgs.size());
1948 ResourceResponseHead response_head;
1949 GetResponseHead(msgs[0], &response_head);
1950 ASSERT_EQ("text/html", response_head.mime_type);
1953 // Tests that we don't sniff the mime type when the server provides one.
1954 TEST_F(ResourceDispatcherHostTest, MimeNotSniffed) {
1955 std::string raw_headers("HTTP/1.1 200 OK\n"
1956 "Content-type: image/jpeg\n\n");
1957 std::string response_data("<html><title>Test One</title></html>");
1958 SetResponse(raw_headers, response_data);
1960 HandleScheme("http");
1961 MakeTestRequest(0, 1, GURL("http:bla"));
1963 // Flush all pending requests.
1964 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1966 // Sorts out all the messages we saw by request.
1967 ResourceIPCAccumulator::ClassifiedMessages msgs;
1968 accum_.GetClassifiedMessages(&msgs);
1969 ASSERT_EQ(1U, msgs.size());
1971 ResourceResponseHead response_head;
1972 GetResponseHead(msgs[0], &response_head);
1973 ASSERT_EQ("image/jpeg", response_head.mime_type);
1976 // Tests that we don't sniff the mime type when there is no message body.
1977 TEST_F(ResourceDispatcherHostTest, MimeNotSniffed2) {
1978 SetResponse("HTTP/1.1 304 Not Modified\n\n");
1980 HandleScheme("http");
1981 MakeTestRequest(0, 1, GURL("http:bla"));
1983 // Flush all pending requests.
1984 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1986 // Sorts out all the messages we saw by request.
1987 ResourceIPCAccumulator::ClassifiedMessages msgs;
1988 accum_.GetClassifiedMessages(&msgs);
1989 ASSERT_EQ(1U, msgs.size());
1991 ResourceResponseHead response_head;
1992 GetResponseHead(msgs[0], &response_head);
1993 ASSERT_EQ("", response_head.mime_type);
1996 TEST_F(ResourceDispatcherHostTest, MimeSniff204) {
1997 SetResponse("HTTP/1.1 204 No Content\n\n");
1999 HandleScheme("http");
2000 MakeTestRequest(0, 1, GURL("http:bla"));
2002 // Flush all pending requests.
2003 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2005 // Sorts out all the messages we saw by request.
2006 ResourceIPCAccumulator::ClassifiedMessages msgs;
2007 accum_.GetClassifiedMessages(&msgs);
2008 ASSERT_EQ(1U, msgs.size());
2010 ResourceResponseHead response_head;
2011 GetResponseHead(msgs[0], &response_head);
2012 ASSERT_EQ("text/plain", response_head.mime_type);
2015 TEST_F(ResourceDispatcherHostTest, MimeSniffEmpty) {
2016 SetResponse("HTTP/1.1 200 OK\n\n");
2018 HandleScheme("http");
2019 MakeTestRequest(0, 1, GURL("http:bla"));
2021 // Flush all pending requests.
2022 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2024 // Sorts out all the messages we saw by request.
2025 ResourceIPCAccumulator::ClassifiedMessages msgs;
2026 accum_.GetClassifiedMessages(&msgs);
2027 ASSERT_EQ(1U, msgs.size());
2029 ResourceResponseHead response_head;
2030 GetResponseHead(msgs[0], &response_head);
2031 ASSERT_EQ("text/plain", response_head.mime_type);
2034 // Tests for crbug.com/31266 (Non-2xx + application/octet-stream).
2035 TEST_F(ResourceDispatcherHostTest, ForbiddenDownload) {
2036 std::string raw_headers("HTTP/1.1 403 Forbidden\n"
2037 "Content-disposition: attachment; filename=blah\n"
2038 "Content-type: application/octet-stream\n\n");
2039 std::string response_data("<html><title>Test One</title></html>");
2040 SetResponse(raw_headers, response_data);
2042 HandleScheme("http");
2044 // Only MAIN_FRAMEs can trigger a download.
2045 MakeTestRequestWithResourceType(filter_.get(), 0, 1, GURL("http:bla"),
2046 RESOURCE_TYPE_MAIN_FRAME);
2048 // Flush all pending requests.
2049 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2050 base::MessageLoop::current()->RunUntilIdle();
2052 // Sorts out all the messages we saw by request.
2053 ResourceIPCAccumulator::ClassifiedMessages msgs;
2054 accum_.GetClassifiedMessages(&msgs);
2056 // We should have gotten one RequestComplete message.
2057 ASSERT_EQ(1U, msgs.size());
2058 ASSERT_EQ(1U, msgs[0].size());
2059 EXPECT_EQ(ResourceMsg_RequestComplete::ID, msgs[0][0].type());
2061 // The RequestComplete message should have had the error code of
2062 // ERR_INVALID_RESPONSE.
2063 CheckRequestCompleteErrorCode(msgs[0][0], net::ERR_INVALID_RESPONSE);
2066 // Test for http://crbug.com/76202 . We don't want to destroy a
2067 // download request prematurely when processing a cancellation from
2069 TEST_F(ResourceDispatcherHostTest, IgnoreCancelForDownloads) {
2070 EXPECT_EQ(0, host_.pending_requests());
2072 int render_view_id = 0;
2075 std::string raw_headers("HTTP\n"
2076 "Content-disposition: attachment; filename=foo\n\n");
2077 std::string response_data("01234567890123456789\x01foobar");
2079 // Get past sniffing metrics in the BufferedResourceHandler. Note that
2080 // if we don't get past the sniffing metrics, the result will be that
2081 // the BufferedResourceHandler won't have figured out that it's a download,
2082 // won't have constructed a DownloadResourceHandler, and and the request
2083 // will be successfully canceled below, failing the test.
2084 response_data.resize(1025, ' ');
2086 SetResponse(raw_headers, response_data);
2087 job_factory_->SetDelayedCompleteJobGeneration(true);
2088 HandleScheme("http");
2090 MakeTestRequestWithResourceType(filter_.get(), render_view_id, request_id,
2091 GURL("http://example.com/blah"),
2092 RESOURCE_TYPE_MAIN_FRAME);
2093 // Return some data so that the request is identified as a download
2094 // and the proper resource handlers are created.
2095 EXPECT_TRUE(net::URLRequestTestJob::ProcessOnePendingMessage());
2097 // And now simulate a cancellation coming from the renderer.
2098 ResourceHostMsg_CancelRequest msg(request_id);
2099 host_.OnMessageReceived(msg, filter_.get());
2101 // Since the request had already started processing as a download,
2102 // the cancellation above should have been ignored and the request
2103 // should still be alive.
2104 EXPECT_EQ(1, host_.pending_requests());
2106 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2109 TEST_F(ResourceDispatcherHostTest, CancelRequestsForContext) {
2110 EXPECT_EQ(0, host_.pending_requests());
2112 int render_view_id = 0;
2115 std::string raw_headers("HTTP\n"
2116 "Content-disposition: attachment; filename=foo\n\n");
2117 std::string response_data("01234567890123456789\x01foobar");
2118 // Get past sniffing metrics.
2119 response_data.resize(1025, ' ');
2121 SetResponse(raw_headers, response_data);
2122 job_factory_->SetDelayedCompleteJobGeneration(true);
2123 HandleScheme("http");
2125 MakeTestRequestWithResourceType(filter_.get(), render_view_id, request_id,
2126 GURL("http://example.com/blah"),
2127 RESOURCE_TYPE_MAIN_FRAME);
2128 // Return some data so that the request is identified as a download
2129 // and the proper resource handlers are created.
2130 EXPECT_TRUE(net::URLRequestTestJob::ProcessOnePendingMessage());
2132 // And now simulate a cancellation coming from the renderer.
2133 ResourceHostMsg_CancelRequest msg(request_id);
2134 host_.OnMessageReceived(msg, filter_.get());
2136 // Since the request had already started processing as a download,
2137 // the cancellation above should have been ignored and the request
2138 // should still be alive.
2139 EXPECT_EQ(1, host_.pending_requests());
2141 // Cancelling by other methods shouldn't work either.
2142 host_.CancelRequestsForProcess(render_view_id);
2143 EXPECT_EQ(1, host_.pending_requests());
2145 // Cancelling by context should work.
2146 host_.CancelRequestsForContext(filter_->resource_context());
2147 EXPECT_EQ(0, host_.pending_requests());
2150 TEST_F(ResourceDispatcherHostTest, CancelRequestsForContextDetached) {
2151 EXPECT_EQ(0, host_.pending_requests());
2153 int render_view_id = 0;
2156 MakeTestRequestWithResourceType(filter_.get(), render_view_id, request_id,
2157 net::URLRequestTestJob::test_url_4(),
2158 RESOURCE_TYPE_PREFETCH); // detachable type
2160 // Simulate a cancel coming from the renderer.
2161 RendererCancelRequest(request_id);
2163 // Since the request had already started processing as detachable,
2164 // the cancellation above should have been ignored and the request
2165 // should have been detached.
2166 EXPECT_EQ(1, host_.pending_requests());
2168 // Cancelling by other methods should also leave it detached.
2169 host_.CancelRequestsForProcess(render_view_id);
2170 EXPECT_EQ(1, host_.pending_requests());
2172 // Cancelling by context should work.
2173 host_.CancelRequestsForContext(filter_->resource_context());
2174 EXPECT_EQ(0, host_.pending_requests());
2177 // Test the cancelling of requests that are being transferred to a new renderer
2178 // due to a redirection.
2179 TEST_F(ResourceDispatcherHostTest, CancelRequestsForContextTransferred) {
2180 EXPECT_EQ(0, host_.pending_requests());
2182 int render_view_id = 0;
2185 std::string raw_headers("HTTP/1.1 200 OK\n"
2186 "Content-Type: text/html; charset=utf-8\n\n");
2187 std::string response_data("<html>foobar</html>");
2189 SetResponse(raw_headers, response_data);
2190 HandleScheme("http");
2192 MakeTestRequestWithResourceType(filter_.get(), render_view_id, request_id,
2193 GURL("http://example.com/blah"),
2194 RESOURCE_TYPE_MAIN_FRAME);
2197 GlobalRequestID global_request_id(filter_->child_id(), request_id);
2198 host_.MarkAsTransferredNavigation(global_request_id);
2200 // And now simulate a cancellation coming from the renderer.
2201 ResourceHostMsg_CancelRequest msg(request_id);
2202 host_.OnMessageReceived(msg, filter_.get());
2204 // Since the request is marked as being transferred,
2205 // the cancellation above should have been ignored and the request
2206 // should still be alive.
2207 EXPECT_EQ(1, host_.pending_requests());
2209 // Cancelling by other methods shouldn't work either.
2210 host_.CancelRequestsForProcess(render_view_id);
2211 EXPECT_EQ(1, host_.pending_requests());
2213 // Cancelling by context should work.
2214 host_.CancelRequestsForContext(filter_->resource_context());
2215 EXPECT_EQ(0, host_.pending_requests());
2218 // Test transferred navigations with text/html, which doesn't trigger any
2219 // content sniffing.
2220 TEST_F(ResourceDispatcherHostTest, TransferNavigationHtml) {
2221 // This test expects the cross site request to be leaked, so it can transfer
2222 // the request directly.
2223 CrossSiteResourceHandler::SetLeakRequestsForTesting(true);
2225 EXPECT_EQ(0, host_.pending_requests());
2227 int render_view_id = 0;
2230 // Configure initial request.
2231 SetResponse("HTTP/1.1 302 Found\n"
2232 "Location: http://other.com/blech\n\n");
2234 HandleScheme("http");
2236 // Temporarily replace ContentBrowserClient with one that will trigger the
2237 // transfer navigation code paths.
2238 TransfersAllNavigationsContentBrowserClient new_client;
2239 ContentBrowserClient* old_client = SetBrowserClientForTesting(&new_client);
2241 MakeTestRequestWithResourceType(filter_.get(), render_view_id, request_id,
2242 GURL("http://example.com/blah"),
2243 RESOURCE_TYPE_MAIN_FRAME);
2245 // Now that we're blocked on the redirect, update the response and unblock by
2246 // telling the AsyncResourceHandler to follow the redirect.
2247 const std::string kResponseBody = "hello world";
2248 SetResponse("HTTP/1.1 200 OK\n"
2249 "Content-Type: text/html\n\n",
2251 ResourceHostMsg_FollowRedirect redirect_msg(request_id);
2252 host_.OnMessageReceived(redirect_msg, filter_.get());
2253 base::MessageLoop::current()->RunUntilIdle();
2255 // Flush all the pending requests to get the response through the
2256 // BufferedResourceHandler.
2257 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2259 // Restore, now that we've set up a transfer.
2260 SetBrowserClientForTesting(old_client);
2262 // This second filter is used to emulate a second process.
2263 scoped_refptr<ForwardingFilter> second_filter = MakeForwardingFilter();
2265 int new_render_view_id = 1;
2266 int new_request_id = 2;
2268 ResourceHostMsg_Request request =
2269 CreateResourceRequest("GET", RESOURCE_TYPE_MAIN_FRAME,
2270 GURL("http://other.com/blech"));
2271 request.transferred_request_child_id = filter_->child_id();
2272 request.transferred_request_request_id = request_id;
2274 ResourceHostMsg_RequestResource transfer_request_msg(
2275 new_render_view_id, new_request_id, request);
2276 host_.OnMessageReceived(transfer_request_msg, second_filter.get());
2277 base::MessageLoop::current()->RunUntilIdle();
2279 // Check generated messages.
2280 ResourceIPCAccumulator::ClassifiedMessages msgs;
2281 accum_.GetClassifiedMessages(&msgs);
2283 ASSERT_EQ(2U, msgs.size());
2284 EXPECT_EQ(ResourceMsg_ReceivedRedirect::ID, msgs[0][0].type());
2285 CheckSuccessfulRequest(msgs[1], kResponseBody);
2288 // Test transferred navigations with text/plain, which causes
2289 // BufferedResourceHandler to buffer the response to sniff the content
2290 // before the transfer occurs.
2291 TEST_F(ResourceDispatcherHostTest, TransferNavigationText) {
2292 // This test expects the cross site request to be leaked, so it can transfer
2293 // the request directly.
2294 CrossSiteResourceHandler::SetLeakRequestsForTesting(true);
2296 EXPECT_EQ(0, host_.pending_requests());
2298 int render_view_id = 0;
2301 // Configure initial request.
2302 SetResponse("HTTP/1.1 302 Found\n"
2303 "Location: http://other.com/blech\n\n");
2305 HandleScheme("http");
2307 // Temporarily replace ContentBrowserClient with one that will trigger the
2308 // transfer navigation code paths.
2309 TransfersAllNavigationsContentBrowserClient new_client;
2310 ContentBrowserClient* old_client = SetBrowserClientForTesting(&new_client);
2312 MakeTestRequestWithResourceType(filter_.get(), render_view_id, request_id,
2313 GURL("http://example.com/blah"),
2314 RESOURCE_TYPE_MAIN_FRAME);
2316 // Now that we're blocked on the redirect, update the response and unblock by
2317 // telling the AsyncResourceHandler to follow the redirect. Use a text/plain
2318 // MIME type, which causes BufferedResourceHandler to buffer it before the
2320 const std::string kResponseBody = "hello world";
2321 SetResponse("HTTP/1.1 200 OK\n"
2322 "Content-Type: text/plain\n\n",
2324 ResourceHostMsg_FollowRedirect redirect_msg(request_id);
2325 host_.OnMessageReceived(redirect_msg, filter_.get());
2326 base::MessageLoop::current()->RunUntilIdle();
2328 // Flush all the pending requests to get the response through the
2329 // BufferedResourceHandler.
2330 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2332 // Restore, now that we've set up a transfer.
2333 SetBrowserClientForTesting(old_client);
2335 // This second filter is used to emulate a second process.
2336 scoped_refptr<ForwardingFilter> second_filter = MakeForwardingFilter();
2338 int new_render_view_id = 1;
2339 int new_request_id = 2;
2341 ResourceHostMsg_Request request =
2342 CreateResourceRequest("GET", RESOURCE_TYPE_MAIN_FRAME,
2343 GURL("http://other.com/blech"));
2344 request.transferred_request_child_id = filter_->child_id();
2345 request.transferred_request_request_id = request_id;
2347 ResourceHostMsg_RequestResource transfer_request_msg(
2348 new_render_view_id, new_request_id, request);
2349 host_.OnMessageReceived(transfer_request_msg, second_filter.get());
2350 base::MessageLoop::current()->RunUntilIdle();
2352 // Check generated messages.
2353 ResourceIPCAccumulator::ClassifiedMessages msgs;
2354 accum_.GetClassifiedMessages(&msgs);
2356 ASSERT_EQ(2U, msgs.size());
2357 EXPECT_EQ(ResourceMsg_ReceivedRedirect::ID, msgs[0][0].type());
2358 CheckSuccessfulRequest(msgs[1], kResponseBody);
2361 TEST_F(ResourceDispatcherHostTest, TransferNavigationWithProcessCrash) {
2362 // This test expects the cross site request to be leaked, so it can transfer
2363 // the request directly.
2364 CrossSiteResourceHandler::SetLeakRequestsForTesting(true);
2366 EXPECT_EQ(0, host_.pending_requests());
2368 int render_view_id = 0;
2370 int first_child_id = -1;
2372 // Configure initial request.
2373 SetResponse("HTTP/1.1 302 Found\n"
2374 "Location: http://other.com/blech\n\n");
2375 const std::string kResponseBody = "hello world";
2377 HandleScheme("http");
2379 // Temporarily replace ContentBrowserClient with one that will trigger the
2380 // transfer navigation code paths.
2381 TransfersAllNavigationsContentBrowserClient new_client;
2382 ContentBrowserClient* old_client = SetBrowserClientForTesting(&new_client);
2384 // Create a first filter that can be deleted before the second one starts.
2386 scoped_refptr<ForwardingFilter> first_filter = MakeForwardingFilter();
2387 first_child_id = first_filter->child_id();
2389 ResourceHostMsg_Request first_request =
2390 CreateResourceRequest("GET", RESOURCE_TYPE_MAIN_FRAME,
2391 GURL("http://example.com/blah"));
2393 ResourceHostMsg_RequestResource first_request_msg(
2394 render_view_id, request_id, first_request);
2395 host_.OnMessageReceived(first_request_msg, first_filter.get());
2396 base::MessageLoop::current()->RunUntilIdle();
2398 // Now that we're blocked on the redirect, update the response and unblock
2399 // by telling the AsyncResourceHandler to follow the redirect.
2400 SetResponse("HTTP/1.1 200 OK\n"
2401 "Content-Type: text/html\n\n",
2403 ResourceHostMsg_FollowRedirect redirect_msg(request_id);
2404 host_.OnMessageReceived(redirect_msg, first_filter.get());
2405 base::MessageLoop::current()->RunUntilIdle();
2407 // Flush all the pending requests to get the response through the
2408 // BufferedResourceHandler.
2409 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2411 // The first filter is now deleted, as if the child process died.
2414 SetBrowserClientForTesting(old_client);
2416 // Make sure we don't hold onto the ResourceMessageFilter after it is deleted.
2417 GlobalRequestID first_global_request_id(first_child_id, request_id);
2419 // This second filter is used to emulate a second process.
2420 scoped_refptr<ForwardingFilter> second_filter = MakeForwardingFilter();
2422 int new_render_view_id = 1;
2423 int new_request_id = 2;
2425 ResourceHostMsg_Request request =
2426 CreateResourceRequest("GET", RESOURCE_TYPE_MAIN_FRAME,
2427 GURL("http://other.com/blech"));
2428 request.transferred_request_child_id = first_child_id;
2429 request.transferred_request_request_id = request_id;
2432 child_ids_.insert(second_filter->child_id());
2433 ResourceHostMsg_RequestResource transfer_request_msg(
2434 new_render_view_id, new_request_id, request);
2435 host_.OnMessageReceived(transfer_request_msg, second_filter.get());
2436 base::MessageLoop::current()->RunUntilIdle();
2438 // Check generated messages.
2439 ResourceIPCAccumulator::ClassifiedMessages msgs;
2440 accum_.GetClassifiedMessages(&msgs);
2442 ASSERT_EQ(2U, msgs.size());
2443 EXPECT_EQ(ResourceMsg_ReceivedRedirect::ID, msgs[0][0].type());
2444 CheckSuccessfulRequest(msgs[1], kResponseBody);
2447 TEST_F(ResourceDispatcherHostTest, TransferNavigationWithTwoRedirects) {
2448 // This test expects the cross site request to be leaked, so it can transfer
2449 // the request directly.
2450 CrossSiteResourceHandler::SetLeakRequestsForTesting(true);
2452 EXPECT_EQ(0, host_.pending_requests());
2454 int render_view_id = 0;
2457 // Configure initial request.
2458 SetResponse("HTTP/1.1 302 Found\n"
2459 "Location: http://other.com/blech\n\n");
2461 HandleScheme("http");
2463 // Temporarily replace ContentBrowserClient with one that will trigger the
2464 // transfer navigation code paths.
2465 TransfersAllNavigationsContentBrowserClient new_client;
2466 ContentBrowserClient* old_client = SetBrowserClientForTesting(&new_client);
2468 MakeTestRequestWithResourceType(filter_.get(), render_view_id, request_id,
2469 GURL("http://example.com/blah"),
2470 RESOURCE_TYPE_MAIN_FRAME);
2472 // Now that we're blocked on the redirect, simulate hitting another redirect.
2473 SetResponse("HTTP/1.1 302 Found\n"
2474 "Location: http://other.com/blerg\n\n");
2475 ResourceHostMsg_FollowRedirect redirect_msg(request_id);
2476 host_.OnMessageReceived(redirect_msg, filter_.get());
2477 base::MessageLoop::current()->RunUntilIdle();
2479 // Now that we're blocked on the second redirect, update the response and
2480 // unblock by telling the AsyncResourceHandler to follow the redirect.
2481 // Again, use text/plain to force BufferedResourceHandler to buffer before
2483 const std::string kResponseBody = "hello world";
2484 SetResponse("HTTP/1.1 200 OK\n"
2485 "Content-Type: text/plain\n\n",
2487 ResourceHostMsg_FollowRedirect redirect_msg2(request_id);
2488 host_.OnMessageReceived(redirect_msg2, filter_.get());
2489 base::MessageLoop::current()->RunUntilIdle();
2491 // Flush all the pending requests to get the response through the
2492 // BufferedResourceHandler.
2493 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2496 SetBrowserClientForTesting(old_client);
2498 // This second filter is used to emulate a second process.
2499 scoped_refptr<ForwardingFilter> second_filter = MakeForwardingFilter();
2501 int new_render_view_id = 1;
2502 int new_request_id = 2;
2504 ResourceHostMsg_Request request =
2505 CreateResourceRequest("GET", RESOURCE_TYPE_MAIN_FRAME,
2506 GURL("http://other.com/blech"));
2507 request.transferred_request_child_id = filter_->child_id();
2508 request.transferred_request_request_id = request_id;
2511 child_ids_.insert(second_filter->child_id());
2512 ResourceHostMsg_RequestResource transfer_request_msg(
2513 new_render_view_id, new_request_id, request);
2514 host_.OnMessageReceived(transfer_request_msg, second_filter.get());
2516 // Verify that we update the ResourceRequestInfo.
2517 GlobalRequestID global_request_id(second_filter->child_id(), new_request_id);
2518 const ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest(
2519 host_.GetURLRequest(global_request_id));
2520 EXPECT_EQ(second_filter->child_id(), info->GetChildID());
2521 EXPECT_EQ(new_render_view_id, info->GetRouteID());
2522 EXPECT_EQ(new_request_id, info->GetRequestID());
2523 EXPECT_EQ(second_filter, info->filter());
2525 // Let request complete.
2526 base::MessageLoop::current()->RunUntilIdle();
2528 // Check generated messages.
2529 ResourceIPCAccumulator::ClassifiedMessages msgs;
2530 accum_.GetClassifiedMessages(&msgs);
2532 ASSERT_EQ(2U, msgs.size());
2533 EXPECT_EQ(ResourceMsg_ReceivedRedirect::ID, msgs[0][0].type());
2534 CheckSuccessfulRequest(msgs[1], kResponseBody);
2537 TEST_F(ResourceDispatcherHostTest, UnknownURLScheme) {
2538 EXPECT_EQ(0, host_.pending_requests());
2540 HandleScheme("http");
2542 MakeTestRequestWithResourceType(filter_.get(), 0, 1, GURL("foo://bar"),
2543 RESOURCE_TYPE_MAIN_FRAME);
2545 // Flush all pending requests.
2546 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2548 // Sort all the messages we saw by request.
2549 ResourceIPCAccumulator::ClassifiedMessages msgs;
2550 accum_.GetClassifiedMessages(&msgs);
2552 // We should have gotten one RequestComplete message.
2553 ASSERT_EQ(1U, msgs[0].size());
2554 EXPECT_EQ(ResourceMsg_RequestComplete::ID, msgs[0][0].type());
2556 // The RequestComplete message should have the error code of
2557 // ERR_UNKNOWN_URL_SCHEME.
2558 CheckRequestCompleteErrorCode(msgs[0][0], net::ERR_UNKNOWN_URL_SCHEME);
2561 TEST_F(ResourceDispatcherHostTest, DataReceivedACKs) {
2562 EXPECT_EQ(0, host_.pending_requests());
2564 SendDataReceivedACKs(true);
2566 HandleScheme("big-job");
2567 MakeTestRequest(0, 1, GURL("big-job:0123456789,1000000"));
2569 // Sort all the messages we saw by request.
2570 ResourceIPCAccumulator::ClassifiedMessages msgs;
2571 accum_.GetClassifiedMessages(&msgs);
2573 size_t size = msgs[0].size();
2575 EXPECT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[0][0].type());
2576 EXPECT_EQ(ResourceMsg_SetDataBuffer::ID, msgs[0][1].type());
2577 for (size_t i = 2; i < size - 1; ++i)
2578 EXPECT_EQ(ResourceMsg_DataReceived::ID, msgs[0][i].type());
2579 EXPECT_EQ(ResourceMsg_RequestComplete::ID, msgs[0][size - 1].type());
2582 // Request a very large detachable resource and cancel part way. Some of the
2583 // data should have been sent to the renderer, but not all.
2584 TEST_F(ResourceDispatcherHostTest, DataSentBeforeDetach) {
2585 EXPECT_EQ(0, host_.pending_requests());
2587 int render_view_id = 0;
2590 std::string raw_headers("HTTP\n"
2591 "Content-type: image/jpeg\n\n");
2592 std::string response_data("01234567890123456789\x01foobar");
2594 // Create a response larger than kMaxAllocationSize (currently 32K). Note
2595 // that if this increase beyond 512K we'll need to make the response longer.
2596 const int kAllocSize = 1024*512;
2597 response_data.resize(kAllocSize, ' ');
2599 SetResponse(raw_headers, response_data);
2600 job_factory_->SetDelayedCompleteJobGeneration(true);
2601 HandleScheme("http");
2603 MakeTestRequestWithResourceType(filter_.get(), render_view_id, request_id,
2604 GURL("http://example.com/blah"),
2605 RESOURCE_TYPE_PREFETCH);
2607 // Get a bit of data before cancelling.
2608 EXPECT_TRUE(net::URLRequestTestJob::ProcessOnePendingMessage());
2610 // Simulate a cancellation coming from the renderer.
2611 ResourceHostMsg_CancelRequest msg(request_id);
2612 host_.OnMessageReceived(msg, filter_.get());
2614 EXPECT_EQ(1, host_.pending_requests());
2616 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2618 // Sort all the messages we saw by request.
2619 ResourceIPCAccumulator::ClassifiedMessages msgs;
2620 accum_.GetClassifiedMessages(&msgs);
2622 EXPECT_EQ(4U, msgs[0].size());
2624 // Figure out how many bytes were received by the renderer.
2628 ExtractDataOffsetAndLength(msgs[0][2], &data_offset, &data_length));
2629 EXPECT_LT(0, data_length);
2630 EXPECT_GT(kAllocSize, data_length);
2632 // Verify the data that was received before cancellation. The request should
2633 // have appeared to cancel, however.
2634 CheckSuccessfulRequestWithErrorCode(
2636 std::string(response_data.begin(), response_data.begin() + data_length),
2640 TEST_F(ResourceDispatcherHostTest, DelayedDataReceivedACKs) {
2641 EXPECT_EQ(0, host_.pending_requests());
2643 HandleScheme("big-job");
2644 MakeTestRequest(0, 1, GURL("big-job:0123456789,1000000"));
2646 // Sort all the messages we saw by request.
2647 ResourceIPCAccumulator::ClassifiedMessages msgs;
2648 accum_.GetClassifiedMessages(&msgs);
2650 // We expect 1x ReceivedResponse, 1x SetDataBuffer, Nx ReceivedData messages.
2651 EXPECT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[0][0].type());
2652 EXPECT_EQ(ResourceMsg_SetDataBuffer::ID, msgs[0][1].type());
2653 for (size_t i = 2; i < msgs[0].size(); ++i)
2654 EXPECT_EQ(ResourceMsg_DataReceived::ID, msgs[0][i].type());
2656 // NOTE: If we fail the above checks then it means that we probably didn't
2657 // load a big enough response to trigger the delay mechanism we are trying to
2660 msgs[0].erase(msgs[0].begin());
2661 msgs[0].erase(msgs[0].begin());
2663 // ACK all DataReceived messages until we find a RequestComplete message.
2664 bool complete = false;
2666 for (size_t i = 0; i < msgs[0].size(); ++i) {
2667 if (msgs[0][i].type() == ResourceMsg_RequestComplete::ID) {
2672 EXPECT_EQ(ResourceMsg_DataReceived::ID, msgs[0][i].type());
2674 ResourceHostMsg_DataReceived_ACK msg(1);
2675 host_.OnMessageReceived(msg, filter_.get());
2678 base::MessageLoop::current()->RunUntilIdle();
2681 accum_.GetClassifiedMessages(&msgs);
2685 // Flakyness of this test might indicate memory corruption issues with
2686 // for example the ResourceBuffer of AsyncResourceHandler.
2687 TEST_F(ResourceDispatcherHostTest, DataReceivedUnexpectedACKs) {
2688 EXPECT_EQ(0, host_.pending_requests());
2690 HandleScheme("big-job");
2691 MakeTestRequest(0, 1, GURL("big-job:0123456789,1000000"));
2693 // Sort all the messages we saw by request.
2694 ResourceIPCAccumulator::ClassifiedMessages msgs;
2695 accum_.GetClassifiedMessages(&msgs);
2697 // We expect 1x ReceivedResponse, 1x SetDataBuffer, Nx ReceivedData messages.
2698 EXPECT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[0][0].type());
2699 EXPECT_EQ(ResourceMsg_SetDataBuffer::ID, msgs[0][1].type());
2700 for (size_t i = 2; i < msgs[0].size(); ++i)
2701 EXPECT_EQ(ResourceMsg_DataReceived::ID, msgs[0][i].type());
2703 // NOTE: If we fail the above checks then it means that we probably didn't
2704 // load a big enough response to trigger the delay mechanism.
2706 // Send some unexpected ACKs.
2707 for (size_t i = 0; i < 128; ++i) {
2708 ResourceHostMsg_DataReceived_ACK msg(1);
2709 host_.OnMessageReceived(msg, filter_.get());
2712 msgs[0].erase(msgs[0].begin());
2713 msgs[0].erase(msgs[0].begin());
2715 // ACK all DataReceived messages until we find a RequestComplete message.
2716 bool complete = false;
2718 for (size_t i = 0; i < msgs[0].size(); ++i) {
2719 if (msgs[0][i].type() == ResourceMsg_RequestComplete::ID) {
2724 EXPECT_EQ(ResourceMsg_DataReceived::ID, msgs[0][i].type());
2726 ResourceHostMsg_DataReceived_ACK msg(1);
2727 host_.OnMessageReceived(msg, filter_.get());
2730 base::MessageLoop::current()->RunUntilIdle();
2733 accum_.GetClassifiedMessages(&msgs);
2737 // Tests the dispatcher host's temporary file management.
2738 TEST_F(ResourceDispatcherHostTest, RegisterDownloadedTempFile) {
2739 const int kRequestID = 1;
2741 // Create a temporary file.
2742 base::FilePath file_path;
2743 ASSERT_TRUE(base::CreateTemporaryFile(&file_path));
2744 scoped_refptr<ShareableFileReference> deletable_file =
2745 ShareableFileReference::GetOrCreate(
2747 ShareableFileReference::DELETE_ON_FINAL_RELEASE,
2748 BrowserThread::GetMessageLoopProxyForThread(
2749 BrowserThread::FILE).get());
2752 EXPECT_FALSE(ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
2753 filter_->child_id(), file_path));
2755 // Register it for a resource request.
2756 host_.RegisterDownloadedTempFile(filter_->child_id(), kRequestID, file_path);
2758 // Should be readable now.
2759 EXPECT_TRUE(ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
2760 filter_->child_id(), file_path));
2762 // The child releases from the request.
2763 ResourceHostMsg_ReleaseDownloadedFile release_msg(kRequestID);
2764 host_.OnMessageReceived(release_msg, filter_);
2766 // Still readable because there is another reference to the file. (The child
2767 // may take additional blob references.)
2768 EXPECT_TRUE(ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
2769 filter_->child_id(), file_path));
2771 // Release extra references and wait for the file to be deleted. (This relies
2772 // on the delete happening on the FILE thread which is mapped to main thread
2774 deletable_file = NULL;
2775 base::RunLoop().RunUntilIdle();
2777 // The file is no longer readable to the child and has been deleted.
2778 EXPECT_FALSE(ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
2779 filter_->child_id(), file_path));
2780 EXPECT_FALSE(base::PathExists(file_path));
2783 // Tests that temporary files held on behalf of child processes are released
2784 // when the child process dies.
2785 TEST_F(ResourceDispatcherHostTest, ReleaseTemporiesOnProcessExit) {
2786 const int kRequestID = 1;
2788 // Create a temporary file.
2789 base::FilePath file_path;
2790 ASSERT_TRUE(base::CreateTemporaryFile(&file_path));
2791 scoped_refptr<ShareableFileReference> deletable_file =
2792 ShareableFileReference::GetOrCreate(
2794 ShareableFileReference::DELETE_ON_FINAL_RELEASE,
2795 BrowserThread::GetMessageLoopProxyForThread(
2796 BrowserThread::FILE).get());
2798 // Register it for a resource request.
2799 host_.RegisterDownloadedTempFile(filter_->child_id(), kRequestID, file_path);
2800 deletable_file = NULL;
2802 // Should be readable now.
2803 EXPECT_TRUE(ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
2804 filter_->child_id(), file_path));
2806 // Let the process die.
2807 filter_->OnChannelClosing();
2808 base::RunLoop().RunUntilIdle();
2810 // The file is no longer readable to the child and has been deleted.
2811 EXPECT_FALSE(ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
2812 filter_->child_id(), file_path));
2813 EXPECT_FALSE(base::PathExists(file_path));
2816 TEST_F(ResourceDispatcherHostTest, DownloadToFile) {
2817 // Make a request which downloads to file.
2818 ResourceHostMsg_Request request = CreateResourceRequest(
2819 "GET", RESOURCE_TYPE_SUB_RESOURCE, net::URLRequestTestJob::test_url_1());
2820 request.download_to_file = true;
2821 ResourceHostMsg_RequestResource request_msg(0, 1, request);
2822 host_.OnMessageReceived(request_msg, filter_);
2824 // Running the message loop until idle does not work because
2825 // RedirectToFileResourceHandler posts things to base::WorkerPool. Instead,
2826 // wait for the ResourceMsg_RequestComplete to go out. Then run the event loop
2827 // until idle so the loader is gone.
2828 WaitForRequestComplete();
2829 base::RunLoop().RunUntilIdle();
2830 EXPECT_EQ(0, host_.pending_requests());
2832 ResourceIPCAccumulator::ClassifiedMessages msgs;
2833 accum_.GetClassifiedMessages(&msgs);
2835 ASSERT_EQ(1U, msgs.size());
2836 const std::vector<IPC::Message>& messages = msgs[0];
2838 // The request should contain the following messages:
2839 // ReceivedResponse (indicates headers received and filename)
2840 // DataDownloaded* (bytes downloaded and total length)
2841 // RequestComplete (request is done)
2844 ResourceResponseHead response_head;
2845 GetResponseHead(messages, &response_head);
2846 ASSERT_FALSE(response_head.download_file_path.empty());
2849 size_t total_len = 0;
2850 for (size_t i = 1; i < messages.size() - 1; i++) {
2851 ASSERT_EQ(ResourceMsg_DataDownloaded::ID, messages[i].type());
2852 PickleIterator iter(messages[i]);
2853 int request_id, data_len;
2854 ASSERT_TRUE(IPC::ReadParam(&messages[i], &iter, &request_id));
2855 ASSERT_TRUE(IPC::ReadParam(&messages[i], &iter, &data_len));
2856 total_len += data_len;
2858 EXPECT_EQ(net::URLRequestTestJob::test_data_1().size(), total_len);
2861 CheckRequestCompleteErrorCode(messages.back(), net::OK);
2863 // Verify that the data ended up in the temporary file.
2864 std::string contents;
2865 ASSERT_TRUE(base::ReadFileToString(response_head.download_file_path,
2867 EXPECT_EQ(net::URLRequestTestJob::test_data_1(), contents);
2869 // The file should be readable by the child.
2870 EXPECT_TRUE(ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
2871 filter_->child_id(), response_head.download_file_path));
2873 // When the renderer releases the file, it should be deleted. Again,
2874 // RunUntilIdle doesn't work because base::WorkerPool is involved.
2875 ShareableFileReleaseWaiter waiter(response_head.download_file_path);
2876 ResourceHostMsg_ReleaseDownloadedFile release_msg(1);
2877 host_.OnMessageReceived(release_msg, filter_);
2879 // The release callback runs before the delete is scheduled, so pump the
2880 // message loop for the delete itself. (This relies on the delete happening on
2881 // the FILE thread which is mapped to main thread in this test.)
2882 base::RunLoop().RunUntilIdle();
2884 EXPECT_FALSE(base::PathExists(response_head.download_file_path));
2885 EXPECT_FALSE(ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
2886 filter_->child_id(), response_head.download_file_path));
2889 net::URLRequestJob* TestURLRequestJobFactory::MaybeCreateJobWithProtocolHandler(
2890 const std::string& scheme,
2891 net::URLRequest* request,
2892 net::NetworkDelegate* network_delegate) const {
2893 url_request_jobs_created_count_++;
2894 if (test_fixture_->response_headers_.empty()) {
2896 return new URLRequestTestDelayedStartJob(request, network_delegate);
2897 } else if (delay_complete_) {
2898 return new URLRequestTestDelayedCompletionJob(request,
2900 } else if (network_start_notification_) {
2901 return new URLRequestTestDelayedNetworkJob(request, network_delegate);
2902 } else if (scheme == "big-job") {
2903 return new URLRequestBigJob(request, network_delegate);
2905 return new net::URLRequestTestJob(request, network_delegate);
2909 return new URLRequestTestDelayedStartJob(
2910 request, network_delegate,
2911 test_fixture_->response_headers_, test_fixture_->response_data_,
2913 } else if (delay_complete_) {
2914 return new URLRequestTestDelayedCompletionJob(
2915 request, network_delegate,
2916 test_fixture_->response_headers_, test_fixture_->response_data_,
2919 return new net::URLRequestTestJob(
2920 request, network_delegate,
2921 test_fixture_->response_headers_, test_fixture_->response_data_,
2927 } // namespace content