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/command_line.h"
10 #include "base/files/file_path.h"
11 #include "base/files/file_util.h"
12 #include "base/location.h"
13 #include "base/memory/scoped_vector.h"
14 #include "base/memory/shared_memory.h"
15 #include "base/pickle.h"
16 #include "base/run_loop.h"
17 #include "base/single_thread_task_runner.h"
18 #include "base/strings/string_number_conversions.h"
19 #include "base/strings/string_split.h"
20 #include "base/thread_task_runner_handle.h"
21 #include "content/browser/browser_thread_impl.h"
22 #include "content/browser/child_process_security_policy_impl.h"
23 #include "content/browser/loader/cross_site_resource_handler.h"
24 #include "content/browser/loader/detachable_resource_handler.h"
25 #include "content/browser/loader/resource_dispatcher_host_impl.h"
26 #include "content/browser/loader/resource_loader.h"
27 #include "content/browser/loader/resource_message_filter.h"
28 #include "content/browser/loader/resource_request_info_impl.h"
29 #include "content/common/appcache_interfaces.h"
30 #include "content/common/child_process_host_impl.h"
31 #include "content/common/resource_messages.h"
32 #include "content/common/view_messages.h"
33 #include "content/public/browser/global_request_id.h"
34 #include "content/public/browser/resource_context.h"
35 #include "content/public/browser/resource_dispatcher_host_delegate.h"
36 #include "content/public/browser/resource_request_info.h"
37 #include "content/public/browser/resource_throttle.h"
38 #include "content/public/common/content_switches.h"
39 #include "content/public/common/process_type.h"
40 #include "content/public/common/resource_response.h"
41 #include "content/public/test/test_browser_context.h"
42 #include "content/public/test/test_browser_thread_bundle.h"
43 #include "content/test/test_content_browser_client.h"
44 #include "net/base/elements_upload_data_stream.h"
45 #include "net/base/net_errors.h"
46 #include "net/base/request_priority.h"
47 #include "net/base/upload_bytes_element_reader.h"
48 #include "net/http/http_util.h"
49 #include "net/url_request/url_request.h"
50 #include "net/url_request/url_request_context.h"
51 #include "net/url_request/url_request_job.h"
52 #include "net/url_request/url_request_job_factory.h"
53 #include "net/url_request/url_request_simple_job.h"
54 #include "net/url_request/url_request_test_job.h"
55 #include "net/url_request/url_request_test_util.h"
56 #include "storage/browser/blob/shareable_file_reference.h"
57 #include "testing/gtest/include/gtest/gtest.h"
59 // TODO(eroman): Write unit tests for SafeBrowsing that exercise
60 // SafeBrowsingResourceHandler.
62 using storage::ShareableFileReference
;
68 // Returns the resource response header structure for this request.
69 void GetResponseHead(const std::vector
<IPC::Message
>& messages
,
70 ResourceResponseHead
* response_head
) {
71 ASSERT_GE(messages
.size(), 2U);
73 // The first messages should be received response.
74 ASSERT_EQ(ResourceMsg_ReceivedResponse::ID
, messages
[0].type());
76 base::PickleIterator
iter(messages
[0]);
78 ASSERT_TRUE(IPC::ReadParam(&messages
[0], &iter
, &request_id
));
79 ASSERT_TRUE(IPC::ReadParam(&messages
[0], &iter
, response_head
));
82 void GenerateIPCMessage(
83 scoped_refptr
<ResourceMessageFilter
> filter
,
84 scoped_ptr
<IPC::Message
> message
) {
85 ResourceDispatcherHostImpl::Get()->OnMessageReceived(
86 *message
, filter
.get());
89 // On Windows, ResourceMsg_SetDataBuffer supplies a HANDLE which is not
90 // automatically released.
92 // See ResourceDispatcher::ReleaseResourcesInDataMessage.
94 // TODO(davidben): It would be nice if the behavior for base::SharedMemoryHandle
95 // were more like it is in POSIX where the received fds are tracked in a
96 // ref-counted core that closes them if not extracted.
97 void ReleaseHandlesInMessage(const IPC::Message
& message
) {
98 if (message
.type() == ResourceMsg_SetDataBuffer::ID
) {
99 base::PickleIterator
iter(message
);
101 CHECK(iter
.ReadInt(&request_id
));
102 base::SharedMemoryHandle shm_handle
;
103 if (IPC::ParamTraits
<base::SharedMemoryHandle
>::Read(&message
,
106 if (base::SharedMemory::IsHandleValid(shm_handle
))
107 base::SharedMemory::CloseHandle(shm_handle
);
114 static int RequestIDForMessage(const IPC::Message
& msg
) {
116 switch (msg
.type()) {
117 case ResourceMsg_UploadProgress::ID
:
118 case ResourceMsg_ReceivedResponse::ID
:
119 case ResourceMsg_ReceivedRedirect::ID
:
120 case ResourceMsg_SetDataBuffer::ID
:
121 case ResourceMsg_DataReceived::ID
:
122 case ResourceMsg_DataDownloaded::ID
:
123 case ResourceMsg_RequestComplete::ID
: {
124 bool result
= base::PickleIterator(msg
).ReadInt(&request_id
);
132 static ResourceHostMsg_Request
CreateResourceRequest(const char* method
,
135 ResourceHostMsg_Request request
;
136 request
.method
= std::string(method
);
138 request
.first_party_for_cookies
= url
; // bypass third-party cookie blocking
139 request
.referrer_policy
= blink::WebReferrerPolicyDefault
;
140 request
.load_flags
= 0;
141 request
.origin_pid
= 0;
142 request
.resource_type
= type
;
143 request
.request_context
= 0;
144 request
.appcache_host_id
= kAppCacheNoHostId
;
145 request
.download_to_file
= false;
146 request
.should_reset_appcache
= false;
147 request
.is_main_frame
= true;
148 request
.parent_is_main_frame
= false;
149 request
.parent_render_frame_id
= -1;
150 request
.transition_type
= ui::PAGE_TRANSITION_LINK
;
151 request
.allow_download
= true;
155 // Spin up the message loop to kick off the request.
156 static void KickOffRequest() {
157 base::MessageLoop::current()->RunUntilIdle();
160 // We may want to move this to a shared space if it is useful for something else
161 class ResourceIPCAccumulator
{
163 ~ResourceIPCAccumulator() {
164 for (size_t i
= 0; i
< messages_
.size(); i
++) {
165 ReleaseHandlesInMessage(messages_
[i
]);
169 // On Windows, takes ownership of SharedMemoryHandles in |msg|.
170 void AddMessage(const IPC::Message
& msg
) {
171 messages_
.push_back(msg
);
174 // This groups the messages by their request ID. The groups will be in order
175 // that the first message for each request ID was received, and the messages
176 // within the groups will be in the order that they appeared.
177 // Note that this clears messages_. The caller takes ownership of any
178 // SharedMemoryHandles in messages placed into |msgs|.
179 typedef std::vector
< std::vector
<IPC::Message
> > ClassifiedMessages
;
180 void GetClassifiedMessages(ClassifiedMessages
* msgs
);
183 std::vector
<IPC::Message
> messages_
;
186 // This is very inefficient as a result of repeatedly extracting the ID, use
188 void ResourceIPCAccumulator::GetClassifiedMessages(ClassifiedMessages
* msgs
) {
189 while (!messages_
.empty()) {
190 // Ignore unknown message types as it is valid for code to generated other
191 // IPCs as side-effects that we are not testing here.
192 int cur_id
= RequestIDForMessage(messages_
[0]);
194 std::vector
<IPC::Message
> cur_requests
;
195 cur_requests
.push_back(messages_
[0]);
196 // find all other messages with this ID
197 for (int i
= 1; i
< static_cast<int>(messages_
.size()); i
++) {
198 int id
= RequestIDForMessage(messages_
[i
]);
200 cur_requests
.push_back(messages_
[i
]);
201 messages_
.erase(messages_
.begin() + i
);
205 msgs
->push_back(cur_requests
);
207 messages_
.erase(messages_
.begin());
211 // This is used to emulate different sub-processes, since this filter will
212 // have a different ID than the original.
213 class TestFilter
: public ResourceMessageFilter
{
215 explicit TestFilter(ResourceContext
* resource_context
)
216 : ResourceMessageFilter(
217 ChildProcessHostImpl::GenerateChildProcessUniqueId(),
218 PROCESS_TYPE_RENDERER
, NULL
, NULL
, NULL
, NULL
, NULL
,
219 base::Bind(&TestFilter::GetContexts
, base::Unretained(this))),
220 resource_context_(resource_context
),
222 received_after_canceled_(0) {
223 ChildProcessSecurityPolicyImpl::GetInstance()->Add(child_id());
224 set_peer_process_for_testing(base::Process::Current());
227 void set_canceled(bool canceled
) { canceled_
= canceled
; }
228 int received_after_canceled() const { return received_after_canceled_
; }
230 // ResourceMessageFilter override
231 bool Send(IPC::Message
* msg
) override
{
232 // No messages should be received when the process has been canceled.
234 received_after_canceled_
++;
235 ReleaseHandlesInMessage(*msg
);
240 ResourceContext
* resource_context() { return resource_context_
; }
243 ~TestFilter() override
{}
246 void GetContexts(const ResourceHostMsg_Request
& request
,
247 ResourceContext
** resource_context
,
248 net::URLRequestContext
** request_context
) {
249 *resource_context
= resource_context_
;
250 *request_context
= resource_context_
->GetRequestContext();
253 ResourceContext
* resource_context_
;
255 int received_after_canceled_
;
257 DISALLOW_COPY_AND_ASSIGN(TestFilter
);
261 // This class forwards the incoming messages to the ResourceDispatcherHostTest.
262 // For the test, we want all the incoming messages to go to the same place,
263 // which is why this forwards.
264 class ForwardingFilter
: public TestFilter
{
266 explicit ForwardingFilter(IPC::Sender
* dest
,
267 ResourceContext
* resource_context
)
268 : TestFilter(resource_context
),
272 // TestFilter override
273 bool Send(IPC::Message
* msg
) override
{ return dest_
->Send(msg
); }
276 ~ForwardingFilter() override
{}
280 DISALLOW_COPY_AND_ASSIGN(ForwardingFilter
);
283 // This class is a variation on URLRequestTestJob that will call
284 // URLRequest::WillStartUsingNetwork before starting.
285 class URLRequestTestDelayedNetworkJob
: public net::URLRequestTestJob
{
287 URLRequestTestDelayedNetworkJob(net::URLRequest
* request
,
288 net::NetworkDelegate
* network_delegate
)
289 : net::URLRequestTestJob(request
, network_delegate
) {}
291 // Only start if not deferred for network start.
292 void Start() override
{
294 NotifyBeforeNetworkStart(&defer
);
297 net::URLRequestTestJob::Start();
300 void ResumeNetworkStart() override
{ net::URLRequestTestJob::StartAsync(); }
303 ~URLRequestTestDelayedNetworkJob() override
{}
305 DISALLOW_COPY_AND_ASSIGN(URLRequestTestDelayedNetworkJob
);
308 // This class is a variation on URLRequestTestJob in that it does
309 // not complete start upon entry, only when specifically told to.
310 class URLRequestTestDelayedStartJob
: public net::URLRequestTestJob
{
312 URLRequestTestDelayedStartJob(net::URLRequest
* request
,
313 net::NetworkDelegate
* network_delegate
)
314 : net::URLRequestTestJob(request
, network_delegate
) {
317 URLRequestTestDelayedStartJob(net::URLRequest
* request
,
318 net::NetworkDelegate
* network_delegate
,
320 : net::URLRequestTestJob(request
, network_delegate
, auto_advance
) {
323 URLRequestTestDelayedStartJob(net::URLRequest
* request
,
324 net::NetworkDelegate
* network_delegate
,
325 const std::string
& response_headers
,
326 const std::string
& response_data
,
328 : net::URLRequestTestJob(request
,
336 // Do nothing until you're told to.
337 void Start() override
{}
339 // Finish starting a URL request whose job is an instance of
340 // URLRequestTestDelayedStartJob. It is illegal to call this routine
341 // with a URLRequest that does not use URLRequestTestDelayedStartJob.
342 static void CompleteStart(net::URLRequest
* request
) {
343 for (URLRequestTestDelayedStartJob
* job
= list_head_
;
346 if (job
->request() == request
) {
347 job
->net::URLRequestTestJob::Start();
354 static bool DelayedStartQueueEmpty() {
358 static void ClearQueue() {
361 << "Unreleased entries on URLRequestTestDelayedStartJob delay queue"
362 << "; may result in leaks.";
368 ~URLRequestTestDelayedStartJob() override
{
369 for (URLRequestTestDelayedStartJob
** job
= &list_head_
; *job
;
370 job
= &(*job
)->next_
) {
372 *job
= (*job
)->next_
;
385 static URLRequestTestDelayedStartJob
* list_head_
;
386 URLRequestTestDelayedStartJob
* next_
;
389 URLRequestTestDelayedStartJob
*
390 URLRequestTestDelayedStartJob::list_head_
= NULL
;
392 // This class is a variation on URLRequestTestJob in that it
393 // returns IO_pending errors before every read, not just the first one.
394 class URLRequestTestDelayedCompletionJob
: public net::URLRequestTestJob
{
396 URLRequestTestDelayedCompletionJob(net::URLRequest
* request
,
397 net::NetworkDelegate
* network_delegate
)
398 : net::URLRequestTestJob(request
, network_delegate
) {}
399 URLRequestTestDelayedCompletionJob(net::URLRequest
* request
,
400 net::NetworkDelegate
* network_delegate
,
402 : net::URLRequestTestJob(request
, network_delegate
, auto_advance
) {}
403 URLRequestTestDelayedCompletionJob(net::URLRequest
* request
,
404 net::NetworkDelegate
* network_delegate
,
405 const std::string
& response_headers
,
406 const std::string
& response_data
,
408 : net::URLRequestTestJob(request
,
415 ~URLRequestTestDelayedCompletionJob() override
{}
418 bool NextReadAsync() override
{ return true; }
421 class URLRequestBigJob
: public net::URLRequestSimpleJob
{
423 URLRequestBigJob(net::URLRequest
* request
,
424 net::NetworkDelegate
* network_delegate
)
425 : net::URLRequestSimpleJob(request
, network_delegate
) {
428 // URLRequestSimpleJob implementation:
429 int GetData(std::string
* mime_type
,
430 std::string
* charset
,
432 const net::CompletionCallback
& callback
) const override
{
433 *mime_type
= "text/plain";
438 if (!ParseURL(request_
->url(), &text
, &count
))
439 return net::ERR_INVALID_URL
;
441 data
->reserve(text
.size() * count
);
442 for (int i
= 0; i
< count
; ++i
)
448 base::TaskRunner
* GetTaskRunner() const override
{
449 return base::ThreadTaskRunnerHandle::Get().get();
453 ~URLRequestBigJob() override
{}
455 // big-job:substring,N
456 static bool ParseURL(const GURL
& url
, std::string
* text
, int* count
) {
457 std::vector
<std::string
> parts
;
458 base::SplitString(url
.path(), ',', &parts
);
460 if (parts
.size() != 2)
464 return base::StringToInt(parts
[1], count
);
468 // URLRequestJob used to test GetLoadInfoForAllRoutes. The LoadState and
469 // UploadProgress values are set for the jobs at the time of creation, and
470 // the jobs will never actually do anything.
471 class URLRequestLoadInfoJob
: public net::URLRequestJob
{
473 URLRequestLoadInfoJob(net::URLRequest
* request
,
474 net::NetworkDelegate
* network_delegate
,
475 const net::LoadState
& load_state
,
476 const net::UploadProgress
& upload_progress
)
477 : net::URLRequestJob(request
, network_delegate
),
478 load_state_(load_state
),
479 upload_progress_(upload_progress
) {}
481 // net::URLRequestJob implementation:
482 void Start() override
{}
483 net::LoadState
GetLoadState() const override
{ return load_state_
; }
484 net::UploadProgress
GetUploadProgress() const override
{
485 return upload_progress_
;
489 ~URLRequestLoadInfoJob() override
{}
491 // big-job:substring,N
492 static bool ParseURL(const GURL
& url
, std::string
* text
, int* count
) {
493 std::vector
<std::string
> parts
;
494 base::SplitString(url
.path(), ',', &parts
);
496 if (parts
.size() != 2)
500 return base::StringToInt(parts
[1], count
);
503 const net::LoadState load_state_
;
504 const net::UploadProgress upload_progress_
;
507 class ResourceDispatcherHostTest
;
509 class TestURLRequestJobFactory
: public net::URLRequestJobFactory
{
511 explicit TestURLRequestJobFactory(ResourceDispatcherHostTest
* test_fixture
)
512 : test_fixture_(test_fixture
),
514 delay_complete_(false),
515 network_start_notification_(false),
516 url_request_jobs_created_count_(0) {
519 void HandleScheme(const std::string
& scheme
) {
520 supported_schemes_
.insert(scheme
);
523 int url_request_jobs_created_count() const {
524 return url_request_jobs_created_count_
;
527 void SetDelayedStartJobGeneration(bool delay_job_start
) {
528 delay_start_
= delay_job_start
;
531 void SetDelayedCompleteJobGeneration(bool delay_job_complete
) {
532 delay_complete_
= delay_job_complete
;
535 void SetNetworkStartNotificationJobGeneration(bool notification
) {
536 network_start_notification_
= notification
;
539 net::URLRequestJob
* MaybeCreateJobWithProtocolHandler(
540 const std::string
& scheme
,
541 net::URLRequest
* request
,
542 net::NetworkDelegate
* network_delegate
) const override
;
544 net::URLRequestJob
* MaybeInterceptRedirect(
545 net::URLRequest
* request
,
546 net::NetworkDelegate
* network_delegate
,
547 const GURL
& location
) const override
;
549 net::URLRequestJob
* MaybeInterceptResponse(
550 net::URLRequest
* request
,
551 net::NetworkDelegate
* network_delegate
) const override
;
553 bool IsHandledProtocol(const std::string
& scheme
) const override
{
554 return supported_schemes_
.count(scheme
) > 0;
557 bool IsHandledURL(const GURL
& url
) const override
{
558 return supported_schemes_
.count(url
.scheme()) > 0;
561 bool IsSafeRedirectTarget(const GURL
& location
) const override
{
566 ResourceDispatcherHostTest
* test_fixture_
;
568 bool delay_complete_
;
569 bool network_start_notification_
;
570 mutable int url_request_jobs_created_count_
;
571 std::set
<std::string
> supported_schemes_
;
573 DISALLOW_COPY_AND_ASSIGN(TestURLRequestJobFactory
);
576 // Associated with an URLRequest to determine if the URLRequest gets deleted.
577 class TestUserData
: public base::SupportsUserData::Data
{
579 explicit TestUserData(bool* was_deleted
)
580 : was_deleted_(was_deleted
) {
583 ~TestUserData() override
{ *was_deleted_
= true; }
589 class TransfersAllNavigationsContentBrowserClient
590 : public TestContentBrowserClient
{
592 bool ShouldSwapProcessesForRedirect(ResourceContext
* resource_context
,
593 const GURL
& current_url
,
594 const GURL
& new_url
) override
{
599 enum GenericResourceThrottleFlags
{
601 DEFER_STARTING_REQUEST
= 1 << 0,
602 DEFER_PROCESSING_RESPONSE
= 1 << 1,
603 CANCEL_BEFORE_START
= 1 << 2,
604 DEFER_NETWORK_START
= 1 << 3
607 // Throttle that tracks the current throttle blocking a request. Only one
608 // can throttle any request at a time.
609 class GenericResourceThrottle
: public ResourceThrottle
{
611 // The value is used to indicate that the throttle should not provide
612 // a error code when cancelling a request. net::OK is used, because this
613 // is not an error code.
614 static const int USE_DEFAULT_CANCEL_ERROR_CODE
= net::OK
;
616 GenericResourceThrottle(int flags
, int code
)
618 error_code_for_cancellation_(code
) {
621 ~GenericResourceThrottle() override
{
622 if (active_throttle_
== this)
623 active_throttle_
= NULL
;
626 // ResourceThrottle implementation:
627 void WillStartRequest(bool* defer
) override
{
628 ASSERT_EQ(NULL
, active_throttle_
);
629 if (flags_
& DEFER_STARTING_REQUEST
) {
630 active_throttle_
= this;
634 if (flags_
& CANCEL_BEFORE_START
) {
635 if (error_code_for_cancellation_
== USE_DEFAULT_CANCEL_ERROR_CODE
) {
636 controller()->Cancel();
638 controller()->CancelWithError(error_code_for_cancellation_
);
643 void WillProcessResponse(bool* defer
) override
{
644 ASSERT_EQ(NULL
, active_throttle_
);
645 if (flags_
& DEFER_PROCESSING_RESPONSE
) {
646 active_throttle_
= this;
651 void WillStartUsingNetwork(bool* defer
) override
{
652 ASSERT_EQ(NULL
, active_throttle_
);
654 if (flags_
& DEFER_NETWORK_START
) {
655 active_throttle_
= this;
660 const char* GetNameForLogging() const override
{
661 return "GenericResourceThrottle";
665 ASSERT_TRUE(this == active_throttle_
);
666 active_throttle_
= NULL
;
667 controller()->Resume();
670 static GenericResourceThrottle
* active_throttle() {
671 return active_throttle_
;
675 int flags_
; // bit-wise union of GenericResourceThrottleFlags.
676 int error_code_for_cancellation_
;
678 // The currently active throttle, if any.
679 static GenericResourceThrottle
* active_throttle_
;
682 GenericResourceThrottle
* GenericResourceThrottle::active_throttle_
= NULL
;
684 class TestResourceDispatcherHostDelegate
685 : public ResourceDispatcherHostDelegate
{
687 TestResourceDispatcherHostDelegate()
688 : create_two_throttles_(false),
690 error_code_for_cancellation_(
691 GenericResourceThrottle::USE_DEFAULT_CANCEL_ERROR_CODE
) {
694 void set_url_request_user_data(base::SupportsUserData::Data
* user_data
) {
695 user_data_
.reset(user_data
);
698 void set_flags(int value
) {
702 void set_error_code_for_cancellation(int code
) {
703 error_code_for_cancellation_
= code
;
706 void set_create_two_throttles(bool create_two_throttles
) {
707 create_two_throttles_
= create_two_throttles
;
710 // ResourceDispatcherHostDelegate implementation:
712 void RequestBeginning(net::URLRequest
* request
,
713 ResourceContext
* resource_context
,
714 AppCacheService
* appcache_service
,
715 ResourceType resource_type
,
716 ScopedVector
<ResourceThrottle
>* throttles
) override
{
718 const void* key
= user_data_
.get();
719 request
->SetUserData(key
, user_data_
.release());
722 if (flags_
!= NONE
) {
723 throttles
->push_back(new GenericResourceThrottle(
724 flags_
, error_code_for_cancellation_
));
725 if (create_two_throttles_
)
726 throttles
->push_back(new GenericResourceThrottle(
727 flags_
, error_code_for_cancellation_
));
732 bool create_two_throttles_
;
734 int error_code_for_cancellation_
;
735 scoped_ptr
<base::SupportsUserData::Data
> user_data_
;
738 // Waits for a ShareableFileReference to be released.
739 class ShareableFileReleaseWaiter
{
741 ShareableFileReleaseWaiter(const base::FilePath
& path
) {
742 scoped_refptr
<ShareableFileReference
> file
=
743 ShareableFileReference::Get(path
);
744 file
->AddFinalReleaseCallback(
745 base::Bind(&ShareableFileReleaseWaiter::Released
,
746 base::Unretained(this)));
754 void Released(const base::FilePath
& path
) {
760 DISALLOW_COPY_AND_ASSIGN(ShareableFileReleaseWaiter
);
763 // Information used to create resource requests that use URLRequestLoadInfoJobs.
764 // The child_id is just that of ResourceDispatcherHostTest::filter_.
765 struct LoadInfoTestRequestInfo
{
768 net::LoadState load_state
;
769 net::UploadProgress upload_progress
;
772 class ResourceDispatcherHostTest
: public testing::Test
,
775 typedef ResourceDispatcherHostImpl::LoadInfo LoadInfo
;
776 typedef ResourceDispatcherHostImpl::LoadInfoMap LoadInfoMap
;
778 ResourceDispatcherHostTest()
779 : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP
),
781 send_data_received_acks_(false) {
782 browser_context_
.reset(new TestBrowserContext());
783 BrowserContext::EnsureResourceContextInitialized(browser_context_
.get());
784 base::RunLoop().RunUntilIdle();
785 filter_
= MakeForwardingFilter();
786 // TODO(cbentzel): Better way to get URLRequestContext?
787 net::URLRequestContext
* request_context
=
788 browser_context_
->GetResourceContext()->GetRequestContext();
789 job_factory_
.reset(new TestURLRequestJobFactory(this));
790 request_context
->set_job_factory(job_factory_
.get());
791 request_context
->set_network_delegate(&network_delegate_
);
794 // IPC::Sender implementation
795 bool Send(IPC::Message
* msg
) override
{
796 accum_
.AddMessage(*msg
);
798 if (send_data_received_acks_
&&
799 msg
->type() == ResourceMsg_DataReceived::ID
) {
800 GenerateDataReceivedACK(*msg
);
803 if (wait_for_request_complete_loop_
&&
804 msg
->type() == ResourceMsg_RequestComplete::ID
) {
805 wait_for_request_complete_loop_
->Quit();
808 // Do not release handles in it yet; the accumulator owns them now.
813 scoped_ptr
<LoadInfoMap
> RunLoadInfoTest(LoadInfoTestRequestInfo
* request_info
,
814 size_t num_requests
) {
815 for (size_t i
= 0; i
< num_requests
; ++i
) {
816 loader_test_request_info_
.reset(
817 new LoadInfoTestRequestInfo(request_info
[i
]));
818 wait_for_request_create_loop_
.reset(new base::RunLoop());
819 MakeTestRequest(request_info
[i
].route_id
, i
+ 1, request_info
[i
].url
);
820 wait_for_request_create_loop_
->Run();
821 wait_for_request_create_loop_
.reset();
823 return ResourceDispatcherHostImpl::Get()->GetLoadInfoForAllRoutes();
827 friend class TestURLRequestJobFactory
;
830 void SetUp() override
{
831 ChildProcessSecurityPolicyImpl::GetInstance()->Add(0);
832 HandleScheme("test");
835 void TearDown() override
{
836 EXPECT_TRUE(URLRequestTestDelayedStartJob::DelayedStartQueueEmpty());
837 URLRequestTestDelayedStartJob::ClearQueue();
839 for (std::set
<int>::iterator it
= child_ids_
.begin();
840 it
!= child_ids_
.end(); ++it
) {
841 host_
.CancelRequestsForProcess(*it
);
846 ChildProcessSecurityPolicyImpl::GetInstance()->Remove(0);
848 // Flush the message loop to make application verifiers happy.
849 if (ResourceDispatcherHostImpl::Get())
850 ResourceDispatcherHostImpl::Get()->CancelRequestsForContext(
851 browser_context_
->GetResourceContext());
853 browser_context_
.reset();
854 base::RunLoop().RunUntilIdle();
857 // Creates a new ForwardingFilter and registers it with |child_ids_| so as not
858 // to leak per-child state on test shutdown.
859 ForwardingFilter
* MakeForwardingFilter() {
860 ForwardingFilter
* filter
=
861 new ForwardingFilter(this, browser_context_
->GetResourceContext());
862 child_ids_
.insert(filter
->child_id());
866 // Creates a request using the current test object as the filter and
867 // SubResource as the resource type.
868 void MakeTestRequest(int render_view_id
,
872 // Generates a request using the given filter and resource type.
873 void MakeTestRequestWithResourceType(ResourceMessageFilter
* filter
,
879 void CancelRequest(int request_id
);
880 void RendererCancelRequest(int request_id
) {
881 ResourceMessageFilter
* old_filter
= SetFilter(filter_
.get());
882 host_
.OnCancelRequest(request_id
);
883 SetFilter(old_filter
);
886 void CompleteStartRequest(int request_id
);
887 void CompleteStartRequest(ResourceMessageFilter
* filter
, int request_id
);
889 net::TestNetworkDelegate
* network_delegate() { return &network_delegate_
; }
891 void EnsureSchemeIsAllowed(const std::string
& scheme
) {
892 ChildProcessSecurityPolicyImpl
* policy
=
893 ChildProcessSecurityPolicyImpl::GetInstance();
894 if (!policy
->IsWebSafeScheme(scheme
))
895 policy
->RegisterWebSafeScheme(scheme
);
898 // Sets a particular response for any request from now on. To switch back to
899 // the default bahavior, pass an empty |headers|. |headers| should be raw-
900 // formatted (NULLs instead of EOLs).
901 void SetResponse(const std::string
& headers
, const std::string
& data
) {
902 response_headers_
= net::HttpUtil::AssembleRawHeaders(headers
.data(),
904 response_data_
= data
;
906 void SetResponse(const std::string
& headers
) {
907 SetResponse(headers
, std::string());
910 void SendDataReceivedACKs(bool send_acks
) {
911 send_data_received_acks_
= send_acks
;
914 // Intercepts requests for the given protocol.
915 void HandleScheme(const std::string
& scheme
) {
916 job_factory_
->HandleScheme(scheme
);
917 EnsureSchemeIsAllowed(scheme
);
920 void GenerateDataReceivedACK(const IPC::Message
& msg
) {
921 EXPECT_EQ(ResourceMsg_DataReceived::ID
, msg
.type());
924 bool result
= base::PickleIterator(msg
).ReadInt(&request_id
);
926 scoped_ptr
<IPC::Message
> ack(
927 new ResourceHostMsg_DataReceived_ACK(request_id
));
929 base::ThreadTaskRunnerHandle::Get()->PostTask(
931 base::Bind(&GenerateIPCMessage
, filter_
, base::Passed(&ack
)));
934 // Setting filters for testing renderer messages.
935 // Returns the previous filter.
936 ResourceMessageFilter
* SetFilter(ResourceMessageFilter
* new_filter
) {
937 ResourceMessageFilter
* old_filter
= host_
.filter_
;
938 host_
.filter_
= new_filter
;
942 void WaitForRequestComplete() {
943 DCHECK(!wait_for_request_complete_loop_
);
944 wait_for_request_complete_loop_
.reset(new base::RunLoop
);
945 wait_for_request_complete_loop_
->Run();
946 wait_for_request_complete_loop_
.reset();
949 scoped_ptr
<LoadInfoTestRequestInfo
> loader_test_request_info_
;
950 scoped_ptr
<base::RunLoop
> wait_for_request_create_loop_
;
952 content::TestBrowserThreadBundle thread_bundle_
;
953 scoped_ptr
<TestBrowserContext
> browser_context_
;
954 scoped_ptr
<TestURLRequestJobFactory
> job_factory_
;
955 scoped_refptr
<ForwardingFilter
> filter_
;
956 net::TestNetworkDelegate network_delegate_
;
957 ResourceDispatcherHostImpl host_
;
958 ResourceIPCAccumulator accum_
;
959 std::string response_headers_
;
960 std::string response_data_
;
962 net::URLRequest::ProtocolFactory
* old_factory_
;
963 bool send_data_received_acks_
;
964 std::set
<int> child_ids_
;
965 scoped_ptr
<base::RunLoop
> wait_for_request_complete_loop_
;
968 void ResourceDispatcherHostTest::MakeTestRequest(int render_view_id
,
971 MakeTestRequestWithResourceType(filter_
.get(), render_view_id
, request_id
,
972 url
, RESOURCE_TYPE_SUB_RESOURCE
);
975 void ResourceDispatcherHostTest::MakeTestRequestWithResourceType(
976 ResourceMessageFilter
* filter
,
981 ResourceHostMsg_Request request
=
982 CreateResourceRequest("GET", type
, url
);
983 ResourceHostMsg_RequestResource
msg(render_view_id
, request_id
, request
);
984 host_
.OnMessageReceived(msg
, filter
);
988 void ResourceDispatcherHostTest::CancelRequest(int request_id
) {
989 host_
.CancelRequest(filter_
->child_id(), request_id
);
992 void ResourceDispatcherHostTest::CompleteStartRequest(int request_id
) {
993 CompleteStartRequest(filter_
.get(), request_id
);
996 void ResourceDispatcherHostTest::CompleteStartRequest(
997 ResourceMessageFilter
* filter
,
999 GlobalRequestID
gid(filter
->child_id(), request_id
);
1000 net::URLRequest
* req
= host_
.GetURLRequest(gid
);
1003 URLRequestTestDelayedStartJob::CompleteStart(req
);
1006 void CheckRequestCompleteErrorCode(const IPC::Message
& message
,
1007 int expected_error_code
) {
1008 // Verify the expected error code was received.
1012 ASSERT_EQ(ResourceMsg_RequestComplete::ID
, message
.type());
1014 base::PickleIterator
iter(message
);
1015 ASSERT_TRUE(IPC::ReadParam(&message
, &iter
, &request_id
));
1016 ASSERT_TRUE(IPC::ReadParam(&message
, &iter
, &error_code
));
1017 ASSERT_EQ(expected_error_code
, error_code
);
1020 testing::AssertionResult
ExtractDataOffsetAndLength(const IPC::Message
& message
,
1023 base::PickleIterator
iter(message
);
1025 if (!IPC::ReadParam(&message
, &iter
, &request_id
))
1026 return testing::AssertionFailure() << "Could not read request_id";
1027 if (!IPC::ReadParam(&message
, &iter
, data_offset
))
1028 return testing::AssertionFailure() << "Could not read data_offset";
1029 if (!IPC::ReadParam(&message
, &iter
, data_length
))
1030 return testing::AssertionFailure() << "Could not read data_length";
1031 return testing::AssertionSuccess();
1034 void CheckSuccessfulRequestWithErrorCode(
1035 const std::vector
<IPC::Message
>& messages
,
1036 const std::string
& reference_data
,
1037 int expected_error
) {
1038 // A successful request will have received 4 messages:
1039 // ReceivedResponse (indicates headers received)
1040 // SetDataBuffer (contains shared memory handle)
1041 // DataReceived (data offset and length into shared memory)
1042 // RequestComplete (request is done)
1044 // This function verifies that we received 4 messages and that they are
1045 // appropriate. It allows for an error code other than net::OK if the request
1046 // should successfully receive data and then abort, e.g., on cancel.
1047 ASSERT_EQ(4U, messages
.size());
1049 // The first messages should be received response
1050 ASSERT_EQ(ResourceMsg_ReceivedResponse::ID
, messages
[0].type());
1052 ASSERT_EQ(ResourceMsg_SetDataBuffer::ID
, messages
[1].type());
1054 base::PickleIterator
iter(messages
[1]);
1056 ASSERT_TRUE(IPC::ReadParam(&messages
[1], &iter
, &request_id
));
1057 base::SharedMemoryHandle shm_handle
;
1058 ASSERT_TRUE(IPC::ReadParam(&messages
[1], &iter
, &shm_handle
));
1060 ASSERT_TRUE(IPC::ReadParam(&messages
[1], &iter
, &shm_size
));
1062 // Followed by the data, currently we only do the data in one chunk, but
1063 // should probably test multiple chunks later
1064 ASSERT_EQ(ResourceMsg_DataReceived::ID
, messages
[2].type());
1069 ExtractDataOffsetAndLength(messages
[2], &data_offset
, &data_length
));
1071 ASSERT_EQ(reference_data
.size(), static_cast<size_t>(data_length
));
1072 ASSERT_GE(shm_size
, data_length
);
1074 base::SharedMemory
shared_mem(shm_handle
, true); // read only
1075 shared_mem
.Map(data_length
);
1076 const char* data
= static_cast<char*>(shared_mem
.memory()) + data_offset
;
1077 ASSERT_EQ(0, memcmp(reference_data
.c_str(), data
, data_length
));
1079 // The last message should be all data received.
1080 CheckRequestCompleteErrorCode(messages
[3], expected_error
);
1083 void CheckSuccessfulRequest(const std::vector
<IPC::Message
>& messages
,
1084 const std::string
& reference_data
) {
1085 CheckSuccessfulRequestWithErrorCode(messages
, reference_data
, net::OK
);
1088 void CheckSuccessfulRedirect(const std::vector
<IPC::Message
>& messages
,
1089 const std::string
& reference_data
) {
1090 ASSERT_EQ(5U, messages
.size());
1091 ASSERT_EQ(ResourceMsg_ReceivedRedirect::ID
, messages
[0].type());
1093 const std::vector
<IPC::Message
> second_req_msgs
=
1094 std::vector
<IPC::Message
>(messages
.begin() + 1, messages
.end());
1095 CheckSuccessfulRequest(second_req_msgs
, reference_data
);
1098 void CheckFailedRequest(const std::vector
<IPC::Message
>& messages
,
1099 const std::string
& reference_data
,
1100 int expected_error
) {
1101 ASSERT_LT(0U, messages
.size());
1102 ASSERT_GE(2U, messages
.size());
1103 size_t failure_index
= messages
.size() - 1;
1105 if (messages
.size() == 2) {
1106 EXPECT_EQ(ResourceMsg_ReceivedResponse::ID
, messages
[0].type());
1109 CheckRequestCompleteErrorCode(messages
[failure_index
], expected_error
);
1112 // Tests whether many messages get dispatched properly.
1113 TEST_F(ResourceDispatcherHostTest
, TestMany
) {
1114 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
1115 MakeTestRequest(0, 2, net::URLRequestTestJob::test_url_2());
1116 MakeTestRequest(0, 3, net::URLRequestTestJob::test_url_3());
1117 MakeTestRequestWithResourceType(filter_
.get(), 0, 4,
1118 net::URLRequestTestJob::test_url_4(),
1119 RESOURCE_TYPE_PREFETCH
); // detachable type
1120 MakeTestRequest(0, 5, net::URLRequestTestJob::test_url_redirect_to_url_2());
1122 // Finish the redirection
1123 ResourceHostMsg_FollowRedirect
redirect_msg(5);
1124 host_
.OnMessageReceived(redirect_msg
, filter_
.get());
1125 base::MessageLoop::current()->RunUntilIdle();
1127 // flush all the pending requests
1128 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1130 // sorts out all the messages we saw by request
1131 ResourceIPCAccumulator::ClassifiedMessages msgs
;
1132 accum_
.GetClassifiedMessages(&msgs
);
1134 // there are five requests, so we should have gotten them classified as such
1135 ASSERT_EQ(5U, msgs
.size());
1137 CheckSuccessfulRequest(msgs
[0], net::URLRequestTestJob::test_data_1());
1138 CheckSuccessfulRequest(msgs
[1], net::URLRequestTestJob::test_data_2());
1139 CheckSuccessfulRequest(msgs
[2], net::URLRequestTestJob::test_data_3());
1140 CheckSuccessfulRequest(msgs
[3], net::URLRequestTestJob::test_data_4());
1141 CheckSuccessfulRedirect(msgs
[4], net::URLRequestTestJob::test_data_2());
1144 // Tests whether messages get canceled properly. We issue four requests,
1145 // cancel two of them, and make sure that each sent the proper notifications.
1146 TEST_F(ResourceDispatcherHostTest
, Cancel
) {
1147 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
1148 MakeTestRequest(0, 2, net::URLRequestTestJob::test_url_2());
1149 MakeTestRequest(0, 3, net::URLRequestTestJob::test_url_3());
1151 MakeTestRequestWithResourceType(filter_
.get(), 0, 4,
1152 net::URLRequestTestJob::test_url_4(),
1153 RESOURCE_TYPE_PREFETCH
); // detachable type
1157 // Cancel request must come from the renderer for a detachable resource to
1159 RendererCancelRequest(4);
1161 // The handler should have been detached now.
1162 GlobalRequestID
global_request_id(filter_
->child_id(), 4);
1163 ResourceRequestInfoImpl
* info
= ResourceRequestInfoImpl::ForRequest(
1164 host_
.GetURLRequest(global_request_id
));
1165 ASSERT_TRUE(info
->detachable_handler()->is_detached());
1167 // flush all the pending requests
1168 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1169 base::MessageLoop::current()->RunUntilIdle();
1171 // Everything should be out now.
1172 EXPECT_EQ(0, host_
.pending_requests());
1174 ResourceIPCAccumulator::ClassifiedMessages msgs
;
1175 accum_
.GetClassifiedMessages(&msgs
);
1177 // there are four requests, so we should have gotten them classified as such
1178 ASSERT_EQ(4U, msgs
.size());
1180 CheckSuccessfulRequest(msgs
[0], net::URLRequestTestJob::test_data_1());
1181 CheckSuccessfulRequest(msgs
[2], net::URLRequestTestJob::test_data_3());
1183 // Check that request 2 and 4 got canceled, as far as the renderer is
1184 // concerned. Request 2 will have been deleted.
1185 ASSERT_EQ(1U, msgs
[1].size());
1186 ASSERT_EQ(ResourceMsg_ReceivedResponse::ID
, msgs
[1][0].type());
1188 ASSERT_EQ(2U, msgs
[3].size());
1189 ASSERT_EQ(ResourceMsg_ReceivedResponse::ID
, msgs
[3][0].type());
1190 CheckRequestCompleteErrorCode(msgs
[3][1], net::ERR_ABORTED
);
1192 // However, request 4 should have actually gone to completion. (Only request 2
1194 EXPECT_EQ(4, network_delegate()->completed_requests());
1195 EXPECT_EQ(1, network_delegate()->canceled_requests());
1196 EXPECT_EQ(0, network_delegate()->error_count());
1199 // Shows that detachable requests will timeout if the request takes too long to
1201 TEST_F(ResourceDispatcherHostTest
, DetachedResourceTimesOut
) {
1202 MakeTestRequestWithResourceType(filter_
.get(), 0, 1,
1203 net::URLRequestTestJob::test_url_2(),
1204 RESOURCE_TYPE_PREFETCH
); // detachable type
1205 GlobalRequestID
global_request_id(filter_
->child_id(), 1);
1206 ResourceRequestInfoImpl
* info
= ResourceRequestInfoImpl::ForRequest(
1207 host_
.GetURLRequest(global_request_id
));
1208 ASSERT_TRUE(info
->detachable_handler());
1209 info
->detachable_handler()->set_cancel_delay(
1210 base::TimeDelta::FromMilliseconds(200));
1211 base::MessageLoop::current()->RunUntilIdle();
1213 RendererCancelRequest(1);
1215 // From the renderer's perspective, the request was cancelled.
1216 ResourceIPCAccumulator::ClassifiedMessages msgs
;
1217 accum_
.GetClassifiedMessages(&msgs
);
1218 ASSERT_EQ(1U, msgs
.size());
1219 ASSERT_EQ(2U, msgs
[0].size());
1220 ASSERT_EQ(ResourceMsg_ReceivedResponse::ID
, msgs
[0][0].type());
1221 CheckRequestCompleteErrorCode(msgs
[0][1], net::ERR_ABORTED
);
1223 // But it continues detached.
1224 EXPECT_EQ(1, host_
.pending_requests());
1225 EXPECT_TRUE(info
->detachable_handler()->is_detached());
1227 // Wait until after the delay timer times out before we start processing any
1229 base::OneShotTimer
<base::MessageLoop
> timer
;
1230 timer
.Start(FROM_HERE
, base::TimeDelta::FromMilliseconds(210),
1231 base::MessageLoop::current(), &base::MessageLoop::QuitWhenIdle
);
1232 base::MessageLoop::current()->Run();
1234 // The prefetch should be cancelled by now.
1235 EXPECT_EQ(0, host_
.pending_requests());
1236 EXPECT_EQ(1, network_delegate()->completed_requests());
1237 EXPECT_EQ(1, network_delegate()->canceled_requests());
1238 EXPECT_EQ(0, network_delegate()->error_count());
1241 // If the filter has disappeared then detachable resources should continue to
1243 TEST_F(ResourceDispatcherHostTest
, DeletedFilterDetached
) {
1244 // test_url_1's data is available synchronously, so use 2 and 3.
1245 ResourceHostMsg_Request request_prefetch
= CreateResourceRequest(
1246 "GET", RESOURCE_TYPE_PREFETCH
, net::URLRequestTestJob::test_url_2());
1247 ResourceHostMsg_Request request_ping
= CreateResourceRequest(
1248 "GET", RESOURCE_TYPE_PING
, net::URLRequestTestJob::test_url_3());
1250 ResourceHostMsg_RequestResource
msg_prefetch(0, 1, request_prefetch
);
1251 host_
.OnMessageReceived(msg_prefetch
, filter_
.get());
1252 ResourceHostMsg_RequestResource
msg_ping(0, 2, request_ping
);
1253 host_
.OnMessageReceived(msg_ping
, filter_
.get());
1255 // Remove the filter before processing the requests by simulating channel
1257 ResourceRequestInfoImpl
* info_prefetch
= ResourceRequestInfoImpl::ForRequest(
1258 host_
.GetURLRequest(GlobalRequestID(filter_
->child_id(), 1)));
1259 ResourceRequestInfoImpl
* info_ping
= ResourceRequestInfoImpl::ForRequest(
1260 host_
.GetURLRequest(GlobalRequestID(filter_
->child_id(), 2)));
1261 DCHECK_EQ(filter_
.get(), info_prefetch
->filter());
1262 DCHECK_EQ(filter_
.get(), info_ping
->filter());
1263 filter_
->OnChannelClosing();
1264 info_prefetch
->filter_
.reset();
1265 info_ping
->filter_
.reset();
1267 // From the renderer's perspective, the requests were cancelled.
1268 ResourceIPCAccumulator::ClassifiedMessages msgs
;
1269 accum_
.GetClassifiedMessages(&msgs
);
1270 ASSERT_EQ(2U, msgs
.size());
1271 CheckRequestCompleteErrorCode(msgs
[0][0], net::ERR_ABORTED
);
1272 CheckRequestCompleteErrorCode(msgs
[1][0], net::ERR_ABORTED
);
1274 // But it continues detached.
1275 EXPECT_EQ(2, host_
.pending_requests());
1276 EXPECT_TRUE(info_prefetch
->detachable_handler()->is_detached());
1277 EXPECT_TRUE(info_ping
->detachable_handler()->is_detached());
1281 // Make sure the requests weren't canceled early.
1282 EXPECT_EQ(2, host_
.pending_requests());
1284 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1285 base::MessageLoop::current()->RunUntilIdle();
1287 EXPECT_EQ(0, host_
.pending_requests());
1288 EXPECT_EQ(2, network_delegate()->completed_requests());
1289 EXPECT_EQ(0, network_delegate()->canceled_requests());
1290 EXPECT_EQ(0, network_delegate()->error_count());
1293 // If the filter has disappeared (original process dies) then detachable
1294 // resources should continue to load, even when redirected.
1295 TEST_F(ResourceDispatcherHostTest
, DeletedFilterDetachedRedirect
) {
1296 ResourceHostMsg_Request request
= CreateResourceRequest(
1297 "GET", RESOURCE_TYPE_PREFETCH
,
1298 net::URLRequestTestJob::test_url_redirect_to_url_2());
1300 ResourceHostMsg_RequestResource
msg(0, 1, request
);
1301 host_
.OnMessageReceived(msg
, filter_
.get());
1303 // Remove the filter before processing the request by simulating channel
1305 GlobalRequestID
global_request_id(filter_
->child_id(), 1);
1306 ResourceRequestInfoImpl
* info
= ResourceRequestInfoImpl::ForRequest(
1307 host_
.GetURLRequest(global_request_id
));
1308 info
->filter_
->OnChannelClosing();
1309 info
->filter_
.reset();
1311 // From the renderer's perspective, the request was cancelled.
1312 ResourceIPCAccumulator::ClassifiedMessages msgs
;
1313 accum_
.GetClassifiedMessages(&msgs
);
1314 ASSERT_EQ(1U, msgs
.size());
1315 CheckRequestCompleteErrorCode(msgs
[0][0], net::ERR_ABORTED
);
1317 // But it continues detached.
1318 EXPECT_EQ(1, host_
.pending_requests());
1319 EXPECT_TRUE(info
->detachable_handler()->is_detached());
1321 // Verify no redirects before resetting the filter.
1322 net::URLRequest
* url_request
= host_
.GetURLRequest(global_request_id
);
1323 EXPECT_EQ(1u, url_request
->url_chain().size());
1326 // Verify that a redirect was followed.
1327 EXPECT_EQ(2u, url_request
->url_chain().size());
1329 // Make sure the request wasn't canceled early.
1330 EXPECT_EQ(1, host_
.pending_requests());
1332 // Finish up the request.
1333 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1334 base::MessageLoop::current()->RunUntilIdle();
1336 EXPECT_EQ(0, host_
.pending_requests());
1337 EXPECT_EQ(1, network_delegate()->completed_requests());
1338 EXPECT_EQ(0, network_delegate()->canceled_requests());
1339 EXPECT_EQ(0, network_delegate()->error_count());
1342 TEST_F(ResourceDispatcherHostTest
, CancelWhileStartIsDeferred
) {
1343 bool was_deleted
= false;
1345 // Arrange to have requests deferred before starting.
1346 TestResourceDispatcherHostDelegate delegate
;
1347 delegate
.set_flags(DEFER_STARTING_REQUEST
);
1348 delegate
.set_url_request_user_data(new TestUserData(&was_deleted
));
1349 host_
.SetDelegate(&delegate
);
1351 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
1352 // We cancel from the renderer because all non-renderer cancels delete
1353 // the request synchronously.
1354 RendererCancelRequest(1);
1356 // Our TestResourceThrottle should not have been deleted yet. This is to
1357 // ensure that destruction of the URLRequest happens asynchronously to
1358 // calling CancelRequest.
1359 EXPECT_FALSE(was_deleted
);
1361 base::MessageLoop::current()->RunUntilIdle();
1363 EXPECT_TRUE(was_deleted
);
1366 TEST_F(ResourceDispatcherHostTest
, DetachWhileStartIsDeferred
) {
1367 bool was_deleted
= false;
1369 // Arrange to have requests deferred before starting.
1370 TestResourceDispatcherHostDelegate delegate
;
1371 delegate
.set_flags(DEFER_STARTING_REQUEST
);
1372 delegate
.set_url_request_user_data(new TestUserData(&was_deleted
));
1373 host_
.SetDelegate(&delegate
);
1375 MakeTestRequestWithResourceType(filter_
.get(), 0, 1,
1376 net::URLRequestTestJob::test_url_1(),
1377 RESOURCE_TYPE_PREFETCH
); // detachable type
1378 // Cancel request must come from the renderer for a detachable resource to
1380 RendererCancelRequest(1);
1382 // Even after driving the event loop, the request has not been deleted.
1383 EXPECT_FALSE(was_deleted
);
1385 // However, it is still throttled because the defer happened above the
1386 // DetachableResourceHandler.
1387 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1388 base::MessageLoop::current()->RunUntilIdle();
1389 EXPECT_FALSE(was_deleted
);
1391 // Resume the request.
1392 GenericResourceThrottle
* throttle
=
1393 GenericResourceThrottle::active_throttle();
1394 ASSERT_TRUE(throttle
);
1397 // Now, the request completes.
1398 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1399 base::MessageLoop::current()->RunUntilIdle();
1400 EXPECT_TRUE(was_deleted
);
1401 EXPECT_EQ(1, network_delegate()->completed_requests());
1402 EXPECT_EQ(0, network_delegate()->canceled_requests());
1403 EXPECT_EQ(0, network_delegate()->error_count());
1406 // Tests if cancel is called in ResourceThrottle::WillStartRequest, then the
1407 // URLRequest will not be started.
1408 TEST_F(ResourceDispatcherHostTest
, CancelInResourceThrottleWillStartRequest
) {
1409 TestResourceDispatcherHostDelegate delegate
;
1410 delegate
.set_flags(CANCEL_BEFORE_START
);
1411 host_
.SetDelegate(&delegate
);
1413 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
1415 // flush all the pending requests
1416 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1417 base::MessageLoop::current()->RunUntilIdle();
1419 ResourceIPCAccumulator::ClassifiedMessages msgs
;
1420 accum_
.GetClassifiedMessages(&msgs
);
1422 // Check that request got canceled.
1423 ASSERT_EQ(1U, msgs
[0].size());
1424 CheckRequestCompleteErrorCode(msgs
[0][0], net::ERR_ABORTED
);
1426 // Make sure URLRequest is never started.
1427 EXPECT_EQ(0, job_factory_
->url_request_jobs_created_count());
1430 TEST_F(ResourceDispatcherHostTest
, PausedStartError
) {
1431 // Arrange to have requests deferred before processing response headers.
1432 TestResourceDispatcherHostDelegate delegate
;
1433 delegate
.set_flags(DEFER_PROCESSING_RESPONSE
);
1434 host_
.SetDelegate(&delegate
);
1436 job_factory_
->SetDelayedStartJobGeneration(true);
1437 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_error());
1438 CompleteStartRequest(1);
1440 // flush all the pending requests
1441 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1442 base::MessageLoop::current()->RunUntilIdle();
1444 EXPECT_EQ(0, host_
.pending_requests());
1447 // Test the WillStartUsingNetwork throttle.
1448 TEST_F(ResourceDispatcherHostTest
, ThrottleNetworkStart
) {
1449 // Arrange to have requests deferred before processing response headers.
1450 TestResourceDispatcherHostDelegate delegate
;
1451 delegate
.set_flags(DEFER_NETWORK_START
);
1452 host_
.SetDelegate(&delegate
);
1454 job_factory_
->SetNetworkStartNotificationJobGeneration(true);
1455 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_2());
1457 // Should have deferred for network start.
1458 GenericResourceThrottle
* first_throttle
=
1459 GenericResourceThrottle::active_throttle();
1460 ASSERT_TRUE(first_throttle
);
1461 EXPECT_EQ(0, network_delegate()->completed_requests());
1462 EXPECT_EQ(1, host_
.pending_requests());
1464 first_throttle
->Resume();
1466 // Flush all the pending requests.
1467 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1468 base::MessageLoop::current()->RunUntilIdle();
1470 EXPECT_EQ(1, network_delegate()->completed_requests());
1471 EXPECT_EQ(0, host_
.pending_requests());
1474 TEST_F(ResourceDispatcherHostTest
, ThrottleAndResumeTwice
) {
1475 // Arrange to have requests deferred before starting.
1476 TestResourceDispatcherHostDelegate delegate
;
1477 delegate
.set_flags(DEFER_STARTING_REQUEST
);
1478 delegate
.set_create_two_throttles(true);
1479 host_
.SetDelegate(&delegate
);
1481 // Make sure the first throttle blocked the request, and then resume.
1482 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
1483 GenericResourceThrottle
* first_throttle
=
1484 GenericResourceThrottle::active_throttle();
1485 ASSERT_TRUE(first_throttle
);
1486 first_throttle
->Resume();
1488 // Make sure the second throttle blocked the request, and then resume.
1489 ASSERT_TRUE(GenericResourceThrottle::active_throttle());
1490 ASSERT_NE(first_throttle
, GenericResourceThrottle::active_throttle());
1491 GenericResourceThrottle::active_throttle()->Resume();
1493 ASSERT_FALSE(GenericResourceThrottle::active_throttle());
1495 // The request is started asynchronously.
1496 base::MessageLoop::current()->RunUntilIdle();
1498 // Flush all the pending requests.
1499 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1501 EXPECT_EQ(0, host_
.pending_requests());
1503 // Make sure the request completed successfully.
1504 ResourceIPCAccumulator::ClassifiedMessages msgs
;
1505 accum_
.GetClassifiedMessages(&msgs
);
1506 ASSERT_EQ(1U, msgs
.size());
1507 CheckSuccessfulRequest(msgs
[0], net::URLRequestTestJob::test_data_1());
1511 // Tests that the delegate can cancel a request and provide a error code.
1512 TEST_F(ResourceDispatcherHostTest
, CancelInDelegate
) {
1513 TestResourceDispatcherHostDelegate delegate
;
1514 delegate
.set_flags(CANCEL_BEFORE_START
);
1515 delegate
.set_error_code_for_cancellation(net::ERR_ACCESS_DENIED
);
1516 host_
.SetDelegate(&delegate
);
1518 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
1519 // The request will get cancelled by the throttle.
1521 // flush all the pending requests
1522 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1523 base::MessageLoop::current()->RunUntilIdle();
1525 ResourceIPCAccumulator::ClassifiedMessages msgs
;
1526 accum_
.GetClassifiedMessages(&msgs
);
1528 // Check the cancellation
1529 ASSERT_EQ(1U, msgs
.size());
1530 ASSERT_EQ(1U, msgs
[0].size());
1532 CheckRequestCompleteErrorCode(msgs
[0][0], net::ERR_ACCESS_DENIED
);
1535 // Tests CancelRequestsForProcess
1536 TEST_F(ResourceDispatcherHostTest
, TestProcessCancel
) {
1537 scoped_refptr
<TestFilter
> test_filter
= new TestFilter(
1538 browser_context_
->GetResourceContext());
1539 child_ids_
.insert(test_filter
->child_id());
1541 // request 1 goes to the test delegate
1542 ResourceHostMsg_Request request
= CreateResourceRequest(
1543 "GET", RESOURCE_TYPE_SUB_RESOURCE
, net::URLRequestTestJob::test_url_1());
1545 MakeTestRequestWithResourceType(test_filter
.get(), 0, 1,
1546 net::URLRequestTestJob::test_url_1(),
1547 RESOURCE_TYPE_SUB_RESOURCE
);
1549 // request 2 goes to us
1550 MakeTestRequest(0, 2, net::URLRequestTestJob::test_url_2());
1552 // request 3 goes to the test delegate
1553 MakeTestRequestWithResourceType(test_filter
.get(), 0, 3,
1554 net::URLRequestTestJob::test_url_3(),
1555 RESOURCE_TYPE_SUB_RESOURCE
);
1557 // request 4 goes to us
1558 MakeTestRequestWithResourceType(filter_
.get(), 0, 4,
1559 net::URLRequestTestJob::test_url_4(),
1560 RESOURCE_TYPE_PREFETCH
); // detachable type
1563 // Make sure all requests have finished stage one. test_url_1 will have
1565 base::MessageLoop::current()->RunUntilIdle();
1568 // Now that the async IO path is in place, the IO always completes on the
1569 // initial call; so the requests have already completed. This basically
1570 // breaks the whole test.
1571 //EXPECT_EQ(3, host_.pending_requests());
1573 // Process test_url_2 and test_url_3 for one level so one callback is called.
1574 // We'll cancel test_url_4 (detachable) before processing it to verify that it
1575 // delays the cancel.
1576 for (int i
= 0; i
< 2; i
++)
1577 EXPECT_TRUE(net::URLRequestTestJob::ProcessOnePendingMessage());
1579 // Cancel the requests to the test process.
1580 host_
.CancelRequestsForProcess(filter_
->child_id());
1581 test_filter
->set_canceled(true);
1583 // The requests should all be cancelled, except request 4, which is detached.
1584 EXPECT_EQ(1, host_
.pending_requests());
1585 GlobalRequestID
global_request_id(filter_
->child_id(), 4);
1586 ResourceRequestInfoImpl
* info
= ResourceRequestInfoImpl::ForRequest(
1587 host_
.GetURLRequest(global_request_id
));
1588 ASSERT_TRUE(info
->detachable_handler()->is_detached());
1590 // Flush all the pending requests.
1591 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1593 EXPECT_EQ(0, host_
.pending_requests());
1595 // The test delegate should not have gotten any messages after being canceled.
1596 ASSERT_EQ(0, test_filter
->received_after_canceled());
1598 // There should be two results.
1599 ResourceIPCAccumulator::ClassifiedMessages msgs
;
1600 accum_
.GetClassifiedMessages(&msgs
);
1601 ASSERT_EQ(2U, msgs
.size());
1602 CheckSuccessfulRequest(msgs
[0], net::URLRequestTestJob::test_data_2());
1603 // The detachable request was cancelled by the renderer before it
1604 // finished. From the perspective of the renderer, it should have cancelled.
1605 ASSERT_EQ(2U, msgs
[1].size());
1606 ASSERT_EQ(ResourceMsg_ReceivedResponse::ID
, msgs
[1][0].type());
1607 CheckRequestCompleteErrorCode(msgs
[1][1], net::ERR_ABORTED
);
1608 // But it completed anyway. For the network stack, no requests were canceled.
1609 EXPECT_EQ(4, network_delegate()->completed_requests());
1610 EXPECT_EQ(0, network_delegate()->canceled_requests());
1611 EXPECT_EQ(0, network_delegate()->error_count());
1614 TEST_F(ResourceDispatcherHostTest
, TestProcessCancelDetachedTimesOut
) {
1615 MakeTestRequestWithResourceType(filter_
.get(), 0, 1,
1616 net::URLRequestTestJob::test_url_4(),
1617 RESOURCE_TYPE_PREFETCH
); // detachable type
1618 GlobalRequestID
global_request_id(filter_
->child_id(), 1);
1619 ResourceRequestInfoImpl
* info
= ResourceRequestInfoImpl::ForRequest(
1620 host_
.GetURLRequest(global_request_id
));
1621 ASSERT_TRUE(info
->detachable_handler());
1622 info
->detachable_handler()->set_cancel_delay(
1623 base::TimeDelta::FromMilliseconds(200));
1624 base::MessageLoop::current()->RunUntilIdle();
1626 // Cancel the requests to the test process.
1627 host_
.CancelRequestsForProcess(filter_
->child_id());
1628 EXPECT_EQ(1, host_
.pending_requests());
1630 // Wait until after the delay timer times out before we start processing any
1632 base::OneShotTimer
<base::MessageLoop
> timer
;
1633 timer
.Start(FROM_HERE
, base::TimeDelta::FromMilliseconds(210),
1634 base::MessageLoop::current(), &base::MessageLoop::QuitWhenIdle
);
1635 base::MessageLoop::current()->Run();
1637 // The prefetch should be cancelled by now.
1638 EXPECT_EQ(0, host_
.pending_requests());
1640 // In case any messages are still to be processed.
1641 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1642 base::MessageLoop::current()->RunUntilIdle();
1644 ResourceIPCAccumulator::ClassifiedMessages msgs
;
1645 accum_
.GetClassifiedMessages(&msgs
);
1647 ASSERT_EQ(1U, msgs
.size());
1649 // The request should have cancelled.
1650 ASSERT_EQ(2U, msgs
[0].size());
1651 ASSERT_EQ(ResourceMsg_ReceivedResponse::ID
, msgs
[0][0].type());
1652 CheckRequestCompleteErrorCode(msgs
[0][1], net::ERR_ABORTED
);
1653 // And not run to completion.
1654 EXPECT_EQ(1, network_delegate()->completed_requests());
1655 EXPECT_EQ(1, network_delegate()->canceled_requests());
1656 EXPECT_EQ(0, network_delegate()->error_count());
1659 // Tests blocking and resuming requests.
1660 TEST_F(ResourceDispatcherHostTest
, TestBlockingResumingRequests
) {
1661 host_
.BlockRequestsForRoute(filter_
->child_id(), 1);
1662 host_
.BlockRequestsForRoute(filter_
->child_id(), 2);
1663 host_
.BlockRequestsForRoute(filter_
->child_id(), 3);
1665 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
1666 MakeTestRequest(1, 2, net::URLRequestTestJob::test_url_2());
1667 MakeTestRequest(0, 3, net::URLRequestTestJob::test_url_3());
1668 MakeTestRequest(1, 4, net::URLRequestTestJob::test_url_1());
1669 MakeTestRequest(2, 5, net::URLRequestTestJob::test_url_2());
1670 MakeTestRequest(3, 6, net::URLRequestTestJob::test_url_3());
1672 // Flush all the pending requests
1673 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1675 // Sort out all the messages we saw by request
1676 ResourceIPCAccumulator::ClassifiedMessages msgs
;
1677 accum_
.GetClassifiedMessages(&msgs
);
1679 // All requests but the 2 for the RVH 0 should have been blocked.
1680 ASSERT_EQ(2U, msgs
.size());
1682 CheckSuccessfulRequest(msgs
[0], net::URLRequestTestJob::test_data_1());
1683 CheckSuccessfulRequest(msgs
[1], net::URLRequestTestJob::test_data_3());
1685 // Resume requests for RVH 1 and flush pending requests.
1686 host_
.ResumeBlockedRequestsForRoute(filter_
->child_id(), 1);
1688 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1691 accum_
.GetClassifiedMessages(&msgs
);
1692 ASSERT_EQ(2U, msgs
.size());
1693 CheckSuccessfulRequest(msgs
[0], net::URLRequestTestJob::test_data_2());
1694 CheckSuccessfulRequest(msgs
[1], net::URLRequestTestJob::test_data_1());
1696 // Test that new requests are not blocked for RVH 1.
1697 MakeTestRequest(1, 7, net::URLRequestTestJob::test_url_1());
1698 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1700 accum_
.GetClassifiedMessages(&msgs
);
1701 ASSERT_EQ(1U, msgs
.size());
1702 CheckSuccessfulRequest(msgs
[0], net::URLRequestTestJob::test_data_1());
1704 // Now resumes requests for all RVH (2 and 3).
1705 host_
.ResumeBlockedRequestsForRoute(filter_
->child_id(), 2);
1706 host_
.ResumeBlockedRequestsForRoute(filter_
->child_id(), 3);
1708 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1711 accum_
.GetClassifiedMessages(&msgs
);
1712 ASSERT_EQ(2U, msgs
.size());
1713 CheckSuccessfulRequest(msgs
[0], net::URLRequestTestJob::test_data_2());
1714 CheckSuccessfulRequest(msgs
[1], net::URLRequestTestJob::test_data_3());
1717 // Tests blocking and canceling requests.
1718 TEST_F(ResourceDispatcherHostTest
, TestBlockingCancelingRequests
) {
1719 host_
.BlockRequestsForRoute(filter_
->child_id(), 1);
1721 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
1722 MakeTestRequest(1, 2, net::URLRequestTestJob::test_url_2());
1723 MakeTestRequest(0, 3, net::URLRequestTestJob::test_url_3());
1724 MakeTestRequest(1, 4, net::URLRequestTestJob::test_url_1());
1725 // Blocked detachable resources should not delay cancellation.
1726 MakeTestRequestWithResourceType(filter_
.get(), 1, 5,
1727 net::URLRequestTestJob::test_url_4(),
1728 RESOURCE_TYPE_PREFETCH
); // detachable type
1730 // Flush all the pending requests.
1731 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1733 // Sort out all the messages we saw by request.
1734 ResourceIPCAccumulator::ClassifiedMessages msgs
;
1735 accum_
.GetClassifiedMessages(&msgs
);
1737 // The 2 requests for the RVH 0 should have been processed.
1738 ASSERT_EQ(2U, msgs
.size());
1740 CheckSuccessfulRequest(msgs
[0], net::URLRequestTestJob::test_data_1());
1741 CheckSuccessfulRequest(msgs
[1], net::URLRequestTestJob::test_data_3());
1743 // Cancel requests for RVH 1.
1744 host_
.CancelBlockedRequestsForRoute(filter_
->child_id(), 1);
1746 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1749 accum_
.GetClassifiedMessages(&msgs
);
1750 ASSERT_EQ(0U, msgs
.size());
1753 // Tests that blocked requests are canceled if their associated process dies.
1754 TEST_F(ResourceDispatcherHostTest
, TestBlockedRequestsProcessDies
) {
1755 // This second filter is used to emulate a second process.
1756 scoped_refptr
<ForwardingFilter
> second_filter
= MakeForwardingFilter();
1758 host_
.BlockRequestsForRoute(second_filter
->child_id(), 0);
1760 MakeTestRequestWithResourceType(filter_
.get(), 0, 1,
1761 net::URLRequestTestJob::test_url_1(),
1762 RESOURCE_TYPE_SUB_RESOURCE
);
1763 MakeTestRequestWithResourceType(second_filter
.get(), 0, 2,
1764 net::URLRequestTestJob::test_url_2(),
1765 RESOURCE_TYPE_SUB_RESOURCE
);
1766 MakeTestRequestWithResourceType(filter_
.get(), 0, 3,
1767 net::URLRequestTestJob::test_url_3(),
1768 RESOURCE_TYPE_SUB_RESOURCE
);
1769 MakeTestRequestWithResourceType(second_filter
.get(), 0, 4,
1770 net::URLRequestTestJob::test_url_1(),
1771 RESOURCE_TYPE_SUB_RESOURCE
);
1772 MakeTestRequestWithResourceType(second_filter
.get(), 0, 5,
1773 net::URLRequestTestJob::test_url_4(),
1774 RESOURCE_TYPE_PREFETCH
); // detachable type
1776 // Simulate process death.
1777 host_
.CancelRequestsForProcess(second_filter
->child_id());
1779 // Flush all the pending requests.
1780 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1782 // Sort out all the messages we saw by request.
1783 ResourceIPCAccumulator::ClassifiedMessages msgs
;
1784 accum_
.GetClassifiedMessages(&msgs
);
1786 // The 2 requests for the RVH 0 should have been processed. Note that
1787 // blocked detachable requests are canceled without delay.
1788 ASSERT_EQ(2U, msgs
.size());
1790 CheckSuccessfulRequest(msgs
[0], net::URLRequestTestJob::test_data_1());
1791 CheckSuccessfulRequest(msgs
[1], net::URLRequestTestJob::test_data_3());
1793 EXPECT_TRUE(host_
.blocked_loaders_map_
.empty());
1796 // Tests that blocked requests don't leak when the ResourceDispatcherHost goes
1797 // away. Note that we rely on Purify for finding the leaks if any.
1798 // If this test turns the Purify bot red, check the ResourceDispatcherHost
1799 // destructor to make sure the blocked requests are deleted.
1800 TEST_F(ResourceDispatcherHostTest
, TestBlockedRequestsDontLeak
) {
1801 // This second filter is used to emulate a second process.
1802 scoped_refptr
<ForwardingFilter
> second_filter
= MakeForwardingFilter();
1804 host_
.BlockRequestsForRoute(filter_
->child_id(), 1);
1805 host_
.BlockRequestsForRoute(filter_
->child_id(), 2);
1806 host_
.BlockRequestsForRoute(second_filter
->child_id(), 1);
1808 MakeTestRequestWithResourceType(filter_
.get(), 0, 1,
1809 net::URLRequestTestJob::test_url_1(),
1810 RESOURCE_TYPE_SUB_RESOURCE
);
1811 MakeTestRequestWithResourceType(filter_
.get(), 1, 2,
1812 net::URLRequestTestJob::test_url_2(),
1813 RESOURCE_TYPE_SUB_RESOURCE
);
1814 MakeTestRequestWithResourceType(filter_
.get(), 0, 3,
1815 net::URLRequestTestJob::test_url_3(),
1816 RESOURCE_TYPE_SUB_RESOURCE
);
1817 MakeTestRequestWithResourceType(second_filter
.get(), 1, 4,
1818 net::URLRequestTestJob::test_url_1(),
1819 RESOURCE_TYPE_SUB_RESOURCE
);
1820 MakeTestRequestWithResourceType(filter_
.get(), 2, 5,
1821 net::URLRequestTestJob::test_url_2(),
1822 RESOURCE_TYPE_SUB_RESOURCE
);
1823 MakeTestRequestWithResourceType(filter_
.get(), 2, 6,
1824 net::URLRequestTestJob::test_url_3(),
1825 RESOURCE_TYPE_SUB_RESOURCE
);
1826 MakeTestRequestWithResourceType(filter_
.get(), 0, 7,
1827 net::URLRequestTestJob::test_url_4(),
1828 RESOURCE_TYPE_PREFETCH
); // detachable type
1829 MakeTestRequestWithResourceType(second_filter
.get(), 1, 8,
1830 net::URLRequestTestJob::test_url_4(),
1831 RESOURCE_TYPE_PREFETCH
); // detachable type
1833 host_
.CancelRequestsForProcess(filter_
->child_id());
1834 host_
.CancelRequestsForProcess(second_filter
->child_id());
1836 // Flush all the pending requests.
1837 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1840 // Test the private helper method "CalculateApproximateMemoryCost()".
1841 TEST_F(ResourceDispatcherHostTest
, CalculateApproximateMemoryCost
) {
1842 net::URLRequestContext context
;
1843 scoped_ptr
<net::URLRequest
> req(context
.CreateRequest(
1844 GURL("http://www.google.com"), net::DEFAULT_PRIORITY
, NULL
));
1847 ResourceDispatcherHostImpl::CalculateApproximateMemoryCost(req
.get()));
1849 // Add 9 bytes of referrer.
1850 req
->SetReferrer("123456789");
1853 ResourceDispatcherHostImpl::CalculateApproximateMemoryCost(req
.get()));
1855 // Add 33 bytes of upload content.
1856 std::string upload_content
;
1857 upload_content
.resize(33);
1858 std::fill(upload_content
.begin(), upload_content
.end(), 'x');
1859 scoped_ptr
<net::UploadElementReader
> reader(new net::UploadBytesElementReader(
1860 upload_content
.data(), upload_content
.size()));
1862 net::ElementsUploadDataStream::CreateWithReader(reader
.Pass(), 0));
1864 // Since the upload throttling is disabled, this has no effect on the cost.
1867 ResourceDispatcherHostImpl::CalculateApproximateMemoryCost(req
.get()));
1870 // Test that too much memory for outstanding requests for a particular
1871 // render_process_host_id causes requests to fail.
1872 TEST_F(ResourceDispatcherHostTest
, TooMuchOutstandingRequestsMemory
) {
1873 // Expected cost of each request as measured by
1874 // ResourceDispatcherHost::CalculateApproximateMemoryCost().
1875 int kMemoryCostOfTest2Req
=
1876 ResourceDispatcherHostImpl::kAvgBytesPerOutstandingRequest
+
1877 std::string("GET").size() +
1878 net::URLRequestTestJob::test_url_2().spec().size();
1880 // Tighten the bound on the ResourceDispatcherHost, to speed things up.
1881 int kMaxCostPerProcess
= 440000;
1882 host_
.set_max_outstanding_requests_cost_per_process(kMaxCostPerProcess
);
1884 // Determine how many instance of test_url_2() we can request before
1885 // throttling kicks in.
1886 size_t kMaxRequests
= kMaxCostPerProcess
/ kMemoryCostOfTest2Req
;
1888 // This second filter is used to emulate a second process.
1889 scoped_refptr
<ForwardingFilter
> second_filter
= MakeForwardingFilter();
1891 // Saturate the number of outstanding requests for our process.
1892 for (size_t i
= 0; i
< kMaxRequests
; ++i
) {
1893 MakeTestRequestWithResourceType(filter_
.get(), 0, i
+ 1,
1894 net::URLRequestTestJob::test_url_2(),
1895 RESOURCE_TYPE_SUB_RESOURCE
);
1898 // Issue two more requests for our process -- these should fail immediately.
1899 MakeTestRequestWithResourceType(filter_
.get(), 0, kMaxRequests
+ 1,
1900 net::URLRequestTestJob::test_url_2(),
1901 RESOURCE_TYPE_SUB_RESOURCE
);
1902 MakeTestRequestWithResourceType(filter_
.get(), 0, kMaxRequests
+ 2,
1903 net::URLRequestTestJob::test_url_2(),
1904 RESOURCE_TYPE_SUB_RESOURCE
);
1906 // Issue two requests for the second process -- these should succeed since
1907 // it is just process 0 that is saturated.
1908 MakeTestRequestWithResourceType(second_filter
.get(), 0, kMaxRequests
+ 3,
1909 net::URLRequestTestJob::test_url_2(),
1910 RESOURCE_TYPE_SUB_RESOURCE
);
1911 MakeTestRequestWithResourceType(second_filter
.get(), 0, kMaxRequests
+ 4,
1912 net::URLRequestTestJob::test_url_2(),
1913 RESOURCE_TYPE_SUB_RESOURCE
);
1915 // Flush all the pending requests.
1916 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1917 base::MessageLoop::current()->RunUntilIdle();
1919 // Sorts out all the messages we saw by request.
1920 ResourceIPCAccumulator::ClassifiedMessages msgs
;
1921 accum_
.GetClassifiedMessages(&msgs
);
1923 // We issued (kMaxRequests + 4) total requests.
1924 ASSERT_EQ(kMaxRequests
+ 4, msgs
.size());
1926 // Check that the first kMaxRequests succeeded.
1927 for (size_t i
= 0; i
< kMaxRequests
; ++i
)
1928 CheckSuccessfulRequest(msgs
[i
], net::URLRequestTestJob::test_data_2());
1930 // Check that the subsequent two requests (kMaxRequests + 1) and
1931 // (kMaxRequests + 2) were failed, since the per-process bound was reached.
1932 for (int i
= 0; i
< 2; ++i
) {
1933 // Should have sent a single RequestComplete message.
1934 int index
= kMaxRequests
+ i
;
1935 CheckFailedRequest(msgs
[index
], net::URLRequestTestJob::test_data_2(),
1936 net::ERR_INSUFFICIENT_RESOURCES
);
1939 // The final 2 requests should have succeeded.
1940 CheckSuccessfulRequest(msgs
[kMaxRequests
+ 2],
1941 net::URLRequestTestJob::test_data_2());
1942 CheckSuccessfulRequest(msgs
[kMaxRequests
+ 3],
1943 net::URLRequestTestJob::test_data_2());
1946 // Test that when too many requests are outstanding for a particular
1947 // render_process_host_id, any subsequent request from it fails. Also verify
1948 // that the global limit is honored.
1949 TEST_F(ResourceDispatcherHostTest
, TooManyOutstandingRequests
) {
1950 // Tighten the bound on the ResourceDispatcherHost, to speed things up.
1951 const size_t kMaxRequestsPerProcess
= 2;
1952 host_
.set_max_num_in_flight_requests_per_process(kMaxRequestsPerProcess
);
1953 const size_t kMaxRequests
= 3;
1954 host_
.set_max_num_in_flight_requests(kMaxRequests
);
1956 // Needed to emulate additional processes.
1957 scoped_refptr
<ForwardingFilter
> second_filter
= MakeForwardingFilter();
1958 scoped_refptr
<ForwardingFilter
> third_filter
= MakeForwardingFilter();
1960 // Saturate the number of outstanding requests for our process.
1961 for (size_t i
= 0; i
< kMaxRequestsPerProcess
; ++i
) {
1962 MakeTestRequestWithResourceType(filter_
.get(), 0, i
+ 1,
1963 net::URLRequestTestJob::test_url_2(),
1964 RESOURCE_TYPE_SUB_RESOURCE
);
1967 // Issue another request for our process -- this should fail immediately.
1968 MakeTestRequestWithResourceType(filter_
.get(), 0, kMaxRequestsPerProcess
+ 1,
1969 net::URLRequestTestJob::test_url_2(),
1970 RESOURCE_TYPE_SUB_RESOURCE
);
1972 // Issue a request for the second process -- this should succeed, because it
1973 // is just process 0 that is saturated.
1974 MakeTestRequestWithResourceType(
1975 second_filter
.get(), 0, kMaxRequestsPerProcess
+ 2,
1976 net::URLRequestTestJob::test_url_2(), RESOURCE_TYPE_SUB_RESOURCE
);
1978 // Issue a request for the third process -- this should fail, because the
1979 // global limit has been reached.
1980 MakeTestRequestWithResourceType(
1981 third_filter
.get(), 0, kMaxRequestsPerProcess
+ 3,
1982 net::URLRequestTestJob::test_url_2(), RESOURCE_TYPE_SUB_RESOURCE
);
1984 // Flush all the pending requests.
1985 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1986 base::MessageLoop::current()->RunUntilIdle();
1988 // Sorts out all the messages we saw by request.
1989 ResourceIPCAccumulator::ClassifiedMessages msgs
;
1990 accum_
.GetClassifiedMessages(&msgs
);
1992 // The processes issued the following requests:
1993 // #1 issued kMaxRequestsPerProcess that passed + 1 that failed
1994 // #2 issued 1 request that passed
1995 // #3 issued 1 request that failed
1996 ASSERT_EQ((kMaxRequestsPerProcess
+ 1) + 1 + 1, msgs
.size());
1998 for (size_t i
= 0; i
< kMaxRequestsPerProcess
; ++i
)
1999 CheckSuccessfulRequest(msgs
[i
], net::URLRequestTestJob::test_data_2());
2001 CheckFailedRequest(msgs
[kMaxRequestsPerProcess
+ 0],
2002 net::URLRequestTestJob::test_data_2(),
2003 net::ERR_INSUFFICIENT_RESOURCES
);
2004 CheckSuccessfulRequest(msgs
[kMaxRequestsPerProcess
+ 1],
2005 net::URLRequestTestJob::test_data_2());
2006 CheckFailedRequest(msgs
[kMaxRequestsPerProcess
+ 2],
2007 net::URLRequestTestJob::test_data_2(),
2008 net::ERR_INSUFFICIENT_RESOURCES
);
2011 // Tests that we sniff the mime type for a simple request.
2012 TEST_F(ResourceDispatcherHostTest
, MimeSniffed
) {
2013 std::string
raw_headers("HTTP/1.1 200 OK\n\n");
2014 std::string
response_data("<html><title>Test One</title></html>");
2015 SetResponse(raw_headers
, response_data
);
2017 HandleScheme("http");
2018 MakeTestRequest(0, 1, GURL("http:bla"));
2020 // Flush all pending requests.
2021 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2023 // Sorts out all the messages we saw by request.
2024 ResourceIPCAccumulator::ClassifiedMessages msgs
;
2025 accum_
.GetClassifiedMessages(&msgs
);
2026 ASSERT_EQ(1U, msgs
.size());
2028 ResourceResponseHead response_head
;
2029 GetResponseHead(msgs
[0], &response_head
);
2030 ASSERT_EQ("text/html", response_head
.mime_type
);
2033 // Tests that we don't sniff the mime type when the server provides one.
2034 TEST_F(ResourceDispatcherHostTest
, MimeNotSniffed
) {
2035 std::string
raw_headers("HTTP/1.1 200 OK\n"
2036 "Content-type: image/jpeg\n\n");
2037 std::string
response_data("<html><title>Test One</title></html>");
2038 SetResponse(raw_headers
, response_data
);
2040 HandleScheme("http");
2041 MakeTestRequest(0, 1, GURL("http:bla"));
2043 // Flush all pending requests.
2044 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2046 // Sorts out all the messages we saw by request.
2047 ResourceIPCAccumulator::ClassifiedMessages msgs
;
2048 accum_
.GetClassifiedMessages(&msgs
);
2049 ASSERT_EQ(1U, msgs
.size());
2051 ResourceResponseHead response_head
;
2052 GetResponseHead(msgs
[0], &response_head
);
2053 ASSERT_EQ("image/jpeg", response_head
.mime_type
);
2056 // Tests that we don't sniff the mime type when there is no message body.
2057 TEST_F(ResourceDispatcherHostTest
, MimeNotSniffed2
) {
2058 SetResponse("HTTP/1.1 304 Not Modified\n\n");
2060 HandleScheme("http");
2061 MakeTestRequest(0, 1, GURL("http:bla"));
2063 // Flush all pending requests.
2064 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2066 // Sorts out all the messages we saw by request.
2067 ResourceIPCAccumulator::ClassifiedMessages msgs
;
2068 accum_
.GetClassifiedMessages(&msgs
);
2069 ASSERT_EQ(1U, msgs
.size());
2071 ResourceResponseHead response_head
;
2072 GetResponseHead(msgs
[0], &response_head
);
2073 ASSERT_EQ("", response_head
.mime_type
);
2076 TEST_F(ResourceDispatcherHostTest
, MimeSniff204
) {
2077 SetResponse("HTTP/1.1 204 No Content\n\n");
2079 HandleScheme("http");
2080 MakeTestRequest(0, 1, GURL("http:bla"));
2082 // Flush all pending requests.
2083 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2085 // Sorts out all the messages we saw by request.
2086 ResourceIPCAccumulator::ClassifiedMessages msgs
;
2087 accum_
.GetClassifiedMessages(&msgs
);
2088 ASSERT_EQ(1U, msgs
.size());
2090 ResourceResponseHead response_head
;
2091 GetResponseHead(msgs
[0], &response_head
);
2092 ASSERT_EQ("text/plain", response_head
.mime_type
);
2095 TEST_F(ResourceDispatcherHostTest
, MimeSniffEmpty
) {
2096 SetResponse("HTTP/1.1 200 OK\n\n");
2098 HandleScheme("http");
2099 MakeTestRequest(0, 1, GURL("http:bla"));
2101 // Flush all pending requests.
2102 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2104 // Sorts out all the messages we saw by request.
2105 ResourceIPCAccumulator::ClassifiedMessages msgs
;
2106 accum_
.GetClassifiedMessages(&msgs
);
2107 ASSERT_EQ(1U, msgs
.size());
2109 ResourceResponseHead response_head
;
2110 GetResponseHead(msgs
[0], &response_head
);
2111 ASSERT_EQ("text/plain", response_head
.mime_type
);
2114 // Tests for crbug.com/31266 (Non-2xx + application/octet-stream).
2115 TEST_F(ResourceDispatcherHostTest
, ForbiddenDownload
) {
2116 std::string
raw_headers("HTTP/1.1 403 Forbidden\n"
2117 "Content-disposition: attachment; filename=blah\n"
2118 "Content-type: application/octet-stream\n\n");
2119 std::string
response_data("<html><title>Test One</title></html>");
2120 SetResponse(raw_headers
, response_data
);
2122 HandleScheme("http");
2124 // Only MAIN_FRAMEs can trigger a download.
2125 MakeTestRequestWithResourceType(filter_
.get(), 0, 1, GURL("http:bla"),
2126 RESOURCE_TYPE_MAIN_FRAME
);
2128 // Flush all pending requests.
2129 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2130 base::MessageLoop::current()->RunUntilIdle();
2132 // Sorts out all the messages we saw by request.
2133 ResourceIPCAccumulator::ClassifiedMessages msgs
;
2134 accum_
.GetClassifiedMessages(&msgs
);
2136 // We should have gotten one RequestComplete message.
2137 ASSERT_EQ(1U, msgs
.size());
2138 ASSERT_EQ(1U, msgs
[0].size());
2139 EXPECT_EQ(ResourceMsg_RequestComplete::ID
, msgs
[0][0].type());
2141 // The RequestComplete message should have had the error code of
2142 // ERR_INVALID_RESPONSE.
2143 CheckRequestCompleteErrorCode(msgs
[0][0], net::ERR_INVALID_RESPONSE
);
2146 // Test for http://crbug.com/76202 . We don't want to destroy a
2147 // download request prematurely when processing a cancellation from
2149 TEST_F(ResourceDispatcherHostTest
, IgnoreCancelForDownloads
) {
2150 EXPECT_EQ(0, host_
.pending_requests());
2152 int render_view_id
= 0;
2155 std::string
raw_headers("HTTP\n"
2156 "Content-disposition: attachment; filename=foo\n\n");
2157 std::string
response_data("01234567890123456789\x01foobar");
2159 // Get past sniffing metrics in the MimeTypeResourceHandler. Note that
2160 // if we don't get past the sniffing metrics, the result will be that
2161 // the MimeTypeResourceHandler won't have figured out that it's a download,
2162 // won't have constructed a DownloadResourceHandler, and and the request will
2163 // be successfully canceled below, failing the test.
2164 response_data
.resize(1025, ' ');
2166 SetResponse(raw_headers
, response_data
);
2167 job_factory_
->SetDelayedCompleteJobGeneration(true);
2168 HandleScheme("http");
2170 MakeTestRequestWithResourceType(filter_
.get(), render_view_id
, request_id
,
2171 GURL("http://example.com/blah"),
2172 RESOURCE_TYPE_MAIN_FRAME
);
2173 // Return some data so that the request is identified as a download
2174 // and the proper resource handlers are created.
2175 EXPECT_TRUE(net::URLRequestTestJob::ProcessOnePendingMessage());
2177 // And now simulate a cancellation coming from the renderer.
2178 ResourceHostMsg_CancelRequest
msg(request_id
);
2179 host_
.OnMessageReceived(msg
, filter_
.get());
2181 // Since the request had already started processing as a download,
2182 // the cancellation above should have been ignored and the request
2183 // should still be alive.
2184 EXPECT_EQ(1, host_
.pending_requests());
2186 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2189 TEST_F(ResourceDispatcherHostTest
, CancelRequestsForContext
) {
2190 EXPECT_EQ(0, host_
.pending_requests());
2192 int render_view_id
= 0;
2195 std::string
raw_headers("HTTP\n"
2196 "Content-disposition: attachment; filename=foo\n\n");
2197 std::string
response_data("01234567890123456789\x01foobar");
2198 // Get past sniffing metrics.
2199 response_data
.resize(1025, ' ');
2201 SetResponse(raw_headers
, response_data
);
2202 job_factory_
->SetDelayedCompleteJobGeneration(true);
2203 HandleScheme("http");
2205 MakeTestRequestWithResourceType(filter_
.get(), render_view_id
, request_id
,
2206 GURL("http://example.com/blah"),
2207 RESOURCE_TYPE_MAIN_FRAME
);
2208 // Return some data so that the request is identified as a download
2209 // and the proper resource handlers are created.
2210 EXPECT_TRUE(net::URLRequestTestJob::ProcessOnePendingMessage());
2212 // And now simulate a cancellation coming from the renderer.
2213 ResourceHostMsg_CancelRequest
msg(request_id
);
2214 host_
.OnMessageReceived(msg
, filter_
.get());
2216 // Since the request had already started processing as a download,
2217 // the cancellation above should have been ignored and the request
2218 // should still be alive.
2219 EXPECT_EQ(1, host_
.pending_requests());
2221 // Cancelling by other methods shouldn't work either.
2222 host_
.CancelRequestsForProcess(render_view_id
);
2223 EXPECT_EQ(1, host_
.pending_requests());
2225 // Cancelling by context should work.
2226 host_
.CancelRequestsForContext(filter_
->resource_context());
2227 EXPECT_EQ(0, host_
.pending_requests());
2230 TEST_F(ResourceDispatcherHostTest
, CancelRequestsForContextDetached
) {
2231 EXPECT_EQ(0, host_
.pending_requests());
2233 int render_view_id
= 0;
2236 MakeTestRequestWithResourceType(filter_
.get(), render_view_id
, request_id
,
2237 net::URLRequestTestJob::test_url_4(),
2238 RESOURCE_TYPE_PREFETCH
); // detachable type
2240 // Simulate a cancel coming from the renderer.
2241 RendererCancelRequest(request_id
);
2243 // Since the request had already started processing as detachable,
2244 // the cancellation above should have been ignored and the request
2245 // should have been detached.
2246 EXPECT_EQ(1, host_
.pending_requests());
2248 // Cancelling by other methods should also leave it detached.
2249 host_
.CancelRequestsForProcess(render_view_id
);
2250 EXPECT_EQ(1, host_
.pending_requests());
2252 // Cancelling by context should work.
2253 host_
.CancelRequestsForContext(filter_
->resource_context());
2254 EXPECT_EQ(0, host_
.pending_requests());
2257 // Test the cancelling of requests that are being transferred to a new renderer
2258 // due to a redirection.
2259 TEST_F(ResourceDispatcherHostTest
, CancelRequestsForContextTransferred
) {
2260 EXPECT_EQ(0, host_
.pending_requests());
2262 int render_view_id
= 0;
2265 std::string
raw_headers("HTTP/1.1 200 OK\n"
2266 "Content-Type: text/html; charset=utf-8\n\n");
2267 std::string
response_data("<html>foobar</html>");
2269 SetResponse(raw_headers
, response_data
);
2270 HandleScheme("http");
2272 MakeTestRequestWithResourceType(filter_
.get(), render_view_id
, request_id
,
2273 GURL("http://example.com/blah"),
2274 RESOURCE_TYPE_MAIN_FRAME
);
2277 GlobalRequestID
global_request_id(filter_
->child_id(), request_id
);
2278 host_
.MarkAsTransferredNavigation(global_request_id
);
2280 // And now simulate a cancellation coming from the renderer.
2281 ResourceHostMsg_CancelRequest
msg(request_id
);
2282 host_
.OnMessageReceived(msg
, filter_
.get());
2284 // Since the request is marked as being transferred,
2285 // the cancellation above should have been ignored and the request
2286 // should still be alive.
2287 EXPECT_EQ(1, host_
.pending_requests());
2289 // Cancelling by other methods shouldn't work either.
2290 host_
.CancelRequestsForProcess(render_view_id
);
2291 EXPECT_EQ(1, host_
.pending_requests());
2293 // Cancelling by context should work.
2294 host_
.CancelRequestsForContext(filter_
->resource_context());
2295 EXPECT_EQ(0, host_
.pending_requests());
2298 // Test transferred navigations with text/html, which doesn't trigger any
2299 // content sniffing.
2300 TEST_F(ResourceDispatcherHostTest
, TransferNavigationHtml
) {
2301 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
2302 switches::kEnableBrowserSideNavigation
)) {
2303 SUCCEED() << "Test is not applicable with browser side navigation enabled";
2306 // This test expects the cross site request to be leaked, so it can transfer
2307 // the request directly.
2308 CrossSiteResourceHandler::SetLeakRequestsForTesting(true);
2310 EXPECT_EQ(0, host_
.pending_requests());
2312 int render_view_id
= 0;
2315 // Configure initial request.
2316 SetResponse("HTTP/1.1 302 Found\n"
2317 "Location: http://other.com/blech\n\n");
2319 HandleScheme("http");
2321 // Temporarily replace ContentBrowserClient with one that will trigger the
2322 // transfer navigation code paths.
2323 TransfersAllNavigationsContentBrowserClient new_client
;
2324 ContentBrowserClient
* old_client
= SetBrowserClientForTesting(&new_client
);
2326 MakeTestRequestWithResourceType(filter_
.get(), render_view_id
, request_id
,
2327 GURL("http://example.com/blah"),
2328 RESOURCE_TYPE_MAIN_FRAME
);
2330 // Now that we're blocked on the redirect, update the response and unblock by
2331 // telling the AsyncResourceHandler to follow the redirect.
2332 const std::string kResponseBody
= "hello world";
2333 SetResponse("HTTP/1.1 200 OK\n"
2334 "Content-Type: text/html\n\n",
2336 ResourceHostMsg_FollowRedirect
redirect_msg(request_id
);
2337 host_
.OnMessageReceived(redirect_msg
, filter_
.get());
2338 base::MessageLoop::current()->RunUntilIdle();
2340 // Flush all the pending requests to get the response through the
2341 // MimeTypeResourceHandler.
2342 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2344 // Restore, now that we've set up a transfer.
2345 SetBrowserClientForTesting(old_client
);
2347 // This second filter is used to emulate a second process.
2348 scoped_refptr
<ForwardingFilter
> second_filter
= MakeForwardingFilter();
2350 int new_render_view_id
= 1;
2351 int new_request_id
= 2;
2353 ResourceHostMsg_Request request
=
2354 CreateResourceRequest("GET", RESOURCE_TYPE_MAIN_FRAME
,
2355 GURL("http://other.com/blech"));
2356 request
.transferred_request_child_id
= filter_
->child_id();
2357 request
.transferred_request_request_id
= request_id
;
2359 ResourceHostMsg_RequestResource
transfer_request_msg(
2360 new_render_view_id
, new_request_id
, request
);
2361 host_
.OnMessageReceived(transfer_request_msg
, second_filter
.get());
2362 base::MessageLoop::current()->RunUntilIdle();
2364 // Check generated messages.
2365 ResourceIPCAccumulator::ClassifiedMessages msgs
;
2366 accum_
.GetClassifiedMessages(&msgs
);
2368 ASSERT_EQ(2U, msgs
.size());
2369 EXPECT_EQ(ResourceMsg_ReceivedRedirect::ID
, msgs
[0][0].type());
2370 CheckSuccessfulRequest(msgs
[1], kResponseBody
);
2373 // Test transferring two navigations with text/html, to ensure the resource
2374 // accounting works.
2375 TEST_F(ResourceDispatcherHostTest
, TransferTwoNavigationsHtml
) {
2376 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
2377 switches::kEnableBrowserSideNavigation
)) {
2378 SUCCEED() << "Test is not applicable with browser side navigation enabled";
2381 // This test expects the cross site request to be leaked, so it can transfer
2382 // the request directly.
2383 CrossSiteResourceHandler::SetLeakRequestsForTesting(true);
2385 EXPECT_EQ(0, host_
.pending_requests());
2387 int render_view_id
= 0;
2390 // Configure initial request.
2391 const std::string kResponseBody
= "hello world";
2392 SetResponse("HTTP/1.1 200 OK\n"
2393 "Content-Type: text/html\n\n",
2396 HandleScheme("http");
2398 // Temporarily replace ContentBrowserClient with one that will trigger the
2399 // transfer navigation code paths.
2400 TransfersAllNavigationsContentBrowserClient new_client
;
2401 ContentBrowserClient
* old_client
= SetBrowserClientForTesting(&new_client
);
2403 // Make the first request.
2404 MakeTestRequestWithResourceType(filter_
.get(), render_view_id
, request_id
,
2405 GURL("http://example.com/blah"),
2406 RESOURCE_TYPE_MAIN_FRAME
);
2408 // Make a second request from the same process.
2409 int second_request_id
= 2;
2410 MakeTestRequestWithResourceType(filter_
.get(), render_view_id
,
2412 GURL("http://example.com/foo"),
2413 RESOURCE_TYPE_MAIN_FRAME
);
2415 // Flush all the pending requests to get the response through the
2416 // MimeTypeResourceHandler.
2417 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2419 // Restore, now that we've set up a transfer.
2420 SetBrowserClientForTesting(old_client
);
2422 // This second filter is used to emulate a second process.
2423 scoped_refptr
<ForwardingFilter
> second_filter
= MakeForwardingFilter();
2425 // Transfer the first request.
2426 int new_render_view_id
= 1;
2427 int new_request_id
= 5;
2428 ResourceHostMsg_Request request
=
2429 CreateResourceRequest("GET", RESOURCE_TYPE_MAIN_FRAME
,
2430 GURL("http://example.com/blah"));
2431 request
.transferred_request_child_id
= filter_
->child_id();
2432 request
.transferred_request_request_id
= request_id
;
2434 ResourceHostMsg_RequestResource
transfer_request_msg(
2435 new_render_view_id
, new_request_id
, request
);
2436 host_
.OnMessageReceived(transfer_request_msg
, second_filter
.get());
2437 base::MessageLoop::current()->RunUntilIdle();
2439 // Transfer the second request.
2440 int new_second_request_id
= 6;
2441 ResourceHostMsg_Request second_request
=
2442 CreateResourceRequest("GET", RESOURCE_TYPE_MAIN_FRAME
,
2443 GURL("http://example.com/foo"));
2444 request
.transferred_request_child_id
= filter_
->child_id();
2445 request
.transferred_request_request_id
= second_request_id
;
2447 ResourceHostMsg_RequestResource
second_transfer_request_msg(
2448 new_render_view_id
, new_second_request_id
, second_request
);
2449 host_
.OnMessageReceived(second_transfer_request_msg
, second_filter
.get());
2450 base::MessageLoop::current()->RunUntilIdle();
2452 // Check generated messages.
2453 ResourceIPCAccumulator::ClassifiedMessages msgs
;
2454 accum_
.GetClassifiedMessages(&msgs
);
2456 ASSERT_EQ(2U, msgs
.size());
2457 CheckSuccessfulRequest(msgs
[0], kResponseBody
);
2460 // Test transferred navigations with text/plain, which causes
2461 // MimeTypeResourceHandler to buffer the response to sniff the content before
2462 // the transfer occurs.
2463 TEST_F(ResourceDispatcherHostTest
, TransferNavigationText
) {
2464 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
2465 switches::kEnableBrowserSideNavigation
)) {
2466 SUCCEED() << "Test is not applicable with browser side navigation enabled";
2469 // This test expects the cross site request to be leaked, so it can transfer
2470 // the request directly.
2471 CrossSiteResourceHandler::SetLeakRequestsForTesting(true);
2473 EXPECT_EQ(0, host_
.pending_requests());
2475 int render_view_id
= 0;
2478 // Configure initial request.
2479 SetResponse("HTTP/1.1 302 Found\n"
2480 "Location: http://other.com/blech\n\n");
2482 HandleScheme("http");
2484 // Temporarily replace ContentBrowserClient with one that will trigger the
2485 // transfer navigation code paths.
2486 TransfersAllNavigationsContentBrowserClient new_client
;
2487 ContentBrowserClient
* old_client
= SetBrowserClientForTesting(&new_client
);
2489 MakeTestRequestWithResourceType(filter_
.get(), render_view_id
, request_id
,
2490 GURL("http://example.com/blah"),
2491 RESOURCE_TYPE_MAIN_FRAME
);
2493 // Now that we're blocked on the redirect, update the response and unblock by
2494 // telling the AsyncResourceHandler to follow the redirect. Use a text/plain
2495 // MIME type, which causes MimeTypeResourceHandler to buffer it before the
2497 const std::string kResponseBody
= "hello world";
2498 SetResponse("HTTP/1.1 200 OK\n"
2499 "Content-Type: text/plain\n\n",
2501 ResourceHostMsg_FollowRedirect
redirect_msg(request_id
);
2502 host_
.OnMessageReceived(redirect_msg
, filter_
.get());
2503 base::MessageLoop::current()->RunUntilIdle();
2505 // Flush all the pending requests to get the response through the
2506 // MimeTypeResourceHandler.
2507 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2509 // Restore, now that we've set up a transfer.
2510 SetBrowserClientForTesting(old_client
);
2512 // This second filter is used to emulate a second process.
2513 scoped_refptr
<ForwardingFilter
> second_filter
= MakeForwardingFilter();
2515 int new_render_view_id
= 1;
2516 int new_request_id
= 2;
2518 ResourceHostMsg_Request request
=
2519 CreateResourceRequest("GET", RESOURCE_TYPE_MAIN_FRAME
,
2520 GURL("http://other.com/blech"));
2521 request
.transferred_request_child_id
= filter_
->child_id();
2522 request
.transferred_request_request_id
= request_id
;
2524 ResourceHostMsg_RequestResource
transfer_request_msg(
2525 new_render_view_id
, new_request_id
, request
);
2526 host_
.OnMessageReceived(transfer_request_msg
, second_filter
.get());
2527 base::MessageLoop::current()->RunUntilIdle();
2529 // Check generated messages.
2530 ResourceIPCAccumulator::ClassifiedMessages msgs
;
2531 accum_
.GetClassifiedMessages(&msgs
);
2533 ASSERT_EQ(2U, msgs
.size());
2534 EXPECT_EQ(ResourceMsg_ReceivedRedirect::ID
, msgs
[0][0].type());
2535 CheckSuccessfulRequest(msgs
[1], kResponseBody
);
2538 TEST_F(ResourceDispatcherHostTest
, TransferNavigationWithProcessCrash
) {
2539 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
2540 switches::kEnableBrowserSideNavigation
)) {
2541 SUCCEED() << "Test is not applicable with browser side navigation enabled";
2544 // This test expects the cross site request to be leaked, so it can transfer
2545 // the request directly.
2546 CrossSiteResourceHandler::SetLeakRequestsForTesting(true);
2548 EXPECT_EQ(0, host_
.pending_requests());
2550 int render_view_id
= 0;
2552 int first_child_id
= -1;
2554 // Configure initial request.
2555 SetResponse("HTTP/1.1 302 Found\n"
2556 "Location: http://other.com/blech\n\n");
2557 const std::string kResponseBody
= "hello world";
2559 HandleScheme("http");
2561 // Temporarily replace ContentBrowserClient with one that will trigger the
2562 // transfer navigation code paths.
2563 TransfersAllNavigationsContentBrowserClient new_client
;
2564 ContentBrowserClient
* old_client
= SetBrowserClientForTesting(&new_client
);
2566 // Create a first filter that can be deleted before the second one starts.
2568 scoped_refptr
<ForwardingFilter
> first_filter
= MakeForwardingFilter();
2569 first_child_id
= first_filter
->child_id();
2571 ResourceHostMsg_Request first_request
=
2572 CreateResourceRequest("GET", RESOURCE_TYPE_MAIN_FRAME
,
2573 GURL("http://example.com/blah"));
2575 ResourceHostMsg_RequestResource
first_request_msg(
2576 render_view_id
, request_id
, first_request
);
2577 host_
.OnMessageReceived(first_request_msg
, first_filter
.get());
2578 base::MessageLoop::current()->RunUntilIdle();
2580 // Now that we're blocked on the redirect, update the response and unblock
2581 // by telling the AsyncResourceHandler to follow the redirect.
2582 SetResponse("HTTP/1.1 200 OK\n"
2583 "Content-Type: text/html\n\n",
2585 ResourceHostMsg_FollowRedirect
redirect_msg(request_id
);
2586 host_
.OnMessageReceived(redirect_msg
, first_filter
.get());
2587 base::MessageLoop::current()->RunUntilIdle();
2589 // Flush all the pending requests to get the response through the
2590 // MimeTypeResourceHandler.
2591 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2593 // The first filter is now deleted, as if the child process died.
2596 SetBrowserClientForTesting(old_client
);
2598 // Make sure we don't hold onto the ResourceMessageFilter after it is deleted.
2599 GlobalRequestID
first_global_request_id(first_child_id
, request_id
);
2601 // This second filter is used to emulate a second process.
2602 scoped_refptr
<ForwardingFilter
> second_filter
= MakeForwardingFilter();
2604 int new_render_view_id
= 1;
2605 int new_request_id
= 2;
2607 ResourceHostMsg_Request request
=
2608 CreateResourceRequest("GET", RESOURCE_TYPE_MAIN_FRAME
,
2609 GURL("http://other.com/blech"));
2610 request
.transferred_request_child_id
= first_child_id
;
2611 request
.transferred_request_request_id
= request_id
;
2614 child_ids_
.insert(second_filter
->child_id());
2615 ResourceHostMsg_RequestResource
transfer_request_msg(
2616 new_render_view_id
, new_request_id
, request
);
2617 host_
.OnMessageReceived(transfer_request_msg
, second_filter
.get());
2618 base::MessageLoop::current()->RunUntilIdle();
2620 // Check generated messages.
2621 ResourceIPCAccumulator::ClassifiedMessages msgs
;
2622 accum_
.GetClassifiedMessages(&msgs
);
2624 ASSERT_EQ(2U, msgs
.size());
2625 EXPECT_EQ(ResourceMsg_ReceivedRedirect::ID
, msgs
[0][0].type());
2626 CheckSuccessfulRequest(msgs
[1], kResponseBody
);
2629 TEST_F(ResourceDispatcherHostTest
, TransferNavigationWithTwoRedirects
) {
2630 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
2631 switches::kEnableBrowserSideNavigation
)) {
2632 SUCCEED() << "Test is not applicable with browser side navigation enabled";
2635 // This test expects the cross site request to be leaked, so it can transfer
2636 // the request directly.
2637 CrossSiteResourceHandler::SetLeakRequestsForTesting(true);
2639 EXPECT_EQ(0, host_
.pending_requests());
2641 int render_view_id
= 0;
2644 // Configure initial request.
2645 SetResponse("HTTP/1.1 302 Found\n"
2646 "Location: http://other.com/blech\n\n");
2648 HandleScheme("http");
2650 // Temporarily replace ContentBrowserClient with one that will trigger the
2651 // transfer navigation code paths.
2652 TransfersAllNavigationsContentBrowserClient new_client
;
2653 ContentBrowserClient
* old_client
= SetBrowserClientForTesting(&new_client
);
2655 MakeTestRequestWithResourceType(filter_
.get(), render_view_id
, request_id
,
2656 GURL("http://example.com/blah"),
2657 RESOURCE_TYPE_MAIN_FRAME
);
2659 // Now that we're blocked on the redirect, simulate hitting another redirect.
2660 SetResponse("HTTP/1.1 302 Found\n"
2661 "Location: http://other.com/blerg\n\n");
2662 ResourceHostMsg_FollowRedirect
redirect_msg(request_id
);
2663 host_
.OnMessageReceived(redirect_msg
, filter_
.get());
2664 base::MessageLoop::current()->RunUntilIdle();
2666 // Now that we're blocked on the second redirect, update the response and
2667 // unblock by telling the AsyncResourceHandler to follow the redirect.
2668 // Again, use text/plain to force MimeTypeResourceHandler to buffer before
2670 const std::string kResponseBody
= "hello world";
2671 SetResponse("HTTP/1.1 200 OK\n"
2672 "Content-Type: text/plain\n\n",
2674 ResourceHostMsg_FollowRedirect
redirect_msg2(request_id
);
2675 host_
.OnMessageReceived(redirect_msg2
, filter_
.get());
2676 base::MessageLoop::current()->RunUntilIdle();
2678 // Flush all the pending requests to get the response through the
2679 // MimeTypeResourceHandler.
2680 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2683 SetBrowserClientForTesting(old_client
);
2685 // This second filter is used to emulate a second process.
2686 scoped_refptr
<ForwardingFilter
> second_filter
= MakeForwardingFilter();
2688 int new_render_view_id
= 1;
2689 int new_request_id
= 2;
2691 ResourceHostMsg_Request request
=
2692 CreateResourceRequest("GET", RESOURCE_TYPE_MAIN_FRAME
,
2693 GURL("http://other.com/blech"));
2694 request
.transferred_request_child_id
= filter_
->child_id();
2695 request
.transferred_request_request_id
= request_id
;
2698 child_ids_
.insert(second_filter
->child_id());
2699 ResourceHostMsg_RequestResource
transfer_request_msg(
2700 new_render_view_id
, new_request_id
, request
);
2701 host_
.OnMessageReceived(transfer_request_msg
, second_filter
.get());
2703 // Verify that we update the ResourceRequestInfo.
2704 GlobalRequestID
global_request_id(second_filter
->child_id(), new_request_id
);
2705 const ResourceRequestInfoImpl
* info
= ResourceRequestInfoImpl::ForRequest(
2706 host_
.GetURLRequest(global_request_id
));
2707 EXPECT_EQ(second_filter
->child_id(), info
->GetChildID());
2708 EXPECT_EQ(new_render_view_id
, info
->GetRouteID());
2709 EXPECT_EQ(new_request_id
, info
->GetRequestID());
2710 EXPECT_EQ(second_filter
.get(), info
->filter());
2712 // Let request complete.
2713 base::MessageLoop::current()->RunUntilIdle();
2715 // Check generated messages.
2716 ResourceIPCAccumulator::ClassifiedMessages msgs
;
2717 accum_
.GetClassifiedMessages(&msgs
);
2719 ASSERT_EQ(2U, msgs
.size());
2720 EXPECT_EQ(ResourceMsg_ReceivedRedirect::ID
, msgs
[0][0].type());
2721 CheckSuccessfulRequest(msgs
[1], kResponseBody
);
2724 TEST_F(ResourceDispatcherHostTest
, UnknownURLScheme
) {
2725 EXPECT_EQ(0, host_
.pending_requests());
2727 HandleScheme("http");
2729 MakeTestRequestWithResourceType(filter_
.get(), 0, 1, GURL("foo://bar"),
2730 RESOURCE_TYPE_MAIN_FRAME
);
2732 // Flush all pending requests.
2733 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2735 // Sort all the messages we saw by request.
2736 ResourceIPCAccumulator::ClassifiedMessages msgs
;
2737 accum_
.GetClassifiedMessages(&msgs
);
2739 // We should have gotten one RequestComplete message.
2740 ASSERT_EQ(1U, msgs
[0].size());
2741 EXPECT_EQ(ResourceMsg_RequestComplete::ID
, msgs
[0][0].type());
2743 // The RequestComplete message should have the error code of
2744 // ERR_UNKNOWN_URL_SCHEME.
2745 CheckRequestCompleteErrorCode(msgs
[0][0], net::ERR_UNKNOWN_URL_SCHEME
);
2748 TEST_F(ResourceDispatcherHostTest
, DataReceivedACKs
) {
2749 EXPECT_EQ(0, host_
.pending_requests());
2751 SendDataReceivedACKs(true);
2753 HandleScheme("big-job");
2754 MakeTestRequest(0, 1, GURL("big-job:0123456789,1000000"));
2756 base::RunLoop().RunUntilIdle();
2758 // Sort all the messages we saw by request.
2759 ResourceIPCAccumulator::ClassifiedMessages msgs
;
2760 accum_
.GetClassifiedMessages(&msgs
);
2762 size_t size
= msgs
[0].size();
2764 EXPECT_EQ(ResourceMsg_ReceivedResponse::ID
, msgs
[0][0].type());
2765 EXPECT_EQ(ResourceMsg_SetDataBuffer::ID
, msgs
[0][1].type());
2766 for (size_t i
= 2; i
< size
- 1; ++i
)
2767 EXPECT_EQ(ResourceMsg_DataReceived::ID
, msgs
[0][i
].type());
2768 EXPECT_EQ(ResourceMsg_RequestComplete::ID
, msgs
[0][size
- 1].type());
2771 // Request a very large detachable resource and cancel part way. Some of the
2772 // data should have been sent to the renderer, but not all.
2773 TEST_F(ResourceDispatcherHostTest
, DataSentBeforeDetach
) {
2774 EXPECT_EQ(0, host_
.pending_requests());
2776 int render_view_id
= 0;
2779 std::string
raw_headers("HTTP\n"
2780 "Content-type: image/jpeg\n\n");
2781 std::string
response_data("01234567890123456789\x01foobar");
2783 // Create a response larger than kMaxAllocationSize (currently 32K). Note
2784 // that if this increase beyond 512K we'll need to make the response longer.
2785 const int kAllocSize
= 1024*512;
2786 response_data
.resize(kAllocSize
, ' ');
2788 SetResponse(raw_headers
, response_data
);
2789 job_factory_
->SetDelayedCompleteJobGeneration(true);
2790 HandleScheme("http");
2792 MakeTestRequestWithResourceType(filter_
.get(), render_view_id
, request_id
,
2793 GURL("http://example.com/blah"),
2794 RESOURCE_TYPE_PREFETCH
);
2796 // Get a bit of data before cancelling.
2797 EXPECT_TRUE(net::URLRequestTestJob::ProcessOnePendingMessage());
2799 // Simulate a cancellation coming from the renderer.
2800 ResourceHostMsg_CancelRequest
msg(request_id
);
2801 host_
.OnMessageReceived(msg
, filter_
.get());
2803 EXPECT_EQ(1, host_
.pending_requests());
2805 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2807 // Sort all the messages we saw by request.
2808 ResourceIPCAccumulator::ClassifiedMessages msgs
;
2809 accum_
.GetClassifiedMessages(&msgs
);
2811 EXPECT_EQ(4U, msgs
[0].size());
2813 // Figure out how many bytes were received by the renderer.
2817 ExtractDataOffsetAndLength(msgs
[0][2], &data_offset
, &data_length
));
2818 EXPECT_LT(0, data_length
);
2819 EXPECT_GT(kAllocSize
, data_length
);
2821 // Verify the data that was received before cancellation. The request should
2822 // have appeared to cancel, however.
2823 CheckSuccessfulRequestWithErrorCode(
2825 std::string(response_data
.begin(), response_data
.begin() + data_length
),
2829 TEST_F(ResourceDispatcherHostTest
, DelayedDataReceivedACKs
) {
2830 EXPECT_EQ(0, host_
.pending_requests());
2832 HandleScheme("big-job");
2833 MakeTestRequest(0, 1, GURL("big-job:0123456789,1000000"));
2835 base::RunLoop().RunUntilIdle();
2837 // Sort all the messages we saw by request.
2838 ResourceIPCAccumulator::ClassifiedMessages msgs
;
2839 accum_
.GetClassifiedMessages(&msgs
);
2841 // We expect 1x ReceivedResponse, 1x SetDataBuffer, Nx ReceivedData messages.
2842 EXPECT_EQ(ResourceMsg_ReceivedResponse::ID
, msgs
[0][0].type());
2843 EXPECT_EQ(ResourceMsg_SetDataBuffer::ID
, msgs
[0][1].type());
2844 for (size_t i
= 2; i
< msgs
[0].size(); ++i
)
2845 EXPECT_EQ(ResourceMsg_DataReceived::ID
, msgs
[0][i
].type());
2847 // NOTE: If we fail the above checks then it means that we probably didn't
2848 // load a big enough response to trigger the delay mechanism we are trying to
2851 msgs
[0].erase(msgs
[0].begin());
2852 msgs
[0].erase(msgs
[0].begin());
2854 // ACK all DataReceived messages until we find a RequestComplete message.
2855 bool complete
= false;
2857 for (size_t i
= 0; i
< msgs
[0].size(); ++i
) {
2858 if (msgs
[0][i
].type() == ResourceMsg_RequestComplete::ID
) {
2863 EXPECT_EQ(ResourceMsg_DataReceived::ID
, msgs
[0][i
].type());
2865 ResourceHostMsg_DataReceived_ACK
msg(1);
2866 host_
.OnMessageReceived(msg
, filter_
.get());
2869 base::MessageLoop::current()->RunUntilIdle();
2872 accum_
.GetClassifiedMessages(&msgs
);
2876 // Flakyness of this test might indicate memory corruption issues with
2877 // for example the ResourceBuffer of AsyncResourceHandler.
2878 TEST_F(ResourceDispatcherHostTest
, DataReceivedUnexpectedACKs
) {
2879 EXPECT_EQ(0, host_
.pending_requests());
2881 HandleScheme("big-job");
2882 MakeTestRequest(0, 1, GURL("big-job:0123456789,1000000"));
2884 base::RunLoop().RunUntilIdle();
2886 // Sort all the messages we saw by request.
2887 ResourceIPCAccumulator::ClassifiedMessages msgs
;
2888 accum_
.GetClassifiedMessages(&msgs
);
2890 // We expect 1x ReceivedResponse, 1x SetDataBuffer, Nx ReceivedData messages.
2891 EXPECT_EQ(ResourceMsg_ReceivedResponse::ID
, msgs
[0][0].type());
2892 EXPECT_EQ(ResourceMsg_SetDataBuffer::ID
, msgs
[0][1].type());
2893 for (size_t i
= 2; i
< msgs
[0].size(); ++i
)
2894 EXPECT_EQ(ResourceMsg_DataReceived::ID
, msgs
[0][i
].type());
2896 // NOTE: If we fail the above checks then it means that we probably didn't
2897 // load a big enough response to trigger the delay mechanism.
2899 // Send some unexpected ACKs.
2900 for (size_t i
= 0; i
< 128; ++i
) {
2901 ResourceHostMsg_DataReceived_ACK
msg(1);
2902 host_
.OnMessageReceived(msg
, filter_
.get());
2905 msgs
[0].erase(msgs
[0].begin());
2906 msgs
[0].erase(msgs
[0].begin());
2908 // ACK all DataReceived messages until we find a RequestComplete message.
2909 bool complete
= false;
2911 for (size_t i
= 0; i
< msgs
[0].size(); ++i
) {
2912 if (msgs
[0][i
].type() == ResourceMsg_RequestComplete::ID
) {
2917 EXPECT_EQ(ResourceMsg_DataReceived::ID
, msgs
[0][i
].type());
2919 ResourceHostMsg_DataReceived_ACK
msg(1);
2920 host_
.OnMessageReceived(msg
, filter_
.get());
2923 base::MessageLoop::current()->RunUntilIdle();
2926 accum_
.GetClassifiedMessages(&msgs
);
2930 // Tests the dispatcher host's temporary file management.
2931 TEST_F(ResourceDispatcherHostTest
, RegisterDownloadedTempFile
) {
2932 const int kRequestID
= 1;
2934 // Create a temporary file.
2935 base::FilePath file_path
;
2936 ASSERT_TRUE(base::CreateTemporaryFile(&file_path
));
2937 scoped_refptr
<ShareableFileReference
> deletable_file
=
2938 ShareableFileReference::GetOrCreate(
2940 ShareableFileReference::DELETE_ON_FINAL_RELEASE
,
2941 BrowserThread::GetMessageLoopProxyForThread(
2942 BrowserThread::FILE).get());
2945 EXPECT_FALSE(ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
2946 filter_
->child_id(), file_path
));
2948 // Register it for a resource request.
2949 host_
.RegisterDownloadedTempFile(filter_
->child_id(), kRequestID
, file_path
);
2951 // Should be readable now.
2952 EXPECT_TRUE(ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
2953 filter_
->child_id(), file_path
));
2955 // The child releases from the request.
2956 ResourceHostMsg_ReleaseDownloadedFile
release_msg(kRequestID
);
2957 host_
.OnMessageReceived(release_msg
, filter_
.get());
2959 // Still readable because there is another reference to the file. (The child
2960 // may take additional blob references.)
2961 EXPECT_TRUE(ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
2962 filter_
->child_id(), file_path
));
2964 // Release extra references and wait for the file to be deleted. (This relies
2965 // on the delete happening on the FILE thread which is mapped to main thread
2967 deletable_file
= NULL
;
2968 base::RunLoop().RunUntilIdle();
2970 // The file is no longer readable to the child and has been deleted.
2971 EXPECT_FALSE(ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
2972 filter_
->child_id(), file_path
));
2973 EXPECT_FALSE(base::PathExists(file_path
));
2976 // Tests that temporary files held on behalf of child processes are released
2977 // when the child process dies.
2978 TEST_F(ResourceDispatcherHostTest
, ReleaseTemporiesOnProcessExit
) {
2979 const int kRequestID
= 1;
2981 // Create a temporary file.
2982 base::FilePath file_path
;
2983 ASSERT_TRUE(base::CreateTemporaryFile(&file_path
));
2984 scoped_refptr
<ShareableFileReference
> deletable_file
=
2985 ShareableFileReference::GetOrCreate(
2987 ShareableFileReference::DELETE_ON_FINAL_RELEASE
,
2988 BrowserThread::GetMessageLoopProxyForThread(
2989 BrowserThread::FILE).get());
2991 // Register it for a resource request.
2992 host_
.RegisterDownloadedTempFile(filter_
->child_id(), kRequestID
, file_path
);
2993 deletable_file
= NULL
;
2995 // Should be readable now.
2996 EXPECT_TRUE(ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
2997 filter_
->child_id(), file_path
));
2999 // Let the process die.
3000 filter_
->OnChannelClosing();
3001 base::RunLoop().RunUntilIdle();
3003 // The file is no longer readable to the child and has been deleted.
3004 EXPECT_FALSE(ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
3005 filter_
->child_id(), file_path
));
3006 EXPECT_FALSE(base::PathExists(file_path
));
3009 TEST_F(ResourceDispatcherHostTest
, DownloadToFile
) {
3010 // Make a request which downloads to file.
3011 ResourceHostMsg_Request request
= CreateResourceRequest(
3012 "GET", RESOURCE_TYPE_SUB_RESOURCE
, net::URLRequestTestJob::test_url_1());
3013 request
.download_to_file
= true;
3014 ResourceHostMsg_RequestResource
request_msg(0, 1, request
);
3015 host_
.OnMessageReceived(request_msg
, filter_
.get());
3017 // Running the message loop until idle does not work because
3018 // RedirectToFileResourceHandler posts things to base::WorkerPool. Instead,
3019 // wait for the ResourceMsg_RequestComplete to go out. Then run the event loop
3020 // until idle so the loader is gone.
3021 WaitForRequestComplete();
3022 base::RunLoop().RunUntilIdle();
3023 EXPECT_EQ(0, host_
.pending_requests());
3025 ResourceIPCAccumulator::ClassifiedMessages msgs
;
3026 accum_
.GetClassifiedMessages(&msgs
);
3028 ASSERT_EQ(1U, msgs
.size());
3029 const std::vector
<IPC::Message
>& messages
= msgs
[0];
3031 // The request should contain the following messages:
3032 // ReceivedResponse (indicates headers received and filename)
3033 // DataDownloaded* (bytes downloaded and total length)
3034 // RequestComplete (request is done)
3037 ResourceResponseHead response_head
;
3038 GetResponseHead(messages
, &response_head
);
3039 ASSERT_FALSE(response_head
.download_file_path
.empty());
3042 size_t total_len
= 0;
3043 for (size_t i
= 1; i
< messages
.size() - 1; i
++) {
3044 ASSERT_EQ(ResourceMsg_DataDownloaded::ID
, messages
[i
].type());
3045 base::PickleIterator
iter(messages
[i
]);
3046 int request_id
, data_len
;
3047 ASSERT_TRUE(IPC::ReadParam(&messages
[i
], &iter
, &request_id
));
3048 ASSERT_TRUE(IPC::ReadParam(&messages
[i
], &iter
, &data_len
));
3049 total_len
+= data_len
;
3051 EXPECT_EQ(net::URLRequestTestJob::test_data_1().size(), total_len
);
3054 CheckRequestCompleteErrorCode(messages
.back(), net::OK
);
3056 // Verify that the data ended up in the temporary file.
3057 std::string contents
;
3058 ASSERT_TRUE(base::ReadFileToString(response_head
.download_file_path
,
3060 EXPECT_EQ(net::URLRequestTestJob::test_data_1(), contents
);
3062 // The file should be readable by the child.
3063 EXPECT_TRUE(ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
3064 filter_
->child_id(), response_head
.download_file_path
));
3066 // When the renderer releases the file, it should be deleted. Again,
3067 // RunUntilIdle doesn't work because base::WorkerPool is involved.
3068 ShareableFileReleaseWaiter
waiter(response_head
.download_file_path
);
3069 ResourceHostMsg_ReleaseDownloadedFile
release_msg(1);
3070 host_
.OnMessageReceived(release_msg
, filter_
.get());
3072 // The release callback runs before the delete is scheduled, so pump the
3073 // message loop for the delete itself. (This relies on the delete happening on
3074 // the FILE thread which is mapped to main thread in this test.)
3075 base::RunLoop().RunUntilIdle();
3077 EXPECT_FALSE(base::PathExists(response_head
.download_file_path
));
3078 EXPECT_FALSE(ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
3079 filter_
->child_id(), response_head
.download_file_path
));
3082 // Tests GetLoadInfoForAllRoutes when there are no pending requests.
3083 TEST_F(ResourceDispatcherHostTest
, LoadInfoNoRequests
) {
3084 scoped_ptr
<LoadInfoMap
> load_info_map
= RunLoadInfoTest(nullptr, 0);
3085 EXPECT_EQ(0u, load_info_map
->size());
3088 // Tests GetLoadInfoForAllRoutes when there are 3 requests from the same
3089 // RenderView. The second one is farthest along.
3090 TEST_F(ResourceDispatcherHostTest
, LoadInfo
) {
3091 const GlobalRoutingID
kId(filter_
->child_id(), 0);
3092 LoadInfoTestRequestInfo request_info
[] = {
3095 net::LOAD_STATE_SENDING_REQUEST
,
3096 net::UploadProgress(0, 0)},
3099 net::LOAD_STATE_READING_RESPONSE
,
3100 net::UploadProgress(0, 0)},
3103 net::LOAD_STATE_SENDING_REQUEST
,
3104 net::UploadProgress(0, 0)},
3106 scoped_ptr
<LoadInfoMap
> load_info_map
=
3107 RunLoadInfoTest(request_info
, arraysize(request_info
));
3108 ASSERT_EQ(1u, load_info_map
->size());
3109 ASSERT_TRUE(load_info_map
->find(kId
) != load_info_map
->end());
3110 EXPECT_EQ(GURL("test://2/"), (*load_info_map
)[kId
].url
);
3111 EXPECT_EQ(net::LOAD_STATE_READING_RESPONSE
,
3112 (*load_info_map
)[kId
].load_state
.state
);
3113 EXPECT_EQ(0u, (*load_info_map
)[kId
].upload_position
);
3114 EXPECT_EQ(0u, (*load_info_map
)[kId
].upload_size
);
3117 // Tests GetLoadInfoForAllRoutes when there are 2 requests with the same
3118 // priority. The first one (Which will have the lowest ID) should be returned.
3119 TEST_F(ResourceDispatcherHostTest
, LoadInfoSamePriority
) {
3120 const GlobalRoutingID
kId(filter_
->child_id(), 0);
3121 LoadInfoTestRequestInfo request_info
[] = {
3124 net::LOAD_STATE_IDLE
,
3125 net::UploadProgress(0, 0)},
3128 net::LOAD_STATE_IDLE
,
3129 net::UploadProgress(0, 0)},
3131 scoped_ptr
<LoadInfoMap
> load_info_map
=
3132 RunLoadInfoTest(request_info
, arraysize(request_info
));
3133 ASSERT_EQ(1u, load_info_map
->size());
3134 ASSERT_TRUE(load_info_map
->find(kId
) != load_info_map
->end());
3135 EXPECT_EQ(GURL("test://1/"), (*load_info_map
)[kId
].url
);
3136 EXPECT_EQ(net::LOAD_STATE_IDLE
, (*load_info_map
)[kId
].load_state
.state
);
3137 EXPECT_EQ(0u, (*load_info_map
)[kId
].upload_position
);
3138 EXPECT_EQ(0u, (*load_info_map
)[kId
].upload_size
);
3141 // Tests GetLoadInfoForAllRoutes when a request is uploading a body.
3142 TEST_F(ResourceDispatcherHostTest
, LoadInfoUploadProgress
) {
3143 const GlobalRoutingID
kId(filter_
->child_id(), 0);
3144 LoadInfoTestRequestInfo request_info
[] = {
3147 net::LOAD_STATE_READING_RESPONSE
,
3148 net::UploadProgress(0, 0)},
3151 net::LOAD_STATE_READING_RESPONSE
,
3152 net::UploadProgress(1000, 1000)},
3155 net::LOAD_STATE_SENDING_REQUEST
,
3156 net::UploadProgress(50, 100)},
3159 net::LOAD_STATE_READING_RESPONSE
,
3160 net::UploadProgress(1000, 1000)},
3163 net::LOAD_STATE_READING_RESPONSE
,
3164 net::UploadProgress(0, 0)},
3166 scoped_ptr
<LoadInfoMap
> load_info_map
=
3167 RunLoadInfoTest(request_info
, arraysize(request_info
));
3168 ASSERT_EQ(1u, load_info_map
->size());
3169 ASSERT_TRUE(load_info_map
->find(kId
) != load_info_map
->end());
3170 EXPECT_EQ(GURL("test://2/"), (*load_info_map
)[kId
].url
);
3171 EXPECT_EQ(net::LOAD_STATE_SENDING_REQUEST
,
3172 (*load_info_map
)[kId
].load_state
.state
);
3173 EXPECT_EQ(50u, (*load_info_map
)[kId
].upload_position
);
3174 EXPECT_EQ(100u, (*load_info_map
)[kId
].upload_size
);
3177 // Tests GetLoadInfoForAllRoutes when there are 4 requests from 2 different
3178 // RenderViews. Also tests the case where the first / last requests are the
3179 // most interesting ones.
3180 TEST_F(ResourceDispatcherHostTest
, LoadInfoTwoRenderViews
) {
3181 const GlobalRoutingID
kId1(filter_
->child_id(), 0);
3182 const GlobalRoutingID
kId2(filter_
->child_id(), 1);
3183 LoadInfoTestRequestInfo request_info
[] = {
3186 net::LOAD_STATE_CONNECTING
,
3187 net::UploadProgress(0, 0)},
3190 net::LOAD_STATE_IDLE
,
3191 net::UploadProgress(0, 0)},
3194 net::LOAD_STATE_IDLE
,
3195 net::UploadProgress(0, 0)},
3198 net::LOAD_STATE_CONNECTING
,
3199 net::UploadProgress(0, 0)},
3201 scoped_ptr
<LoadInfoMap
> load_info_map
=
3202 RunLoadInfoTest(request_info
, arraysize(request_info
));
3203 ASSERT_EQ(2u, load_info_map
->size());
3205 ASSERT_TRUE(load_info_map
->find(kId1
) != load_info_map
->end());
3206 EXPECT_EQ(GURL("test://1/"), (*load_info_map
)[kId1
].url
);
3207 EXPECT_EQ(net::LOAD_STATE_CONNECTING
,
3208 (*load_info_map
)[kId1
].load_state
.state
);
3209 EXPECT_EQ(0u, (*load_info_map
)[kId1
].upload_position
);
3210 EXPECT_EQ(0u, (*load_info_map
)[kId1
].upload_size
);
3212 ASSERT_TRUE(load_info_map
->find(kId2
) != load_info_map
->end());
3213 EXPECT_EQ(GURL("test://4/"), (*load_info_map
)[kId2
].url
);
3214 EXPECT_EQ(net::LOAD_STATE_CONNECTING
,
3215 (*load_info_map
)[kId2
].load_state
.state
);
3216 EXPECT_EQ(0u, (*load_info_map
)[kId2
].upload_position
);
3217 EXPECT_EQ(0u, (*load_info_map
)[kId2
].upload_size
);
3220 net::URLRequestJob
* TestURLRequestJobFactory::MaybeCreateJobWithProtocolHandler(
3221 const std::string
& scheme
,
3222 net::URLRequest
* request
,
3223 net::NetworkDelegate
* network_delegate
) const {
3224 url_request_jobs_created_count_
++;
3225 if (test_fixture_
->wait_for_request_create_loop_
)
3226 test_fixture_
->wait_for_request_create_loop_
->Quit();
3227 if (test_fixture_
->loader_test_request_info_
) {
3228 DCHECK_EQ(test_fixture_
->loader_test_request_info_
->url
, request
->url());
3229 scoped_ptr
<LoadInfoTestRequestInfo
> info
=
3230 test_fixture_
->loader_test_request_info_
.Pass();
3231 return new URLRequestLoadInfoJob(request
, network_delegate
,
3232 info
->load_state
, info
->upload_progress
);
3234 if (test_fixture_
->response_headers_
.empty()) {
3236 return new URLRequestTestDelayedStartJob(request
, network_delegate
);
3237 } else if (delay_complete_
) {
3238 return new URLRequestTestDelayedCompletionJob(request
,
3240 } else if (network_start_notification_
) {
3241 return new URLRequestTestDelayedNetworkJob(request
, network_delegate
);
3242 } else if (scheme
== "big-job") {
3243 return new URLRequestBigJob(request
, network_delegate
);
3245 return new net::URLRequestTestJob(request
, network_delegate
);
3249 return new URLRequestTestDelayedStartJob(
3250 request
, network_delegate
,
3251 test_fixture_
->response_headers_
, test_fixture_
->response_data_
,
3253 } else if (delay_complete_
) {
3254 return new URLRequestTestDelayedCompletionJob(
3255 request
, network_delegate
,
3256 test_fixture_
->response_headers_
, test_fixture_
->response_data_
,
3259 return new net::URLRequestTestJob(
3260 request
, network_delegate
,
3261 test_fixture_
->response_headers_
, test_fixture_
->response_data_
,
3267 net::URLRequestJob
* TestURLRequestJobFactory::MaybeInterceptRedirect(
3268 net::URLRequest
* request
,
3269 net::NetworkDelegate
* network_delegate
,
3270 const GURL
& location
) const {
3274 net::URLRequestJob
* TestURLRequestJobFactory::MaybeInterceptResponse(
3275 net::URLRequest
* request
,
3276 net::NetworkDelegate
* network_delegate
) const {
3280 } // namespace content