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/files/file_path.h"
10 #include "base/files/file_util.h"
11 #include "base/location.h"
12 #include "base/memory/scoped_vector.h"
13 #include "base/memory/shared_memory.h"
14 #include "base/pickle.h"
15 #include "base/run_loop.h"
16 #include "base/single_thread_task_runner.h"
17 #include "base/strings/string_number_conversions.h"
18 #include "base/strings/string_split.h"
19 #include "base/thread_task_runner_handle.h"
20 #include "content/browser/browser_thread_impl.h"
21 #include "content/browser/child_process_security_policy_impl.h"
22 #include "content/browser/loader/cross_site_resource_handler.h"
23 #include "content/browser/loader/detachable_resource_handler.h"
24 #include "content/browser/loader/resource_dispatcher_host_impl.h"
25 #include "content/browser/loader/resource_loader.h"
26 #include "content/browser/loader/resource_message_filter.h"
27 #include "content/browser/loader/resource_request_info_impl.h"
28 #include "content/common/appcache_interfaces.h"
29 #include "content/common/child_process_host_impl.h"
30 #include "content/common/resource_messages.h"
31 #include "content/common/view_messages.h"
32 #include "content/public/browser/global_request_id.h"
33 #include "content/public/browser/resource_context.h"
34 #include "content/public/browser/resource_dispatcher_host_delegate.h"
35 #include "content/public/browser/resource_request_info.h"
36 #include "content/public/browser/resource_throttle.h"
37 #include "content/public/common/process_type.h"
38 #include "content/public/common/resource_response.h"
39 #include "content/public/test/test_browser_context.h"
40 #include "content/public/test/test_browser_thread_bundle.h"
41 #include "content/test/test_content_browser_client.h"
42 #include "net/base/elements_upload_data_stream.h"
43 #include "net/base/net_errors.h"
44 #include "net/base/request_priority.h"
45 #include "net/base/upload_bytes_element_reader.h"
46 #include "net/http/http_util.h"
47 #include "net/url_request/url_request.h"
48 #include "net/url_request/url_request_context.h"
49 #include "net/url_request/url_request_job.h"
50 #include "net/url_request/url_request_job_factory.h"
51 #include "net/url_request/url_request_simple_job.h"
52 #include "net/url_request/url_request_test_job.h"
53 #include "net/url_request/url_request_test_util.h"
54 #include "storage/browser/blob/shareable_file_reference.h"
55 #include "testing/gtest/include/gtest/gtest.h"
57 // TODO(eroman): Write unit tests for SafeBrowsing that exercise
58 // SafeBrowsingResourceHandler.
60 using storage::ShareableFileReference
;
66 // Returns the resource response header structure for this request.
67 void GetResponseHead(const std::vector
<IPC::Message
>& messages
,
68 ResourceResponseHead
* response_head
) {
69 ASSERT_GE(messages
.size(), 2U);
71 // The first messages should be received response.
72 ASSERT_EQ(ResourceMsg_ReceivedResponse::ID
, messages
[0].type());
74 base::PickleIterator
iter(messages
[0]);
76 ASSERT_TRUE(IPC::ReadParam(&messages
[0], &iter
, &request_id
));
77 ASSERT_TRUE(IPC::ReadParam(&messages
[0], &iter
, response_head
));
80 void GenerateIPCMessage(
81 scoped_refptr
<ResourceMessageFilter
> filter
,
82 scoped_ptr
<IPC::Message
> message
) {
83 ResourceDispatcherHostImpl::Get()->OnMessageReceived(
84 *message
, filter
.get());
87 // On Windows, ResourceMsg_SetDataBuffer supplies a HANDLE which is not
88 // automatically released.
90 // See ResourceDispatcher::ReleaseResourcesInDataMessage.
92 // TODO(davidben): It would be nice if the behavior for base::SharedMemoryHandle
93 // were more like it is in POSIX where the received fds are tracked in a
94 // ref-counted core that closes them if not extracted.
95 void ReleaseHandlesInMessage(const IPC::Message
& message
) {
96 if (message
.type() == ResourceMsg_SetDataBuffer::ID
) {
97 base::PickleIterator
iter(message
);
99 CHECK(iter
.ReadInt(&request_id
));
100 base::SharedMemoryHandle shm_handle
;
101 if (IPC::ParamTraits
<base::SharedMemoryHandle
>::Read(&message
,
104 if (base::SharedMemory::IsHandleValid(shm_handle
))
105 base::SharedMemory::CloseHandle(shm_handle
);
112 static int RequestIDForMessage(const IPC::Message
& msg
) {
114 switch (msg
.type()) {
115 case ResourceMsg_UploadProgress::ID
:
116 case ResourceMsg_ReceivedResponse::ID
:
117 case ResourceMsg_ReceivedRedirect::ID
:
118 case ResourceMsg_SetDataBuffer::ID
:
119 case ResourceMsg_DataReceived::ID
:
120 case ResourceMsg_DataDownloaded::ID
:
121 case ResourceMsg_RequestComplete::ID
: {
122 bool result
= base::PickleIterator(msg
).ReadInt(&request_id
);
130 static ResourceHostMsg_Request
CreateResourceRequest(const char* method
,
133 ResourceHostMsg_Request request
;
134 request
.method
= std::string(method
);
136 request
.first_party_for_cookies
= url
; // bypass third-party cookie blocking
137 request
.referrer_policy
= blink::WebReferrerPolicyDefault
;
138 request
.load_flags
= 0;
139 request
.origin_pid
= 0;
140 request
.resource_type
= type
;
141 request
.request_context
= 0;
142 request
.appcache_host_id
= kAppCacheNoHostId
;
143 request
.download_to_file
= false;
144 request
.should_reset_appcache
= false;
145 request
.is_main_frame
= true;
146 request
.parent_is_main_frame
= false;
147 request
.parent_render_frame_id
= -1;
148 request
.transition_type
= ui::PAGE_TRANSITION_LINK
;
149 request
.allow_download
= true;
153 // Spin up the message loop to kick off the request.
154 static void KickOffRequest() {
155 base::MessageLoop::current()->RunUntilIdle();
158 // We may want to move this to a shared space if it is useful for something else
159 class ResourceIPCAccumulator
{
161 ~ResourceIPCAccumulator() {
162 for (size_t i
= 0; i
< messages_
.size(); i
++) {
163 ReleaseHandlesInMessage(messages_
[i
]);
167 // On Windows, takes ownership of SharedMemoryHandles in |msg|.
168 void AddMessage(const IPC::Message
& msg
) {
169 messages_
.push_back(msg
);
172 // This groups the messages by their request ID. The groups will be in order
173 // that the first message for each request ID was received, and the messages
174 // within the groups will be in the order that they appeared.
175 // Note that this clears messages_. The caller takes ownership of any
176 // SharedMemoryHandles in messages placed into |msgs|.
177 typedef std::vector
< std::vector
<IPC::Message
> > ClassifiedMessages
;
178 void GetClassifiedMessages(ClassifiedMessages
* msgs
);
181 std::vector
<IPC::Message
> messages_
;
184 // This is very inefficient as a result of repeatedly extracting the ID, use
186 void ResourceIPCAccumulator::GetClassifiedMessages(ClassifiedMessages
* msgs
) {
187 while (!messages_
.empty()) {
188 // Ignore unknown message types as it is valid for code to generated other
189 // IPCs as side-effects that we are not testing here.
190 int cur_id
= RequestIDForMessage(messages_
[0]);
192 std::vector
<IPC::Message
> cur_requests
;
193 cur_requests
.push_back(messages_
[0]);
194 // find all other messages with this ID
195 for (int i
= 1; i
< static_cast<int>(messages_
.size()); i
++) {
196 int id
= RequestIDForMessage(messages_
[i
]);
198 cur_requests
.push_back(messages_
[i
]);
199 messages_
.erase(messages_
.begin() + i
);
203 msgs
->push_back(cur_requests
);
205 messages_
.erase(messages_
.begin());
209 // This is used to emulate different sub-processes, since this filter will
210 // have a different ID than the original.
211 class TestFilter
: public ResourceMessageFilter
{
213 explicit TestFilter(ResourceContext
* resource_context
)
214 : ResourceMessageFilter(
215 ChildProcessHostImpl::GenerateChildProcessUniqueId(),
216 PROCESS_TYPE_RENDERER
, NULL
, NULL
, NULL
, NULL
, NULL
,
217 base::Bind(&TestFilter::GetContexts
, base::Unretained(this))),
218 resource_context_(resource_context
),
220 received_after_canceled_(0) {
221 ChildProcessSecurityPolicyImpl::GetInstance()->Add(child_id());
222 set_peer_process_for_testing(base::Process::Current());
225 void set_canceled(bool canceled
) { canceled_
= canceled
; }
226 int received_after_canceled() const { return received_after_canceled_
; }
228 // ResourceMessageFilter override
229 bool Send(IPC::Message
* msg
) override
{
230 // No messages should be received when the process has been canceled.
232 received_after_canceled_
++;
233 ReleaseHandlesInMessage(*msg
);
238 ResourceContext
* resource_context() { return resource_context_
; }
241 ~TestFilter() override
{}
244 void GetContexts(const ResourceHostMsg_Request
& request
,
245 ResourceContext
** resource_context
,
246 net::URLRequestContext
** request_context
) {
247 *resource_context
= resource_context_
;
248 *request_context
= resource_context_
->GetRequestContext();
251 ResourceContext
* resource_context_
;
253 int received_after_canceled_
;
255 DISALLOW_COPY_AND_ASSIGN(TestFilter
);
259 // This class forwards the incoming messages to the ResourceDispatcherHostTest.
260 // For the test, we want all the incoming messages to go to the same place,
261 // which is why this forwards.
262 class ForwardingFilter
: public TestFilter
{
264 explicit ForwardingFilter(IPC::Sender
* dest
,
265 ResourceContext
* resource_context
)
266 : TestFilter(resource_context
),
270 // TestFilter override
271 bool Send(IPC::Message
* msg
) override
{ return dest_
->Send(msg
); }
274 ~ForwardingFilter() override
{}
278 DISALLOW_COPY_AND_ASSIGN(ForwardingFilter
);
281 // This class is a variation on URLRequestTestJob that will call
282 // URLRequest::WillStartUsingNetwork before starting.
283 class URLRequestTestDelayedNetworkJob
: public net::URLRequestTestJob
{
285 URLRequestTestDelayedNetworkJob(net::URLRequest
* request
,
286 net::NetworkDelegate
* network_delegate
)
287 : net::URLRequestTestJob(request
, network_delegate
) {}
289 // Only start if not deferred for network start.
290 void Start() override
{
292 NotifyBeforeNetworkStart(&defer
);
295 net::URLRequestTestJob::Start();
298 void ResumeNetworkStart() override
{ net::URLRequestTestJob::StartAsync(); }
301 ~URLRequestTestDelayedNetworkJob() override
{}
303 DISALLOW_COPY_AND_ASSIGN(URLRequestTestDelayedNetworkJob
);
306 // This class is a variation on URLRequestTestJob in that it does
307 // not complete start upon entry, only when specifically told to.
308 class URLRequestTestDelayedStartJob
: public net::URLRequestTestJob
{
310 URLRequestTestDelayedStartJob(net::URLRequest
* request
,
311 net::NetworkDelegate
* network_delegate
)
312 : net::URLRequestTestJob(request
, network_delegate
) {
315 URLRequestTestDelayedStartJob(net::URLRequest
* request
,
316 net::NetworkDelegate
* network_delegate
,
318 : net::URLRequestTestJob(request
, network_delegate
, auto_advance
) {
321 URLRequestTestDelayedStartJob(net::URLRequest
* request
,
322 net::NetworkDelegate
* network_delegate
,
323 const std::string
& response_headers
,
324 const std::string
& response_data
,
326 : net::URLRequestTestJob(request
,
334 // Do nothing until you're told to.
335 void Start() override
{}
337 // Finish starting a URL request whose job is an instance of
338 // URLRequestTestDelayedStartJob. It is illegal to call this routine
339 // with a URLRequest that does not use URLRequestTestDelayedStartJob.
340 static void CompleteStart(net::URLRequest
* request
) {
341 for (URLRequestTestDelayedStartJob
* job
= list_head_
;
344 if (job
->request() == request
) {
345 job
->net::URLRequestTestJob::Start();
352 static bool DelayedStartQueueEmpty() {
356 static void ClearQueue() {
359 << "Unreleased entries on URLRequestTestDelayedStartJob delay queue"
360 << "; may result in leaks.";
366 ~URLRequestTestDelayedStartJob() override
{
367 for (URLRequestTestDelayedStartJob
** job
= &list_head_
; *job
;
368 job
= &(*job
)->next_
) {
370 *job
= (*job
)->next_
;
383 static URLRequestTestDelayedStartJob
* list_head_
;
384 URLRequestTestDelayedStartJob
* next_
;
387 URLRequestTestDelayedStartJob
*
388 URLRequestTestDelayedStartJob::list_head_
= NULL
;
390 // This class is a variation on URLRequestTestJob in that it
391 // returns IO_pending errors before every read, not just the first one.
392 class URLRequestTestDelayedCompletionJob
: public net::URLRequestTestJob
{
394 URLRequestTestDelayedCompletionJob(net::URLRequest
* request
,
395 net::NetworkDelegate
* network_delegate
)
396 : net::URLRequestTestJob(request
, network_delegate
) {}
397 URLRequestTestDelayedCompletionJob(net::URLRequest
* request
,
398 net::NetworkDelegate
* network_delegate
,
400 : net::URLRequestTestJob(request
, network_delegate
, auto_advance
) {}
401 URLRequestTestDelayedCompletionJob(net::URLRequest
* request
,
402 net::NetworkDelegate
* network_delegate
,
403 const std::string
& response_headers
,
404 const std::string
& response_data
,
406 : net::URLRequestTestJob(request
,
413 ~URLRequestTestDelayedCompletionJob() override
{}
416 bool NextReadAsync() override
{ return true; }
419 class URLRequestBigJob
: public net::URLRequestSimpleJob
{
421 URLRequestBigJob(net::URLRequest
* request
,
422 net::NetworkDelegate
* network_delegate
)
423 : net::URLRequestSimpleJob(request
, network_delegate
) {
426 // URLRequestSimpleJob implementation:
427 int GetData(std::string
* mime_type
,
428 std::string
* charset
,
430 const net::CompletionCallback
& callback
) const override
{
431 *mime_type
= "text/plain";
436 if (!ParseURL(request_
->url(), &text
, &count
))
437 return net::ERR_INVALID_URL
;
439 data
->reserve(text
.size() * count
);
440 for (int i
= 0; i
< count
; ++i
)
446 base::TaskRunner
* GetTaskRunner() const override
{
447 return base::ThreadTaskRunnerHandle::Get().get();
451 ~URLRequestBigJob() override
{}
453 // big-job:substring,N
454 static bool ParseURL(const GURL
& url
, std::string
* text
, int* count
) {
455 std::vector
<std::string
> parts
;
456 base::SplitString(url
.path(), ',', &parts
);
458 if (parts
.size() != 2)
462 return base::StringToInt(parts
[1], count
);
466 // URLRequestJob used to test GetLoadInfoForAllRoutes. The LoadState and
467 // UploadProgress values are set for the jobs at the time of creation, and
468 // the jobs will never actually do anything.
469 class URLRequestLoadInfoJob
: public net::URLRequestJob
{
471 URLRequestLoadInfoJob(net::URLRequest
* request
,
472 net::NetworkDelegate
* network_delegate
,
473 const net::LoadState
& load_state
,
474 const net::UploadProgress
& upload_progress
)
475 : net::URLRequestJob(request
, network_delegate
),
476 load_state_(load_state
),
477 upload_progress_(upload_progress
) {}
479 // net::URLRequestJob implementation:
480 void Start() override
{}
481 net::LoadState
GetLoadState() const override
{ return load_state_
; }
482 net::UploadProgress
GetUploadProgress() const override
{
483 return upload_progress_
;
487 ~URLRequestLoadInfoJob() override
{}
489 // big-job:substring,N
490 static bool ParseURL(const GURL
& url
, std::string
* text
, int* count
) {
491 std::vector
<std::string
> parts
;
492 base::SplitString(url
.path(), ',', &parts
);
494 if (parts
.size() != 2)
498 return base::StringToInt(parts
[1], count
);
501 const net::LoadState load_state_
;
502 const net::UploadProgress upload_progress_
;
505 class ResourceDispatcherHostTest
;
507 class TestURLRequestJobFactory
: public net::URLRequestJobFactory
{
509 explicit TestURLRequestJobFactory(ResourceDispatcherHostTest
* test_fixture
)
510 : test_fixture_(test_fixture
),
512 delay_complete_(false),
513 network_start_notification_(false),
514 url_request_jobs_created_count_(0) {
517 void HandleScheme(const std::string
& scheme
) {
518 supported_schemes_
.insert(scheme
);
521 int url_request_jobs_created_count() const {
522 return url_request_jobs_created_count_
;
525 void SetDelayedStartJobGeneration(bool delay_job_start
) {
526 delay_start_
= delay_job_start
;
529 void SetDelayedCompleteJobGeneration(bool delay_job_complete
) {
530 delay_complete_
= delay_job_complete
;
533 void SetNetworkStartNotificationJobGeneration(bool notification
) {
534 network_start_notification_
= notification
;
537 net::URLRequestJob
* MaybeCreateJobWithProtocolHandler(
538 const std::string
& scheme
,
539 net::URLRequest
* request
,
540 net::NetworkDelegate
* network_delegate
) const override
;
542 net::URLRequestJob
* MaybeInterceptRedirect(
543 net::URLRequest
* request
,
544 net::NetworkDelegate
* network_delegate
,
545 const GURL
& location
) const override
;
547 net::URLRequestJob
* MaybeInterceptResponse(
548 net::URLRequest
* request
,
549 net::NetworkDelegate
* network_delegate
) const override
;
551 bool IsHandledProtocol(const std::string
& scheme
) const override
{
552 return supported_schemes_
.count(scheme
) > 0;
555 bool IsHandledURL(const GURL
& url
) const override
{
556 return supported_schemes_
.count(url
.scheme()) > 0;
559 bool IsSafeRedirectTarget(const GURL
& location
) const override
{
564 ResourceDispatcherHostTest
* test_fixture_
;
566 bool delay_complete_
;
567 bool network_start_notification_
;
568 mutable int url_request_jobs_created_count_
;
569 std::set
<std::string
> supported_schemes_
;
571 DISALLOW_COPY_AND_ASSIGN(TestURLRequestJobFactory
);
574 // Associated with an URLRequest to determine if the URLRequest gets deleted.
575 class TestUserData
: public base::SupportsUserData::Data
{
577 explicit TestUserData(bool* was_deleted
)
578 : was_deleted_(was_deleted
) {
581 ~TestUserData() override
{ *was_deleted_
= true; }
587 class TransfersAllNavigationsContentBrowserClient
588 : public TestContentBrowserClient
{
590 bool ShouldSwapProcessesForRedirect(ResourceContext
* resource_context
,
591 const GURL
& current_url
,
592 const GURL
& new_url
) override
{
597 enum GenericResourceThrottleFlags
{
599 DEFER_STARTING_REQUEST
= 1 << 0,
600 DEFER_PROCESSING_RESPONSE
= 1 << 1,
601 CANCEL_BEFORE_START
= 1 << 2,
602 DEFER_NETWORK_START
= 1 << 3
605 // Throttle that tracks the current throttle blocking a request. Only one
606 // can throttle any request at a time.
607 class GenericResourceThrottle
: public ResourceThrottle
{
609 // The value is used to indicate that the throttle should not provide
610 // a error code when cancelling a request. net::OK is used, because this
611 // is not an error code.
612 static const int USE_DEFAULT_CANCEL_ERROR_CODE
= net::OK
;
614 GenericResourceThrottle(int flags
, int code
)
616 error_code_for_cancellation_(code
) {
619 ~GenericResourceThrottle() override
{
620 if (active_throttle_
== this)
621 active_throttle_
= NULL
;
624 // ResourceThrottle implementation:
625 void WillStartRequest(bool* defer
) override
{
626 ASSERT_EQ(NULL
, active_throttle_
);
627 if (flags_
& DEFER_STARTING_REQUEST
) {
628 active_throttle_
= this;
632 if (flags_
& CANCEL_BEFORE_START
) {
633 if (error_code_for_cancellation_
== USE_DEFAULT_CANCEL_ERROR_CODE
) {
634 controller()->Cancel();
636 controller()->CancelWithError(error_code_for_cancellation_
);
641 void WillProcessResponse(bool* defer
) override
{
642 ASSERT_EQ(NULL
, active_throttle_
);
643 if (flags_
& DEFER_PROCESSING_RESPONSE
) {
644 active_throttle_
= this;
649 void WillStartUsingNetwork(bool* defer
) override
{
650 ASSERT_EQ(NULL
, active_throttle_
);
652 if (flags_
& DEFER_NETWORK_START
) {
653 active_throttle_
= this;
658 const char* GetNameForLogging() const override
{
659 return "GenericResourceThrottle";
663 ASSERT_TRUE(this == active_throttle_
);
664 active_throttle_
= NULL
;
665 controller()->Resume();
668 static GenericResourceThrottle
* active_throttle() {
669 return active_throttle_
;
673 int flags_
; // bit-wise union of GenericResourceThrottleFlags.
674 int error_code_for_cancellation_
;
676 // The currently active throttle, if any.
677 static GenericResourceThrottle
* active_throttle_
;
680 GenericResourceThrottle
* GenericResourceThrottle::active_throttle_
= NULL
;
682 class TestResourceDispatcherHostDelegate
683 : public ResourceDispatcherHostDelegate
{
685 TestResourceDispatcherHostDelegate()
686 : create_two_throttles_(false),
688 error_code_for_cancellation_(
689 GenericResourceThrottle::USE_DEFAULT_CANCEL_ERROR_CODE
) {
692 void set_url_request_user_data(base::SupportsUserData::Data
* user_data
) {
693 user_data_
.reset(user_data
);
696 void set_flags(int value
) {
700 void set_error_code_for_cancellation(int code
) {
701 error_code_for_cancellation_
= code
;
704 void set_create_two_throttles(bool create_two_throttles
) {
705 create_two_throttles_
= create_two_throttles
;
708 // ResourceDispatcherHostDelegate implementation:
710 void RequestBeginning(net::URLRequest
* request
,
711 ResourceContext
* resource_context
,
712 AppCacheService
* appcache_service
,
713 ResourceType resource_type
,
714 ScopedVector
<ResourceThrottle
>* throttles
) override
{
716 const void* key
= user_data_
.get();
717 request
->SetUserData(key
, user_data_
.release());
720 if (flags_
!= NONE
) {
721 throttles
->push_back(new GenericResourceThrottle(
722 flags_
, error_code_for_cancellation_
));
723 if (create_two_throttles_
)
724 throttles
->push_back(new GenericResourceThrottle(
725 flags_
, error_code_for_cancellation_
));
730 bool create_two_throttles_
;
732 int error_code_for_cancellation_
;
733 scoped_ptr
<base::SupportsUserData::Data
> user_data_
;
736 // Waits for a ShareableFileReference to be released.
737 class ShareableFileReleaseWaiter
{
739 ShareableFileReleaseWaiter(const base::FilePath
& path
) {
740 scoped_refptr
<ShareableFileReference
> file
=
741 ShareableFileReference::Get(path
);
742 file
->AddFinalReleaseCallback(
743 base::Bind(&ShareableFileReleaseWaiter::Released
,
744 base::Unretained(this)));
752 void Released(const base::FilePath
& path
) {
758 DISALLOW_COPY_AND_ASSIGN(ShareableFileReleaseWaiter
);
761 // Information used to create resource requests that use URLRequestLoadInfoJobs.
762 // The child_id is just that of ResourceDispatcherHostTest::filter_.
763 struct LoadInfoTestRequestInfo
{
766 net::LoadState load_state
;
767 net::UploadProgress upload_progress
;
770 class ResourceDispatcherHostTest
: public testing::Test
,
773 typedef ResourceDispatcherHostImpl::LoadInfo LoadInfo
;
774 typedef ResourceDispatcherHostImpl::LoadInfoMap LoadInfoMap
;
776 ResourceDispatcherHostTest()
777 : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP
),
779 send_data_received_acks_(false) {
780 browser_context_
.reset(new TestBrowserContext());
781 BrowserContext::EnsureResourceContextInitialized(browser_context_
.get());
782 base::RunLoop().RunUntilIdle();
783 filter_
= MakeForwardingFilter();
784 // TODO(cbentzel): Better way to get URLRequestContext?
785 net::URLRequestContext
* request_context
=
786 browser_context_
->GetResourceContext()->GetRequestContext();
787 job_factory_
.reset(new TestURLRequestJobFactory(this));
788 request_context
->set_job_factory(job_factory_
.get());
789 request_context
->set_network_delegate(&network_delegate_
);
792 // IPC::Sender implementation
793 bool Send(IPC::Message
* msg
) override
{
794 accum_
.AddMessage(*msg
);
796 if (send_data_received_acks_
&&
797 msg
->type() == ResourceMsg_DataReceived::ID
) {
798 GenerateDataReceivedACK(*msg
);
801 if (wait_for_request_complete_loop_
&&
802 msg
->type() == ResourceMsg_RequestComplete::ID
) {
803 wait_for_request_complete_loop_
->Quit();
806 // Do not release handles in it yet; the accumulator owns them now.
811 scoped_ptr
<LoadInfoMap
> RunLoadInfoTest(LoadInfoTestRequestInfo
* request_info
,
812 size_t num_requests
) {
813 for (size_t i
= 0; i
< num_requests
; ++i
) {
814 loader_test_request_info_
.reset(
815 new LoadInfoTestRequestInfo(request_info
[i
]));
816 wait_for_request_create_loop_
.reset(new base::RunLoop());
817 MakeTestRequest(request_info
[i
].route_id
, i
+ 1, request_info
[i
].url
);
818 wait_for_request_create_loop_
->Run();
819 wait_for_request_create_loop_
.reset();
821 return ResourceDispatcherHostImpl::Get()->GetLoadInfoForAllRoutes();
825 friend class TestURLRequestJobFactory
;
828 void SetUp() override
{
829 ChildProcessSecurityPolicyImpl::GetInstance()->Add(0);
830 HandleScheme("test");
833 void TearDown() override
{
834 EXPECT_TRUE(URLRequestTestDelayedStartJob::DelayedStartQueueEmpty());
835 URLRequestTestDelayedStartJob::ClearQueue();
837 for (std::set
<int>::iterator it
= child_ids_
.begin();
838 it
!= child_ids_
.end(); ++it
) {
839 host_
.CancelRequestsForProcess(*it
);
844 ChildProcessSecurityPolicyImpl::GetInstance()->Remove(0);
846 // Flush the message loop to make application verifiers happy.
847 if (ResourceDispatcherHostImpl::Get())
848 ResourceDispatcherHostImpl::Get()->CancelRequestsForContext(
849 browser_context_
->GetResourceContext());
851 browser_context_
.reset();
852 base::RunLoop().RunUntilIdle();
855 // Creates a new ForwardingFilter and registers it with |child_ids_| so as not
856 // to leak per-child state on test shutdown.
857 ForwardingFilter
* MakeForwardingFilter() {
858 ForwardingFilter
* filter
=
859 new ForwardingFilter(this, browser_context_
->GetResourceContext());
860 child_ids_
.insert(filter
->child_id());
864 // Creates a request using the current test object as the filter and
865 // SubResource as the resource type.
866 void MakeTestRequest(int render_view_id
,
870 // Generates a request using the given filter and resource type.
871 void MakeTestRequestWithResourceType(ResourceMessageFilter
* filter
,
877 void CancelRequest(int request_id
);
878 void RendererCancelRequest(int request_id
) {
879 ResourceMessageFilter
* old_filter
= SetFilter(filter_
.get());
880 host_
.OnCancelRequest(request_id
);
881 SetFilter(old_filter
);
884 void CompleteStartRequest(int request_id
);
885 void CompleteStartRequest(ResourceMessageFilter
* filter
, int request_id
);
887 net::TestNetworkDelegate
* network_delegate() { return &network_delegate_
; }
889 void EnsureSchemeIsAllowed(const std::string
& scheme
) {
890 ChildProcessSecurityPolicyImpl
* policy
=
891 ChildProcessSecurityPolicyImpl::GetInstance();
892 if (!policy
->IsWebSafeScheme(scheme
))
893 policy
->RegisterWebSafeScheme(scheme
);
896 // Sets a particular response for any request from now on. To switch back to
897 // the default bahavior, pass an empty |headers|. |headers| should be raw-
898 // formatted (NULLs instead of EOLs).
899 void SetResponse(const std::string
& headers
, const std::string
& data
) {
900 response_headers_
= net::HttpUtil::AssembleRawHeaders(headers
.data(),
902 response_data_
= data
;
904 void SetResponse(const std::string
& headers
) {
905 SetResponse(headers
, std::string());
908 void SendDataReceivedACKs(bool send_acks
) {
909 send_data_received_acks_
= send_acks
;
912 // Intercepts requests for the given protocol.
913 void HandleScheme(const std::string
& scheme
) {
914 job_factory_
->HandleScheme(scheme
);
915 EnsureSchemeIsAllowed(scheme
);
918 void GenerateDataReceivedACK(const IPC::Message
& msg
) {
919 EXPECT_EQ(ResourceMsg_DataReceived::ID
, msg
.type());
922 bool result
= base::PickleIterator(msg
).ReadInt(&request_id
);
924 scoped_ptr
<IPC::Message
> ack(
925 new ResourceHostMsg_DataReceived_ACK(request_id
));
927 base::ThreadTaskRunnerHandle::Get()->PostTask(
929 base::Bind(&GenerateIPCMessage
, filter_
, base::Passed(&ack
)));
932 // Setting filters for testing renderer messages.
933 // Returns the previous filter.
934 ResourceMessageFilter
* SetFilter(ResourceMessageFilter
* new_filter
) {
935 ResourceMessageFilter
* old_filter
= host_
.filter_
;
936 host_
.filter_
= new_filter
;
940 void WaitForRequestComplete() {
941 DCHECK(!wait_for_request_complete_loop_
);
942 wait_for_request_complete_loop_
.reset(new base::RunLoop
);
943 wait_for_request_complete_loop_
->Run();
944 wait_for_request_complete_loop_
.reset();
947 scoped_ptr
<LoadInfoTestRequestInfo
> loader_test_request_info_
;
948 scoped_ptr
<base::RunLoop
> wait_for_request_create_loop_
;
950 content::TestBrowserThreadBundle thread_bundle_
;
951 scoped_ptr
<TestBrowserContext
> browser_context_
;
952 scoped_ptr
<TestURLRequestJobFactory
> job_factory_
;
953 scoped_refptr
<ForwardingFilter
> filter_
;
954 net::TestNetworkDelegate network_delegate_
;
955 ResourceDispatcherHostImpl host_
;
956 ResourceIPCAccumulator accum_
;
957 std::string response_headers_
;
958 std::string response_data_
;
960 net::URLRequest::ProtocolFactory
* old_factory_
;
961 bool send_data_received_acks_
;
962 std::set
<int> child_ids_
;
963 scoped_ptr
<base::RunLoop
> wait_for_request_complete_loop_
;
966 void ResourceDispatcherHostTest::MakeTestRequest(int render_view_id
,
969 MakeTestRequestWithResourceType(filter_
.get(), render_view_id
, request_id
,
970 url
, RESOURCE_TYPE_SUB_RESOURCE
);
973 void ResourceDispatcherHostTest::MakeTestRequestWithResourceType(
974 ResourceMessageFilter
* filter
,
979 ResourceHostMsg_Request request
=
980 CreateResourceRequest("GET", type
, url
);
981 ResourceHostMsg_RequestResource
msg(render_view_id
, request_id
, request
);
982 host_
.OnMessageReceived(msg
, filter
);
986 void ResourceDispatcherHostTest::CancelRequest(int request_id
) {
987 host_
.CancelRequest(filter_
->child_id(), request_id
);
990 void ResourceDispatcherHostTest::CompleteStartRequest(int request_id
) {
991 CompleteStartRequest(filter_
.get(), request_id
);
994 void ResourceDispatcherHostTest::CompleteStartRequest(
995 ResourceMessageFilter
* filter
,
997 GlobalRequestID
gid(filter
->child_id(), request_id
);
998 net::URLRequest
* req
= host_
.GetURLRequest(gid
);
1001 URLRequestTestDelayedStartJob::CompleteStart(req
);
1004 void CheckRequestCompleteErrorCode(const IPC::Message
& message
,
1005 int expected_error_code
) {
1006 // Verify the expected error code was received.
1010 ASSERT_EQ(ResourceMsg_RequestComplete::ID
, message
.type());
1012 base::PickleIterator
iter(message
);
1013 ASSERT_TRUE(IPC::ReadParam(&message
, &iter
, &request_id
));
1014 ASSERT_TRUE(IPC::ReadParam(&message
, &iter
, &error_code
));
1015 ASSERT_EQ(expected_error_code
, error_code
);
1018 testing::AssertionResult
ExtractDataOffsetAndLength(const IPC::Message
& message
,
1021 base::PickleIterator
iter(message
);
1023 if (!IPC::ReadParam(&message
, &iter
, &request_id
))
1024 return testing::AssertionFailure() << "Could not read request_id";
1025 if (!IPC::ReadParam(&message
, &iter
, data_offset
))
1026 return testing::AssertionFailure() << "Could not read data_offset";
1027 if (!IPC::ReadParam(&message
, &iter
, data_length
))
1028 return testing::AssertionFailure() << "Could not read data_length";
1029 return testing::AssertionSuccess();
1032 void CheckSuccessfulRequestWithErrorCode(
1033 const std::vector
<IPC::Message
>& messages
,
1034 const std::string
& reference_data
,
1035 int expected_error
) {
1036 // A successful request will have received 4 messages:
1037 // ReceivedResponse (indicates headers received)
1038 // SetDataBuffer (contains shared memory handle)
1039 // DataReceived (data offset and length into shared memory)
1040 // RequestComplete (request is done)
1042 // This function verifies that we received 4 messages and that they are
1043 // appropriate. It allows for an error code other than net::OK if the request
1044 // should successfully receive data and then abort, e.g., on cancel.
1045 ASSERT_EQ(4U, messages
.size());
1047 // The first messages should be received response
1048 ASSERT_EQ(ResourceMsg_ReceivedResponse::ID
, messages
[0].type());
1050 ASSERT_EQ(ResourceMsg_SetDataBuffer::ID
, messages
[1].type());
1052 base::PickleIterator
iter(messages
[1]);
1054 ASSERT_TRUE(IPC::ReadParam(&messages
[1], &iter
, &request_id
));
1055 base::SharedMemoryHandle shm_handle
;
1056 ASSERT_TRUE(IPC::ReadParam(&messages
[1], &iter
, &shm_handle
));
1058 ASSERT_TRUE(IPC::ReadParam(&messages
[1], &iter
, &shm_size
));
1060 // Followed by the data, currently we only do the data in one chunk, but
1061 // should probably test multiple chunks later
1062 ASSERT_EQ(ResourceMsg_DataReceived::ID
, messages
[2].type());
1067 ExtractDataOffsetAndLength(messages
[2], &data_offset
, &data_length
));
1069 ASSERT_EQ(reference_data
.size(), static_cast<size_t>(data_length
));
1070 ASSERT_GE(shm_size
, data_length
);
1072 base::SharedMemory
shared_mem(shm_handle
, true); // read only
1073 shared_mem
.Map(data_length
);
1074 const char* data
= static_cast<char*>(shared_mem
.memory()) + data_offset
;
1075 ASSERT_EQ(0, memcmp(reference_data
.c_str(), data
, data_length
));
1077 // The last message should be all data received.
1078 CheckRequestCompleteErrorCode(messages
[3], expected_error
);
1081 void CheckSuccessfulRequest(const std::vector
<IPC::Message
>& messages
,
1082 const std::string
& reference_data
) {
1083 CheckSuccessfulRequestWithErrorCode(messages
, reference_data
, net::OK
);
1086 void CheckSuccessfulRedirect(const std::vector
<IPC::Message
>& messages
,
1087 const std::string
& reference_data
) {
1088 ASSERT_EQ(5U, messages
.size());
1089 ASSERT_EQ(ResourceMsg_ReceivedRedirect::ID
, messages
[0].type());
1091 const std::vector
<IPC::Message
> second_req_msgs
=
1092 std::vector
<IPC::Message
>(messages
.begin() + 1, messages
.end());
1093 CheckSuccessfulRequest(second_req_msgs
, reference_data
);
1096 void CheckFailedRequest(const std::vector
<IPC::Message
>& messages
,
1097 const std::string
& reference_data
,
1098 int expected_error
) {
1099 ASSERT_LT(0U, messages
.size());
1100 ASSERT_GE(2U, messages
.size());
1101 size_t failure_index
= messages
.size() - 1;
1103 if (messages
.size() == 2) {
1104 EXPECT_EQ(ResourceMsg_ReceivedResponse::ID
, messages
[0].type());
1107 CheckRequestCompleteErrorCode(messages
[failure_index
], expected_error
);
1110 // Tests whether many messages get dispatched properly.
1111 TEST_F(ResourceDispatcherHostTest
, TestMany
) {
1112 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
1113 MakeTestRequest(0, 2, net::URLRequestTestJob::test_url_2());
1114 MakeTestRequest(0, 3, net::URLRequestTestJob::test_url_3());
1115 MakeTestRequestWithResourceType(filter_
.get(), 0, 4,
1116 net::URLRequestTestJob::test_url_4(),
1117 RESOURCE_TYPE_PREFETCH
); // detachable type
1118 MakeTestRequest(0, 5, net::URLRequestTestJob::test_url_redirect_to_url_2());
1120 // Finish the redirection
1121 ResourceHostMsg_FollowRedirect
redirect_msg(5);
1122 host_
.OnMessageReceived(redirect_msg
, filter_
.get());
1123 base::MessageLoop::current()->RunUntilIdle();
1125 // flush all the pending requests
1126 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1128 // sorts out all the messages we saw by request
1129 ResourceIPCAccumulator::ClassifiedMessages msgs
;
1130 accum_
.GetClassifiedMessages(&msgs
);
1132 // there are five requests, so we should have gotten them classified as such
1133 ASSERT_EQ(5U, msgs
.size());
1135 CheckSuccessfulRequest(msgs
[0], net::URLRequestTestJob::test_data_1());
1136 CheckSuccessfulRequest(msgs
[1], net::URLRequestTestJob::test_data_2());
1137 CheckSuccessfulRequest(msgs
[2], net::URLRequestTestJob::test_data_3());
1138 CheckSuccessfulRequest(msgs
[3], net::URLRequestTestJob::test_data_4());
1139 CheckSuccessfulRedirect(msgs
[4], net::URLRequestTestJob::test_data_2());
1142 // Tests whether messages get canceled properly. We issue four requests,
1143 // cancel two of them, and make sure that each sent the proper notifications.
1144 TEST_F(ResourceDispatcherHostTest
, Cancel
) {
1145 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
1146 MakeTestRequest(0, 2, net::URLRequestTestJob::test_url_2());
1147 MakeTestRequest(0, 3, net::URLRequestTestJob::test_url_3());
1149 MakeTestRequestWithResourceType(filter_
.get(), 0, 4,
1150 net::URLRequestTestJob::test_url_4(),
1151 RESOURCE_TYPE_PREFETCH
); // detachable type
1155 // Cancel request must come from the renderer for a detachable resource to
1157 RendererCancelRequest(4);
1159 // The handler should have been detached now.
1160 GlobalRequestID
global_request_id(filter_
->child_id(), 4);
1161 ResourceRequestInfoImpl
* info
= ResourceRequestInfoImpl::ForRequest(
1162 host_
.GetURLRequest(global_request_id
));
1163 ASSERT_TRUE(info
->detachable_handler()->is_detached());
1165 // flush all the pending requests
1166 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1167 base::MessageLoop::current()->RunUntilIdle();
1169 // Everything should be out now.
1170 EXPECT_EQ(0, host_
.pending_requests());
1172 ResourceIPCAccumulator::ClassifiedMessages msgs
;
1173 accum_
.GetClassifiedMessages(&msgs
);
1175 // there are four requests, so we should have gotten them classified as such
1176 ASSERT_EQ(4U, msgs
.size());
1178 CheckSuccessfulRequest(msgs
[0], net::URLRequestTestJob::test_data_1());
1179 CheckSuccessfulRequest(msgs
[2], net::URLRequestTestJob::test_data_3());
1181 // Check that request 2 and 4 got canceled, as far as the renderer is
1182 // concerned. Request 2 will have been deleted.
1183 ASSERT_EQ(1U, msgs
[1].size());
1184 ASSERT_EQ(ResourceMsg_ReceivedResponse::ID
, msgs
[1][0].type());
1186 ASSERT_EQ(2U, msgs
[3].size());
1187 ASSERT_EQ(ResourceMsg_ReceivedResponse::ID
, msgs
[3][0].type());
1188 CheckRequestCompleteErrorCode(msgs
[3][1], net::ERR_ABORTED
);
1190 // However, request 4 should have actually gone to completion. (Only request 2
1192 EXPECT_EQ(4, network_delegate()->completed_requests());
1193 EXPECT_EQ(1, network_delegate()->canceled_requests());
1194 EXPECT_EQ(0, network_delegate()->error_count());
1197 // Shows that detachable requests will timeout if the request takes too long to
1199 TEST_F(ResourceDispatcherHostTest
, DetachedResourceTimesOut
) {
1200 MakeTestRequestWithResourceType(filter_
.get(), 0, 1,
1201 net::URLRequestTestJob::test_url_2(),
1202 RESOURCE_TYPE_PREFETCH
); // detachable type
1203 GlobalRequestID
global_request_id(filter_
->child_id(), 1);
1204 ResourceRequestInfoImpl
* info
= ResourceRequestInfoImpl::ForRequest(
1205 host_
.GetURLRequest(global_request_id
));
1206 ASSERT_TRUE(info
->detachable_handler());
1207 info
->detachable_handler()->set_cancel_delay(
1208 base::TimeDelta::FromMilliseconds(200));
1209 base::MessageLoop::current()->RunUntilIdle();
1211 RendererCancelRequest(1);
1213 // From the renderer's perspective, the request was cancelled.
1214 ResourceIPCAccumulator::ClassifiedMessages msgs
;
1215 accum_
.GetClassifiedMessages(&msgs
);
1216 ASSERT_EQ(1U, msgs
.size());
1217 ASSERT_EQ(2U, msgs
[0].size());
1218 ASSERT_EQ(ResourceMsg_ReceivedResponse::ID
, msgs
[0][0].type());
1219 CheckRequestCompleteErrorCode(msgs
[0][1], net::ERR_ABORTED
);
1221 // But it continues detached.
1222 EXPECT_EQ(1, host_
.pending_requests());
1223 EXPECT_TRUE(info
->detachable_handler()->is_detached());
1225 // Wait until after the delay timer times out before we start processing any
1227 base::OneShotTimer
<base::MessageLoop
> timer
;
1228 timer
.Start(FROM_HERE
, base::TimeDelta::FromMilliseconds(210),
1229 base::MessageLoop::current(), &base::MessageLoop::QuitWhenIdle
);
1230 base::MessageLoop::current()->Run();
1232 // The prefetch should be cancelled by now.
1233 EXPECT_EQ(0, host_
.pending_requests());
1234 EXPECT_EQ(1, network_delegate()->completed_requests());
1235 EXPECT_EQ(1, network_delegate()->canceled_requests());
1236 EXPECT_EQ(0, network_delegate()->error_count());
1239 // If the filter has disappeared then detachable resources should continue to
1241 TEST_F(ResourceDispatcherHostTest
, DeletedFilterDetached
) {
1242 // test_url_1's data is available synchronously, so use 2 and 3.
1243 ResourceHostMsg_Request request_prefetch
= CreateResourceRequest(
1244 "GET", RESOURCE_TYPE_PREFETCH
, net::URLRequestTestJob::test_url_2());
1245 ResourceHostMsg_Request request_ping
= CreateResourceRequest(
1246 "GET", RESOURCE_TYPE_PING
, net::URLRequestTestJob::test_url_3());
1248 ResourceHostMsg_RequestResource
msg_prefetch(0, 1, request_prefetch
);
1249 host_
.OnMessageReceived(msg_prefetch
, filter_
.get());
1250 ResourceHostMsg_RequestResource
msg_ping(0, 2, request_ping
);
1251 host_
.OnMessageReceived(msg_ping
, filter_
.get());
1253 // Remove the filter before processing the requests by simulating channel
1255 ResourceRequestInfoImpl
* info_prefetch
= ResourceRequestInfoImpl::ForRequest(
1256 host_
.GetURLRequest(GlobalRequestID(filter_
->child_id(), 1)));
1257 ResourceRequestInfoImpl
* info_ping
= ResourceRequestInfoImpl::ForRequest(
1258 host_
.GetURLRequest(GlobalRequestID(filter_
->child_id(), 2)));
1259 DCHECK_EQ(filter_
.get(), info_prefetch
->filter());
1260 DCHECK_EQ(filter_
.get(), info_ping
->filter());
1261 filter_
->OnChannelClosing();
1262 info_prefetch
->filter_
.reset();
1263 info_ping
->filter_
.reset();
1265 // From the renderer's perspective, the requests were cancelled.
1266 ResourceIPCAccumulator::ClassifiedMessages msgs
;
1267 accum_
.GetClassifiedMessages(&msgs
);
1268 ASSERT_EQ(2U, msgs
.size());
1269 CheckRequestCompleteErrorCode(msgs
[0][0], net::ERR_ABORTED
);
1270 CheckRequestCompleteErrorCode(msgs
[1][0], net::ERR_ABORTED
);
1272 // But it continues detached.
1273 EXPECT_EQ(2, host_
.pending_requests());
1274 EXPECT_TRUE(info_prefetch
->detachable_handler()->is_detached());
1275 EXPECT_TRUE(info_ping
->detachable_handler()->is_detached());
1279 // Make sure the requests weren't canceled early.
1280 EXPECT_EQ(2, host_
.pending_requests());
1282 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1283 base::MessageLoop::current()->RunUntilIdle();
1285 EXPECT_EQ(0, host_
.pending_requests());
1286 EXPECT_EQ(2, network_delegate()->completed_requests());
1287 EXPECT_EQ(0, network_delegate()->canceled_requests());
1288 EXPECT_EQ(0, network_delegate()->error_count());
1291 // If the filter has disappeared (original process dies) then detachable
1292 // resources should continue to load, even when redirected.
1293 TEST_F(ResourceDispatcherHostTest
, DeletedFilterDetachedRedirect
) {
1294 ResourceHostMsg_Request request
= CreateResourceRequest(
1295 "GET", RESOURCE_TYPE_PREFETCH
,
1296 net::URLRequestTestJob::test_url_redirect_to_url_2());
1298 ResourceHostMsg_RequestResource
msg(0, 1, request
);
1299 host_
.OnMessageReceived(msg
, filter_
.get());
1301 // Remove the filter before processing the request by simulating channel
1303 GlobalRequestID
global_request_id(filter_
->child_id(), 1);
1304 ResourceRequestInfoImpl
* info
= ResourceRequestInfoImpl::ForRequest(
1305 host_
.GetURLRequest(global_request_id
));
1306 info
->filter_
->OnChannelClosing();
1307 info
->filter_
.reset();
1309 // From the renderer's perspective, the request was cancelled.
1310 ResourceIPCAccumulator::ClassifiedMessages msgs
;
1311 accum_
.GetClassifiedMessages(&msgs
);
1312 ASSERT_EQ(1U, msgs
.size());
1313 CheckRequestCompleteErrorCode(msgs
[0][0], net::ERR_ABORTED
);
1315 // But it continues detached.
1316 EXPECT_EQ(1, host_
.pending_requests());
1317 EXPECT_TRUE(info
->detachable_handler()->is_detached());
1319 // Verify no redirects before resetting the filter.
1320 net::URLRequest
* url_request
= host_
.GetURLRequest(global_request_id
);
1321 EXPECT_EQ(1u, url_request
->url_chain().size());
1324 // Verify that a redirect was followed.
1325 EXPECT_EQ(2u, url_request
->url_chain().size());
1327 // Make sure the request wasn't canceled early.
1328 EXPECT_EQ(1, host_
.pending_requests());
1330 // Finish up the request.
1331 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1332 base::MessageLoop::current()->RunUntilIdle();
1334 EXPECT_EQ(0, host_
.pending_requests());
1335 EXPECT_EQ(1, network_delegate()->completed_requests());
1336 EXPECT_EQ(0, network_delegate()->canceled_requests());
1337 EXPECT_EQ(0, network_delegate()->error_count());
1340 TEST_F(ResourceDispatcherHostTest
, CancelWhileStartIsDeferred
) {
1341 bool was_deleted
= false;
1343 // Arrange to have requests deferred before starting.
1344 TestResourceDispatcherHostDelegate delegate
;
1345 delegate
.set_flags(DEFER_STARTING_REQUEST
);
1346 delegate
.set_url_request_user_data(new TestUserData(&was_deleted
));
1347 host_
.SetDelegate(&delegate
);
1349 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
1350 // We cancel from the renderer because all non-renderer cancels delete
1351 // the request synchronously.
1352 RendererCancelRequest(1);
1354 // Our TestResourceThrottle should not have been deleted yet. This is to
1355 // ensure that destruction of the URLRequest happens asynchronously to
1356 // calling CancelRequest.
1357 EXPECT_FALSE(was_deleted
);
1359 base::MessageLoop::current()->RunUntilIdle();
1361 EXPECT_TRUE(was_deleted
);
1364 TEST_F(ResourceDispatcherHostTest
, DetachWhileStartIsDeferred
) {
1365 bool was_deleted
= false;
1367 // Arrange to have requests deferred before starting.
1368 TestResourceDispatcherHostDelegate delegate
;
1369 delegate
.set_flags(DEFER_STARTING_REQUEST
);
1370 delegate
.set_url_request_user_data(new TestUserData(&was_deleted
));
1371 host_
.SetDelegate(&delegate
);
1373 MakeTestRequestWithResourceType(filter_
.get(), 0, 1,
1374 net::URLRequestTestJob::test_url_1(),
1375 RESOURCE_TYPE_PREFETCH
); // detachable type
1376 // Cancel request must come from the renderer for a detachable resource to
1378 RendererCancelRequest(1);
1380 // Even after driving the event loop, the request has not been deleted.
1381 EXPECT_FALSE(was_deleted
);
1383 // However, it is still throttled because the defer happened above the
1384 // DetachableResourceHandler.
1385 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1386 base::MessageLoop::current()->RunUntilIdle();
1387 EXPECT_FALSE(was_deleted
);
1389 // Resume the request.
1390 GenericResourceThrottle
* throttle
=
1391 GenericResourceThrottle::active_throttle();
1392 ASSERT_TRUE(throttle
);
1395 // Now, the request completes.
1396 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1397 base::MessageLoop::current()->RunUntilIdle();
1398 EXPECT_TRUE(was_deleted
);
1399 EXPECT_EQ(1, network_delegate()->completed_requests());
1400 EXPECT_EQ(0, network_delegate()->canceled_requests());
1401 EXPECT_EQ(0, network_delegate()->error_count());
1404 // Tests if cancel is called in ResourceThrottle::WillStartRequest, then the
1405 // URLRequest will not be started.
1406 TEST_F(ResourceDispatcherHostTest
, CancelInResourceThrottleWillStartRequest
) {
1407 TestResourceDispatcherHostDelegate delegate
;
1408 delegate
.set_flags(CANCEL_BEFORE_START
);
1409 host_
.SetDelegate(&delegate
);
1411 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
1413 // flush all the pending requests
1414 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1415 base::MessageLoop::current()->RunUntilIdle();
1417 ResourceIPCAccumulator::ClassifiedMessages msgs
;
1418 accum_
.GetClassifiedMessages(&msgs
);
1420 // Check that request got canceled.
1421 ASSERT_EQ(1U, msgs
[0].size());
1422 CheckRequestCompleteErrorCode(msgs
[0][0], net::ERR_ABORTED
);
1424 // Make sure URLRequest is never started.
1425 EXPECT_EQ(0, job_factory_
->url_request_jobs_created_count());
1428 TEST_F(ResourceDispatcherHostTest
, PausedStartError
) {
1429 // Arrange to have requests deferred before processing response headers.
1430 TestResourceDispatcherHostDelegate delegate
;
1431 delegate
.set_flags(DEFER_PROCESSING_RESPONSE
);
1432 host_
.SetDelegate(&delegate
);
1434 job_factory_
->SetDelayedStartJobGeneration(true);
1435 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_error());
1436 CompleteStartRequest(1);
1438 // flush all the pending requests
1439 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1440 base::MessageLoop::current()->RunUntilIdle();
1442 EXPECT_EQ(0, host_
.pending_requests());
1445 // Test the WillStartUsingNetwork throttle.
1446 TEST_F(ResourceDispatcherHostTest
, ThrottleNetworkStart
) {
1447 // Arrange to have requests deferred before processing response headers.
1448 TestResourceDispatcherHostDelegate delegate
;
1449 delegate
.set_flags(DEFER_NETWORK_START
);
1450 host_
.SetDelegate(&delegate
);
1452 job_factory_
->SetNetworkStartNotificationJobGeneration(true);
1453 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_2());
1455 // Should have deferred for network start.
1456 GenericResourceThrottle
* first_throttle
=
1457 GenericResourceThrottle::active_throttle();
1458 ASSERT_TRUE(first_throttle
);
1459 EXPECT_EQ(0, network_delegate()->completed_requests());
1460 EXPECT_EQ(1, host_
.pending_requests());
1462 first_throttle
->Resume();
1464 // Flush all the pending requests.
1465 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1466 base::MessageLoop::current()->RunUntilIdle();
1468 EXPECT_EQ(1, network_delegate()->completed_requests());
1469 EXPECT_EQ(0, host_
.pending_requests());
1472 TEST_F(ResourceDispatcherHostTest
, ThrottleAndResumeTwice
) {
1473 // Arrange to have requests deferred before starting.
1474 TestResourceDispatcherHostDelegate delegate
;
1475 delegate
.set_flags(DEFER_STARTING_REQUEST
);
1476 delegate
.set_create_two_throttles(true);
1477 host_
.SetDelegate(&delegate
);
1479 // Make sure the first throttle blocked the request, and then resume.
1480 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
1481 GenericResourceThrottle
* first_throttle
=
1482 GenericResourceThrottle::active_throttle();
1483 ASSERT_TRUE(first_throttle
);
1484 first_throttle
->Resume();
1486 // Make sure the second throttle blocked the request, and then resume.
1487 ASSERT_TRUE(GenericResourceThrottle::active_throttle());
1488 ASSERT_NE(first_throttle
, GenericResourceThrottle::active_throttle());
1489 GenericResourceThrottle::active_throttle()->Resume();
1491 ASSERT_FALSE(GenericResourceThrottle::active_throttle());
1493 // The request is started asynchronously.
1494 base::MessageLoop::current()->RunUntilIdle();
1496 // Flush all the pending requests.
1497 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1499 EXPECT_EQ(0, host_
.pending_requests());
1501 // Make sure the request completed successfully.
1502 ResourceIPCAccumulator::ClassifiedMessages msgs
;
1503 accum_
.GetClassifiedMessages(&msgs
);
1504 ASSERT_EQ(1U, msgs
.size());
1505 CheckSuccessfulRequest(msgs
[0], net::URLRequestTestJob::test_data_1());
1509 // Tests that the delegate can cancel a request and provide a error code.
1510 TEST_F(ResourceDispatcherHostTest
, CancelInDelegate
) {
1511 TestResourceDispatcherHostDelegate delegate
;
1512 delegate
.set_flags(CANCEL_BEFORE_START
);
1513 delegate
.set_error_code_for_cancellation(net::ERR_ACCESS_DENIED
);
1514 host_
.SetDelegate(&delegate
);
1516 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
1517 // The request will get cancelled by the throttle.
1519 // flush all the pending requests
1520 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1521 base::MessageLoop::current()->RunUntilIdle();
1523 ResourceIPCAccumulator::ClassifiedMessages msgs
;
1524 accum_
.GetClassifiedMessages(&msgs
);
1526 // Check the cancellation
1527 ASSERT_EQ(1U, msgs
.size());
1528 ASSERT_EQ(1U, msgs
[0].size());
1530 CheckRequestCompleteErrorCode(msgs
[0][0], net::ERR_ACCESS_DENIED
);
1533 // Tests CancelRequestsForProcess
1534 TEST_F(ResourceDispatcherHostTest
, TestProcessCancel
) {
1535 scoped_refptr
<TestFilter
> test_filter
= new TestFilter(
1536 browser_context_
->GetResourceContext());
1537 child_ids_
.insert(test_filter
->child_id());
1539 // request 1 goes to the test delegate
1540 ResourceHostMsg_Request request
= CreateResourceRequest(
1541 "GET", RESOURCE_TYPE_SUB_RESOURCE
, net::URLRequestTestJob::test_url_1());
1543 MakeTestRequestWithResourceType(test_filter
.get(), 0, 1,
1544 net::URLRequestTestJob::test_url_1(),
1545 RESOURCE_TYPE_SUB_RESOURCE
);
1547 // request 2 goes to us
1548 MakeTestRequest(0, 2, net::URLRequestTestJob::test_url_2());
1550 // request 3 goes to the test delegate
1551 MakeTestRequestWithResourceType(test_filter
.get(), 0, 3,
1552 net::URLRequestTestJob::test_url_3(),
1553 RESOURCE_TYPE_SUB_RESOURCE
);
1555 // request 4 goes to us
1556 MakeTestRequestWithResourceType(filter_
.get(), 0, 4,
1557 net::URLRequestTestJob::test_url_4(),
1558 RESOURCE_TYPE_PREFETCH
); // detachable type
1561 // Make sure all requests have finished stage one. test_url_1 will have
1563 base::MessageLoop::current()->RunUntilIdle();
1566 // Now that the async IO path is in place, the IO always completes on the
1567 // initial call; so the requests have already completed. This basically
1568 // breaks the whole test.
1569 //EXPECT_EQ(3, host_.pending_requests());
1571 // Process test_url_2 and test_url_3 for one level so one callback is called.
1572 // We'll cancel test_url_4 (detachable) before processing it to verify that it
1573 // delays the cancel.
1574 for (int i
= 0; i
< 2; i
++)
1575 EXPECT_TRUE(net::URLRequestTestJob::ProcessOnePendingMessage());
1577 // Cancel the requests to the test process.
1578 host_
.CancelRequestsForProcess(filter_
->child_id());
1579 test_filter
->set_canceled(true);
1581 // The requests should all be cancelled, except request 4, which is detached.
1582 EXPECT_EQ(1, host_
.pending_requests());
1583 GlobalRequestID
global_request_id(filter_
->child_id(), 4);
1584 ResourceRequestInfoImpl
* info
= ResourceRequestInfoImpl::ForRequest(
1585 host_
.GetURLRequest(global_request_id
));
1586 ASSERT_TRUE(info
->detachable_handler()->is_detached());
1588 // Flush all the pending requests.
1589 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1591 EXPECT_EQ(0, host_
.pending_requests());
1593 // The test delegate should not have gotten any messages after being canceled.
1594 ASSERT_EQ(0, test_filter
->received_after_canceled());
1596 // There should be two results.
1597 ResourceIPCAccumulator::ClassifiedMessages msgs
;
1598 accum_
.GetClassifiedMessages(&msgs
);
1599 ASSERT_EQ(2U, msgs
.size());
1600 CheckSuccessfulRequest(msgs
[0], net::URLRequestTestJob::test_data_2());
1601 // The detachable request was cancelled by the renderer before it
1602 // finished. From the perspective of the renderer, it should have cancelled.
1603 ASSERT_EQ(2U, msgs
[1].size());
1604 ASSERT_EQ(ResourceMsg_ReceivedResponse::ID
, msgs
[1][0].type());
1605 CheckRequestCompleteErrorCode(msgs
[1][1], net::ERR_ABORTED
);
1606 // But it completed anyway. For the network stack, no requests were canceled.
1607 EXPECT_EQ(4, network_delegate()->completed_requests());
1608 EXPECT_EQ(0, network_delegate()->canceled_requests());
1609 EXPECT_EQ(0, network_delegate()->error_count());
1612 TEST_F(ResourceDispatcherHostTest
, TestProcessCancelDetachedTimesOut
) {
1613 MakeTestRequestWithResourceType(filter_
.get(), 0, 1,
1614 net::URLRequestTestJob::test_url_4(),
1615 RESOURCE_TYPE_PREFETCH
); // detachable type
1616 GlobalRequestID
global_request_id(filter_
->child_id(), 1);
1617 ResourceRequestInfoImpl
* info
= ResourceRequestInfoImpl::ForRequest(
1618 host_
.GetURLRequest(global_request_id
));
1619 ASSERT_TRUE(info
->detachable_handler());
1620 info
->detachable_handler()->set_cancel_delay(
1621 base::TimeDelta::FromMilliseconds(200));
1622 base::MessageLoop::current()->RunUntilIdle();
1624 // Cancel the requests to the test process.
1625 host_
.CancelRequestsForProcess(filter_
->child_id());
1626 EXPECT_EQ(1, host_
.pending_requests());
1628 // Wait until after the delay timer times out before we start processing any
1630 base::OneShotTimer
<base::MessageLoop
> timer
;
1631 timer
.Start(FROM_HERE
, base::TimeDelta::FromMilliseconds(210),
1632 base::MessageLoop::current(), &base::MessageLoop::QuitWhenIdle
);
1633 base::MessageLoop::current()->Run();
1635 // The prefetch should be cancelled by now.
1636 EXPECT_EQ(0, host_
.pending_requests());
1638 // In case any messages are still to be processed.
1639 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1640 base::MessageLoop::current()->RunUntilIdle();
1642 ResourceIPCAccumulator::ClassifiedMessages msgs
;
1643 accum_
.GetClassifiedMessages(&msgs
);
1645 ASSERT_EQ(1U, msgs
.size());
1647 // The request should have cancelled.
1648 ASSERT_EQ(2U, msgs
[0].size());
1649 ASSERT_EQ(ResourceMsg_ReceivedResponse::ID
, msgs
[0][0].type());
1650 CheckRequestCompleteErrorCode(msgs
[0][1], net::ERR_ABORTED
);
1651 // And not run to completion.
1652 EXPECT_EQ(1, network_delegate()->completed_requests());
1653 EXPECT_EQ(1, network_delegate()->canceled_requests());
1654 EXPECT_EQ(0, network_delegate()->error_count());
1657 // Tests blocking and resuming requests.
1658 TEST_F(ResourceDispatcherHostTest
, TestBlockingResumingRequests
) {
1659 host_
.BlockRequestsForRoute(filter_
->child_id(), 1);
1660 host_
.BlockRequestsForRoute(filter_
->child_id(), 2);
1661 host_
.BlockRequestsForRoute(filter_
->child_id(), 3);
1663 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
1664 MakeTestRequest(1, 2, net::URLRequestTestJob::test_url_2());
1665 MakeTestRequest(0, 3, net::URLRequestTestJob::test_url_3());
1666 MakeTestRequest(1, 4, net::URLRequestTestJob::test_url_1());
1667 MakeTestRequest(2, 5, net::URLRequestTestJob::test_url_2());
1668 MakeTestRequest(3, 6, net::URLRequestTestJob::test_url_3());
1670 // Flush all the pending requests
1671 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1673 // Sort out all the messages we saw by request
1674 ResourceIPCAccumulator::ClassifiedMessages msgs
;
1675 accum_
.GetClassifiedMessages(&msgs
);
1677 // All requests but the 2 for the RVH 0 should have been blocked.
1678 ASSERT_EQ(2U, msgs
.size());
1680 CheckSuccessfulRequest(msgs
[0], net::URLRequestTestJob::test_data_1());
1681 CheckSuccessfulRequest(msgs
[1], net::URLRequestTestJob::test_data_3());
1683 // Resume requests for RVH 1 and flush pending requests.
1684 host_
.ResumeBlockedRequestsForRoute(filter_
->child_id(), 1);
1686 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1689 accum_
.GetClassifiedMessages(&msgs
);
1690 ASSERT_EQ(2U, msgs
.size());
1691 CheckSuccessfulRequest(msgs
[0], net::URLRequestTestJob::test_data_2());
1692 CheckSuccessfulRequest(msgs
[1], net::URLRequestTestJob::test_data_1());
1694 // Test that new requests are not blocked for RVH 1.
1695 MakeTestRequest(1, 7, net::URLRequestTestJob::test_url_1());
1696 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1698 accum_
.GetClassifiedMessages(&msgs
);
1699 ASSERT_EQ(1U, msgs
.size());
1700 CheckSuccessfulRequest(msgs
[0], net::URLRequestTestJob::test_data_1());
1702 // Now resumes requests for all RVH (2 and 3).
1703 host_
.ResumeBlockedRequestsForRoute(filter_
->child_id(), 2);
1704 host_
.ResumeBlockedRequestsForRoute(filter_
->child_id(), 3);
1706 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1709 accum_
.GetClassifiedMessages(&msgs
);
1710 ASSERT_EQ(2U, msgs
.size());
1711 CheckSuccessfulRequest(msgs
[0], net::URLRequestTestJob::test_data_2());
1712 CheckSuccessfulRequest(msgs
[1], net::URLRequestTestJob::test_data_3());
1715 // Tests blocking and canceling requests.
1716 TEST_F(ResourceDispatcherHostTest
, TestBlockingCancelingRequests
) {
1717 host_
.BlockRequestsForRoute(filter_
->child_id(), 1);
1719 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
1720 MakeTestRequest(1, 2, net::URLRequestTestJob::test_url_2());
1721 MakeTestRequest(0, 3, net::URLRequestTestJob::test_url_3());
1722 MakeTestRequest(1, 4, net::URLRequestTestJob::test_url_1());
1723 // Blocked detachable resources should not delay cancellation.
1724 MakeTestRequestWithResourceType(filter_
.get(), 1, 5,
1725 net::URLRequestTestJob::test_url_4(),
1726 RESOURCE_TYPE_PREFETCH
); // detachable type
1728 // Flush all the pending requests.
1729 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1731 // Sort out all the messages we saw by request.
1732 ResourceIPCAccumulator::ClassifiedMessages msgs
;
1733 accum_
.GetClassifiedMessages(&msgs
);
1735 // The 2 requests for the RVH 0 should have been processed.
1736 ASSERT_EQ(2U, msgs
.size());
1738 CheckSuccessfulRequest(msgs
[0], net::URLRequestTestJob::test_data_1());
1739 CheckSuccessfulRequest(msgs
[1], net::URLRequestTestJob::test_data_3());
1741 // Cancel requests for RVH 1.
1742 host_
.CancelBlockedRequestsForRoute(filter_
->child_id(), 1);
1744 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1747 accum_
.GetClassifiedMessages(&msgs
);
1748 ASSERT_EQ(0U, msgs
.size());
1751 // Tests that blocked requests are canceled if their associated process dies.
1752 TEST_F(ResourceDispatcherHostTest
, TestBlockedRequestsProcessDies
) {
1753 // This second filter is used to emulate a second process.
1754 scoped_refptr
<ForwardingFilter
> second_filter
= MakeForwardingFilter();
1756 host_
.BlockRequestsForRoute(second_filter
->child_id(), 0);
1758 MakeTestRequestWithResourceType(filter_
.get(), 0, 1,
1759 net::URLRequestTestJob::test_url_1(),
1760 RESOURCE_TYPE_SUB_RESOURCE
);
1761 MakeTestRequestWithResourceType(second_filter
.get(), 0, 2,
1762 net::URLRequestTestJob::test_url_2(),
1763 RESOURCE_TYPE_SUB_RESOURCE
);
1764 MakeTestRequestWithResourceType(filter_
.get(), 0, 3,
1765 net::URLRequestTestJob::test_url_3(),
1766 RESOURCE_TYPE_SUB_RESOURCE
);
1767 MakeTestRequestWithResourceType(second_filter
.get(), 0, 4,
1768 net::URLRequestTestJob::test_url_1(),
1769 RESOURCE_TYPE_SUB_RESOURCE
);
1770 MakeTestRequestWithResourceType(second_filter
.get(), 0, 5,
1771 net::URLRequestTestJob::test_url_4(),
1772 RESOURCE_TYPE_PREFETCH
); // detachable type
1774 // Simulate process death.
1775 host_
.CancelRequestsForProcess(second_filter
->child_id());
1777 // Flush all the pending requests.
1778 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1780 // Sort out all the messages we saw by request.
1781 ResourceIPCAccumulator::ClassifiedMessages msgs
;
1782 accum_
.GetClassifiedMessages(&msgs
);
1784 // The 2 requests for the RVH 0 should have been processed. Note that
1785 // blocked detachable requests are canceled without delay.
1786 ASSERT_EQ(2U, msgs
.size());
1788 CheckSuccessfulRequest(msgs
[0], net::URLRequestTestJob::test_data_1());
1789 CheckSuccessfulRequest(msgs
[1], net::URLRequestTestJob::test_data_3());
1791 EXPECT_TRUE(host_
.blocked_loaders_map_
.empty());
1794 // Tests that blocked requests don't leak when the ResourceDispatcherHost goes
1795 // away. Note that we rely on Purify for finding the leaks if any.
1796 // If this test turns the Purify bot red, check the ResourceDispatcherHost
1797 // destructor to make sure the blocked requests are deleted.
1798 TEST_F(ResourceDispatcherHostTest
, TestBlockedRequestsDontLeak
) {
1799 // This second filter is used to emulate a second process.
1800 scoped_refptr
<ForwardingFilter
> second_filter
= MakeForwardingFilter();
1802 host_
.BlockRequestsForRoute(filter_
->child_id(), 1);
1803 host_
.BlockRequestsForRoute(filter_
->child_id(), 2);
1804 host_
.BlockRequestsForRoute(second_filter
->child_id(), 1);
1806 MakeTestRequestWithResourceType(filter_
.get(), 0, 1,
1807 net::URLRequestTestJob::test_url_1(),
1808 RESOURCE_TYPE_SUB_RESOURCE
);
1809 MakeTestRequestWithResourceType(filter_
.get(), 1, 2,
1810 net::URLRequestTestJob::test_url_2(),
1811 RESOURCE_TYPE_SUB_RESOURCE
);
1812 MakeTestRequestWithResourceType(filter_
.get(), 0, 3,
1813 net::URLRequestTestJob::test_url_3(),
1814 RESOURCE_TYPE_SUB_RESOURCE
);
1815 MakeTestRequestWithResourceType(second_filter
.get(), 1, 4,
1816 net::URLRequestTestJob::test_url_1(),
1817 RESOURCE_TYPE_SUB_RESOURCE
);
1818 MakeTestRequestWithResourceType(filter_
.get(), 2, 5,
1819 net::URLRequestTestJob::test_url_2(),
1820 RESOURCE_TYPE_SUB_RESOURCE
);
1821 MakeTestRequestWithResourceType(filter_
.get(), 2, 6,
1822 net::URLRequestTestJob::test_url_3(),
1823 RESOURCE_TYPE_SUB_RESOURCE
);
1824 MakeTestRequestWithResourceType(filter_
.get(), 0, 7,
1825 net::URLRequestTestJob::test_url_4(),
1826 RESOURCE_TYPE_PREFETCH
); // detachable type
1827 MakeTestRequestWithResourceType(second_filter
.get(), 1, 8,
1828 net::URLRequestTestJob::test_url_4(),
1829 RESOURCE_TYPE_PREFETCH
); // detachable type
1831 host_
.CancelRequestsForProcess(filter_
->child_id());
1832 host_
.CancelRequestsForProcess(second_filter
->child_id());
1834 // Flush all the pending requests.
1835 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1838 // Test the private helper method "CalculateApproximateMemoryCost()".
1839 TEST_F(ResourceDispatcherHostTest
, CalculateApproximateMemoryCost
) {
1840 net::URLRequestContext context
;
1841 scoped_ptr
<net::URLRequest
> req(context
.CreateRequest(
1842 GURL("http://www.google.com"), net::DEFAULT_PRIORITY
, NULL
));
1845 ResourceDispatcherHostImpl::CalculateApproximateMemoryCost(req
.get()));
1847 // Add 9 bytes of referrer.
1848 req
->SetReferrer("123456789");
1851 ResourceDispatcherHostImpl::CalculateApproximateMemoryCost(req
.get()));
1853 // Add 33 bytes of upload content.
1854 std::string upload_content
;
1855 upload_content
.resize(33);
1856 std::fill(upload_content
.begin(), upload_content
.end(), 'x');
1857 scoped_ptr
<net::UploadElementReader
> reader(new net::UploadBytesElementReader(
1858 upload_content
.data(), upload_content
.size()));
1860 net::ElementsUploadDataStream::CreateWithReader(reader
.Pass(), 0));
1862 // Since the upload throttling is disabled, this has no effect on the cost.
1865 ResourceDispatcherHostImpl::CalculateApproximateMemoryCost(req
.get()));
1868 // Test that too much memory for outstanding requests for a particular
1869 // render_process_host_id causes requests to fail.
1870 TEST_F(ResourceDispatcherHostTest
, TooMuchOutstandingRequestsMemory
) {
1871 // Expected cost of each request as measured by
1872 // ResourceDispatcherHost::CalculateApproximateMemoryCost().
1873 int kMemoryCostOfTest2Req
=
1874 ResourceDispatcherHostImpl::kAvgBytesPerOutstandingRequest
+
1875 std::string("GET").size() +
1876 net::URLRequestTestJob::test_url_2().spec().size();
1878 // Tighten the bound on the ResourceDispatcherHost, to speed things up.
1879 int kMaxCostPerProcess
= 440000;
1880 host_
.set_max_outstanding_requests_cost_per_process(kMaxCostPerProcess
);
1882 // Determine how many instance of test_url_2() we can request before
1883 // throttling kicks in.
1884 size_t kMaxRequests
= kMaxCostPerProcess
/ kMemoryCostOfTest2Req
;
1886 // This second filter is used to emulate a second process.
1887 scoped_refptr
<ForwardingFilter
> second_filter
= MakeForwardingFilter();
1889 // Saturate the number of outstanding requests for our process.
1890 for (size_t i
= 0; i
< kMaxRequests
; ++i
) {
1891 MakeTestRequestWithResourceType(filter_
.get(), 0, i
+ 1,
1892 net::URLRequestTestJob::test_url_2(),
1893 RESOURCE_TYPE_SUB_RESOURCE
);
1896 // Issue two more requests for our process -- these should fail immediately.
1897 MakeTestRequestWithResourceType(filter_
.get(), 0, kMaxRequests
+ 1,
1898 net::URLRequestTestJob::test_url_2(),
1899 RESOURCE_TYPE_SUB_RESOURCE
);
1900 MakeTestRequestWithResourceType(filter_
.get(), 0, kMaxRequests
+ 2,
1901 net::URLRequestTestJob::test_url_2(),
1902 RESOURCE_TYPE_SUB_RESOURCE
);
1904 // Issue two requests for the second process -- these should succeed since
1905 // it is just process 0 that is saturated.
1906 MakeTestRequestWithResourceType(second_filter
.get(), 0, kMaxRequests
+ 3,
1907 net::URLRequestTestJob::test_url_2(),
1908 RESOURCE_TYPE_SUB_RESOURCE
);
1909 MakeTestRequestWithResourceType(second_filter
.get(), 0, kMaxRequests
+ 4,
1910 net::URLRequestTestJob::test_url_2(),
1911 RESOURCE_TYPE_SUB_RESOURCE
);
1913 // Flush all the pending requests.
1914 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1915 base::MessageLoop::current()->RunUntilIdle();
1917 // Sorts out all the messages we saw by request.
1918 ResourceIPCAccumulator::ClassifiedMessages msgs
;
1919 accum_
.GetClassifiedMessages(&msgs
);
1921 // We issued (kMaxRequests + 4) total requests.
1922 ASSERT_EQ(kMaxRequests
+ 4, msgs
.size());
1924 // Check that the first kMaxRequests succeeded.
1925 for (size_t i
= 0; i
< kMaxRequests
; ++i
)
1926 CheckSuccessfulRequest(msgs
[i
], net::URLRequestTestJob::test_data_2());
1928 // Check that the subsequent two requests (kMaxRequests + 1) and
1929 // (kMaxRequests + 2) were failed, since the per-process bound was reached.
1930 for (int i
= 0; i
< 2; ++i
) {
1931 // Should have sent a single RequestComplete message.
1932 int index
= kMaxRequests
+ i
;
1933 CheckFailedRequest(msgs
[index
], net::URLRequestTestJob::test_data_2(),
1934 net::ERR_INSUFFICIENT_RESOURCES
);
1937 // The final 2 requests should have succeeded.
1938 CheckSuccessfulRequest(msgs
[kMaxRequests
+ 2],
1939 net::URLRequestTestJob::test_data_2());
1940 CheckSuccessfulRequest(msgs
[kMaxRequests
+ 3],
1941 net::URLRequestTestJob::test_data_2());
1944 // Test that when too many requests are outstanding for a particular
1945 // render_process_host_id, any subsequent request from it fails. Also verify
1946 // that the global limit is honored.
1947 TEST_F(ResourceDispatcherHostTest
, TooManyOutstandingRequests
) {
1948 // Tighten the bound on the ResourceDispatcherHost, to speed things up.
1949 const size_t kMaxRequestsPerProcess
= 2;
1950 host_
.set_max_num_in_flight_requests_per_process(kMaxRequestsPerProcess
);
1951 const size_t kMaxRequests
= 3;
1952 host_
.set_max_num_in_flight_requests(kMaxRequests
);
1954 // Needed to emulate additional processes.
1955 scoped_refptr
<ForwardingFilter
> second_filter
= MakeForwardingFilter();
1956 scoped_refptr
<ForwardingFilter
> third_filter
= MakeForwardingFilter();
1958 // Saturate the number of outstanding requests for our process.
1959 for (size_t i
= 0; i
< kMaxRequestsPerProcess
; ++i
) {
1960 MakeTestRequestWithResourceType(filter_
.get(), 0, i
+ 1,
1961 net::URLRequestTestJob::test_url_2(),
1962 RESOURCE_TYPE_SUB_RESOURCE
);
1965 // Issue another request for our process -- this should fail immediately.
1966 MakeTestRequestWithResourceType(filter_
.get(), 0, kMaxRequestsPerProcess
+ 1,
1967 net::URLRequestTestJob::test_url_2(),
1968 RESOURCE_TYPE_SUB_RESOURCE
);
1970 // Issue a request for the second process -- this should succeed, because it
1971 // is just process 0 that is saturated.
1972 MakeTestRequestWithResourceType(
1973 second_filter
.get(), 0, kMaxRequestsPerProcess
+ 2,
1974 net::URLRequestTestJob::test_url_2(), RESOURCE_TYPE_SUB_RESOURCE
);
1976 // Issue a request for the third process -- this should fail, because the
1977 // global limit has been reached.
1978 MakeTestRequestWithResourceType(
1979 third_filter
.get(), 0, kMaxRequestsPerProcess
+ 3,
1980 net::URLRequestTestJob::test_url_2(), RESOURCE_TYPE_SUB_RESOURCE
);
1982 // Flush all the pending requests.
1983 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1984 base::MessageLoop::current()->RunUntilIdle();
1986 // Sorts out all the messages we saw by request.
1987 ResourceIPCAccumulator::ClassifiedMessages msgs
;
1988 accum_
.GetClassifiedMessages(&msgs
);
1990 // The processes issued the following requests:
1991 // #1 issued kMaxRequestsPerProcess that passed + 1 that failed
1992 // #2 issued 1 request that passed
1993 // #3 issued 1 request that failed
1994 ASSERT_EQ((kMaxRequestsPerProcess
+ 1) + 1 + 1, msgs
.size());
1996 for (size_t i
= 0; i
< kMaxRequestsPerProcess
; ++i
)
1997 CheckSuccessfulRequest(msgs
[i
], net::URLRequestTestJob::test_data_2());
1999 CheckFailedRequest(msgs
[kMaxRequestsPerProcess
+ 0],
2000 net::URLRequestTestJob::test_data_2(),
2001 net::ERR_INSUFFICIENT_RESOURCES
);
2002 CheckSuccessfulRequest(msgs
[kMaxRequestsPerProcess
+ 1],
2003 net::URLRequestTestJob::test_data_2());
2004 CheckFailedRequest(msgs
[kMaxRequestsPerProcess
+ 2],
2005 net::URLRequestTestJob::test_data_2(),
2006 net::ERR_INSUFFICIENT_RESOURCES
);
2009 // Tests that we sniff the mime type for a simple request.
2010 TEST_F(ResourceDispatcherHostTest
, MimeSniffed
) {
2011 std::string
raw_headers("HTTP/1.1 200 OK\n\n");
2012 std::string
response_data("<html><title>Test One</title></html>");
2013 SetResponse(raw_headers
, response_data
);
2015 HandleScheme("http");
2016 MakeTestRequest(0, 1, GURL("http:bla"));
2018 // Flush all pending requests.
2019 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2021 // Sorts out all the messages we saw by request.
2022 ResourceIPCAccumulator::ClassifiedMessages msgs
;
2023 accum_
.GetClassifiedMessages(&msgs
);
2024 ASSERT_EQ(1U, msgs
.size());
2026 ResourceResponseHead response_head
;
2027 GetResponseHead(msgs
[0], &response_head
);
2028 ASSERT_EQ("text/html", response_head
.mime_type
);
2031 // Tests that we don't sniff the mime type when the server provides one.
2032 TEST_F(ResourceDispatcherHostTest
, MimeNotSniffed
) {
2033 std::string
raw_headers("HTTP/1.1 200 OK\n"
2034 "Content-type: image/jpeg\n\n");
2035 std::string
response_data("<html><title>Test One</title></html>");
2036 SetResponse(raw_headers
, response_data
);
2038 HandleScheme("http");
2039 MakeTestRequest(0, 1, GURL("http:bla"));
2041 // Flush all pending requests.
2042 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2044 // Sorts out all the messages we saw by request.
2045 ResourceIPCAccumulator::ClassifiedMessages msgs
;
2046 accum_
.GetClassifiedMessages(&msgs
);
2047 ASSERT_EQ(1U, msgs
.size());
2049 ResourceResponseHead response_head
;
2050 GetResponseHead(msgs
[0], &response_head
);
2051 ASSERT_EQ("image/jpeg", response_head
.mime_type
);
2054 // Tests that we don't sniff the mime type when there is no message body.
2055 TEST_F(ResourceDispatcherHostTest
, MimeNotSniffed2
) {
2056 SetResponse("HTTP/1.1 304 Not Modified\n\n");
2058 HandleScheme("http");
2059 MakeTestRequest(0, 1, GURL("http:bla"));
2061 // Flush all pending requests.
2062 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2064 // Sorts out all the messages we saw by request.
2065 ResourceIPCAccumulator::ClassifiedMessages msgs
;
2066 accum_
.GetClassifiedMessages(&msgs
);
2067 ASSERT_EQ(1U, msgs
.size());
2069 ResourceResponseHead response_head
;
2070 GetResponseHead(msgs
[0], &response_head
);
2071 ASSERT_EQ("", response_head
.mime_type
);
2074 TEST_F(ResourceDispatcherHostTest
, MimeSniff204
) {
2075 SetResponse("HTTP/1.1 204 No Content\n\n");
2077 HandleScheme("http");
2078 MakeTestRequest(0, 1, GURL("http:bla"));
2080 // Flush all pending requests.
2081 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2083 // Sorts out all the messages we saw by request.
2084 ResourceIPCAccumulator::ClassifiedMessages msgs
;
2085 accum_
.GetClassifiedMessages(&msgs
);
2086 ASSERT_EQ(1U, msgs
.size());
2088 ResourceResponseHead response_head
;
2089 GetResponseHead(msgs
[0], &response_head
);
2090 ASSERT_EQ("text/plain", response_head
.mime_type
);
2093 TEST_F(ResourceDispatcherHostTest
, MimeSniffEmpty
) {
2094 SetResponse("HTTP/1.1 200 OK\n\n");
2096 HandleScheme("http");
2097 MakeTestRequest(0, 1, GURL("http:bla"));
2099 // Flush all pending requests.
2100 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2102 // Sorts out all the messages we saw by request.
2103 ResourceIPCAccumulator::ClassifiedMessages msgs
;
2104 accum_
.GetClassifiedMessages(&msgs
);
2105 ASSERT_EQ(1U, msgs
.size());
2107 ResourceResponseHead response_head
;
2108 GetResponseHead(msgs
[0], &response_head
);
2109 ASSERT_EQ("text/plain", response_head
.mime_type
);
2112 // Tests for crbug.com/31266 (Non-2xx + application/octet-stream).
2113 TEST_F(ResourceDispatcherHostTest
, ForbiddenDownload
) {
2114 std::string
raw_headers("HTTP/1.1 403 Forbidden\n"
2115 "Content-disposition: attachment; filename=blah\n"
2116 "Content-type: application/octet-stream\n\n");
2117 std::string
response_data("<html><title>Test One</title></html>");
2118 SetResponse(raw_headers
, response_data
);
2120 HandleScheme("http");
2122 // Only MAIN_FRAMEs can trigger a download.
2123 MakeTestRequestWithResourceType(filter_
.get(), 0, 1, GURL("http:bla"),
2124 RESOURCE_TYPE_MAIN_FRAME
);
2126 // Flush all pending requests.
2127 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2128 base::MessageLoop::current()->RunUntilIdle();
2130 // Sorts out all the messages we saw by request.
2131 ResourceIPCAccumulator::ClassifiedMessages msgs
;
2132 accum_
.GetClassifiedMessages(&msgs
);
2134 // We should have gotten one RequestComplete message.
2135 ASSERT_EQ(1U, msgs
.size());
2136 ASSERT_EQ(1U, msgs
[0].size());
2137 EXPECT_EQ(ResourceMsg_RequestComplete::ID
, msgs
[0][0].type());
2139 // The RequestComplete message should have had the error code of
2140 // ERR_INVALID_RESPONSE.
2141 CheckRequestCompleteErrorCode(msgs
[0][0], net::ERR_INVALID_RESPONSE
);
2144 // Test for http://crbug.com/76202 . We don't want to destroy a
2145 // download request prematurely when processing a cancellation from
2147 TEST_F(ResourceDispatcherHostTest
, IgnoreCancelForDownloads
) {
2148 EXPECT_EQ(0, host_
.pending_requests());
2150 int render_view_id
= 0;
2153 std::string
raw_headers("HTTP\n"
2154 "Content-disposition: attachment; filename=foo\n\n");
2155 std::string
response_data("01234567890123456789\x01foobar");
2157 // Get past sniffing metrics in the BufferedResourceHandler. Note that
2158 // if we don't get past the sniffing metrics, the result will be that
2159 // the BufferedResourceHandler won't have figured out that it's a download,
2160 // won't have constructed a DownloadResourceHandler, and and the request
2161 // will be successfully canceled below, failing the test.
2162 response_data
.resize(1025, ' ');
2164 SetResponse(raw_headers
, response_data
);
2165 job_factory_
->SetDelayedCompleteJobGeneration(true);
2166 HandleScheme("http");
2168 MakeTestRequestWithResourceType(filter_
.get(), render_view_id
, request_id
,
2169 GURL("http://example.com/blah"),
2170 RESOURCE_TYPE_MAIN_FRAME
);
2171 // Return some data so that the request is identified as a download
2172 // and the proper resource handlers are created.
2173 EXPECT_TRUE(net::URLRequestTestJob::ProcessOnePendingMessage());
2175 // And now simulate a cancellation coming from the renderer.
2176 ResourceHostMsg_CancelRequest
msg(request_id
);
2177 host_
.OnMessageReceived(msg
, filter_
.get());
2179 // Since the request had already started processing as a download,
2180 // the cancellation above should have been ignored and the request
2181 // should still be alive.
2182 EXPECT_EQ(1, host_
.pending_requests());
2184 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2187 TEST_F(ResourceDispatcherHostTest
, CancelRequestsForContext
) {
2188 EXPECT_EQ(0, host_
.pending_requests());
2190 int render_view_id
= 0;
2193 std::string
raw_headers("HTTP\n"
2194 "Content-disposition: attachment; filename=foo\n\n");
2195 std::string
response_data("01234567890123456789\x01foobar");
2196 // Get past sniffing metrics.
2197 response_data
.resize(1025, ' ');
2199 SetResponse(raw_headers
, response_data
);
2200 job_factory_
->SetDelayedCompleteJobGeneration(true);
2201 HandleScheme("http");
2203 MakeTestRequestWithResourceType(filter_
.get(), render_view_id
, request_id
,
2204 GURL("http://example.com/blah"),
2205 RESOURCE_TYPE_MAIN_FRAME
);
2206 // Return some data so that the request is identified as a download
2207 // and the proper resource handlers are created.
2208 EXPECT_TRUE(net::URLRequestTestJob::ProcessOnePendingMessage());
2210 // And now simulate a cancellation coming from the renderer.
2211 ResourceHostMsg_CancelRequest
msg(request_id
);
2212 host_
.OnMessageReceived(msg
, filter_
.get());
2214 // Since the request had already started processing as a download,
2215 // the cancellation above should have been ignored and the request
2216 // should still be alive.
2217 EXPECT_EQ(1, host_
.pending_requests());
2219 // Cancelling by other methods shouldn't work either.
2220 host_
.CancelRequestsForProcess(render_view_id
);
2221 EXPECT_EQ(1, host_
.pending_requests());
2223 // Cancelling by context should work.
2224 host_
.CancelRequestsForContext(filter_
->resource_context());
2225 EXPECT_EQ(0, host_
.pending_requests());
2228 TEST_F(ResourceDispatcherHostTest
, CancelRequestsForContextDetached
) {
2229 EXPECT_EQ(0, host_
.pending_requests());
2231 int render_view_id
= 0;
2234 MakeTestRequestWithResourceType(filter_
.get(), render_view_id
, request_id
,
2235 net::URLRequestTestJob::test_url_4(),
2236 RESOURCE_TYPE_PREFETCH
); // detachable type
2238 // Simulate a cancel coming from the renderer.
2239 RendererCancelRequest(request_id
);
2241 // Since the request had already started processing as detachable,
2242 // the cancellation above should have been ignored and the request
2243 // should have been detached.
2244 EXPECT_EQ(1, host_
.pending_requests());
2246 // Cancelling by other methods should also leave it detached.
2247 host_
.CancelRequestsForProcess(render_view_id
);
2248 EXPECT_EQ(1, host_
.pending_requests());
2250 // Cancelling by context should work.
2251 host_
.CancelRequestsForContext(filter_
->resource_context());
2252 EXPECT_EQ(0, host_
.pending_requests());
2255 // Test the cancelling of requests that are being transferred to a new renderer
2256 // due to a redirection.
2257 TEST_F(ResourceDispatcherHostTest
, CancelRequestsForContextTransferred
) {
2258 EXPECT_EQ(0, host_
.pending_requests());
2260 int render_view_id
= 0;
2263 std::string
raw_headers("HTTP/1.1 200 OK\n"
2264 "Content-Type: text/html; charset=utf-8\n\n");
2265 std::string
response_data("<html>foobar</html>");
2267 SetResponse(raw_headers
, response_data
);
2268 HandleScheme("http");
2270 MakeTestRequestWithResourceType(filter_
.get(), render_view_id
, request_id
,
2271 GURL("http://example.com/blah"),
2272 RESOURCE_TYPE_MAIN_FRAME
);
2275 GlobalRequestID
global_request_id(filter_
->child_id(), request_id
);
2276 host_
.MarkAsTransferredNavigation(global_request_id
);
2278 // And now simulate a cancellation coming from the renderer.
2279 ResourceHostMsg_CancelRequest
msg(request_id
);
2280 host_
.OnMessageReceived(msg
, filter_
.get());
2282 // Since the request is marked as being transferred,
2283 // the cancellation above should have been ignored and the request
2284 // should still be alive.
2285 EXPECT_EQ(1, host_
.pending_requests());
2287 // Cancelling by other methods shouldn't work either.
2288 host_
.CancelRequestsForProcess(render_view_id
);
2289 EXPECT_EQ(1, host_
.pending_requests());
2291 // Cancelling by context should work.
2292 host_
.CancelRequestsForContext(filter_
->resource_context());
2293 EXPECT_EQ(0, host_
.pending_requests());
2296 // Test transferred navigations with text/html, which doesn't trigger any
2297 // content sniffing.
2298 TEST_F(ResourceDispatcherHostTest
, TransferNavigationHtml
) {
2299 // This test expects the cross site request to be leaked, so it can transfer
2300 // the request directly.
2301 CrossSiteResourceHandler::SetLeakRequestsForTesting(true);
2303 EXPECT_EQ(0, host_
.pending_requests());
2305 int render_view_id
= 0;
2308 // Configure initial request.
2309 SetResponse("HTTP/1.1 302 Found\n"
2310 "Location: http://other.com/blech\n\n");
2312 HandleScheme("http");
2314 // Temporarily replace ContentBrowserClient with one that will trigger the
2315 // transfer navigation code paths.
2316 TransfersAllNavigationsContentBrowserClient new_client
;
2317 ContentBrowserClient
* old_client
= SetBrowserClientForTesting(&new_client
);
2319 MakeTestRequestWithResourceType(filter_
.get(), render_view_id
, request_id
,
2320 GURL("http://example.com/blah"),
2321 RESOURCE_TYPE_MAIN_FRAME
);
2323 // Now that we're blocked on the redirect, update the response and unblock by
2324 // telling the AsyncResourceHandler to follow the redirect.
2325 const std::string kResponseBody
= "hello world";
2326 SetResponse("HTTP/1.1 200 OK\n"
2327 "Content-Type: text/html\n\n",
2329 ResourceHostMsg_FollowRedirect
redirect_msg(request_id
);
2330 host_
.OnMessageReceived(redirect_msg
, filter_
.get());
2331 base::MessageLoop::current()->RunUntilIdle();
2333 // Flush all the pending requests to get the response through the
2334 // BufferedResourceHandler.
2335 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2337 // Restore, now that we've set up a transfer.
2338 SetBrowserClientForTesting(old_client
);
2340 // This second filter is used to emulate a second process.
2341 scoped_refptr
<ForwardingFilter
> second_filter
= MakeForwardingFilter();
2343 int new_render_view_id
= 1;
2344 int new_request_id
= 2;
2346 ResourceHostMsg_Request request
=
2347 CreateResourceRequest("GET", RESOURCE_TYPE_MAIN_FRAME
,
2348 GURL("http://other.com/blech"));
2349 request
.transferred_request_child_id
= filter_
->child_id();
2350 request
.transferred_request_request_id
= request_id
;
2352 ResourceHostMsg_RequestResource
transfer_request_msg(
2353 new_render_view_id
, new_request_id
, request
);
2354 host_
.OnMessageReceived(transfer_request_msg
, second_filter
.get());
2355 base::MessageLoop::current()->RunUntilIdle();
2357 // Check generated messages.
2358 ResourceIPCAccumulator::ClassifiedMessages msgs
;
2359 accum_
.GetClassifiedMessages(&msgs
);
2361 ASSERT_EQ(2U, msgs
.size());
2362 EXPECT_EQ(ResourceMsg_ReceivedRedirect::ID
, msgs
[0][0].type());
2363 CheckSuccessfulRequest(msgs
[1], kResponseBody
);
2366 // Test transferring two navigations with text/html, to ensure the resource
2367 // accounting works.
2368 TEST_F(ResourceDispatcherHostTest
, TransferTwoNavigationsHtml
) {
2369 // This test expects the cross site request to be leaked, so it can transfer
2370 // the request directly.
2371 CrossSiteResourceHandler::SetLeakRequestsForTesting(true);
2373 EXPECT_EQ(0, host_
.pending_requests());
2375 int render_view_id
= 0;
2378 // Configure initial request.
2379 const std::string kResponseBody
= "hello world";
2380 SetResponse("HTTP/1.1 200 OK\n"
2381 "Content-Type: text/html\n\n",
2384 HandleScheme("http");
2386 // Temporarily replace ContentBrowserClient with one that will trigger the
2387 // transfer navigation code paths.
2388 TransfersAllNavigationsContentBrowserClient new_client
;
2389 ContentBrowserClient
* old_client
= SetBrowserClientForTesting(&new_client
);
2391 // Make the first request.
2392 MakeTestRequestWithResourceType(filter_
.get(), render_view_id
, request_id
,
2393 GURL("http://example.com/blah"),
2394 RESOURCE_TYPE_MAIN_FRAME
);
2396 // Make a second request from the same process.
2397 int second_request_id
= 2;
2398 MakeTestRequestWithResourceType(filter_
.get(), render_view_id
,
2400 GURL("http://example.com/foo"),
2401 RESOURCE_TYPE_MAIN_FRAME
);
2403 // Flush all the pending requests to get the response through the
2404 // BufferedResourceHandler.
2405 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2407 // Restore, now that we've set up a transfer.
2408 SetBrowserClientForTesting(old_client
);
2410 // This second filter is used to emulate a second process.
2411 scoped_refptr
<ForwardingFilter
> second_filter
= MakeForwardingFilter();
2413 // Transfer the first request.
2414 int new_render_view_id
= 1;
2415 int new_request_id
= 5;
2416 ResourceHostMsg_Request request
=
2417 CreateResourceRequest("GET", RESOURCE_TYPE_MAIN_FRAME
,
2418 GURL("http://example.com/blah"));
2419 request
.transferred_request_child_id
= filter_
->child_id();
2420 request
.transferred_request_request_id
= request_id
;
2422 ResourceHostMsg_RequestResource
transfer_request_msg(
2423 new_render_view_id
, new_request_id
, request
);
2424 host_
.OnMessageReceived(transfer_request_msg
, second_filter
.get());
2425 base::MessageLoop::current()->RunUntilIdle();
2427 // Transfer the second request.
2428 int new_second_request_id
= 6;
2429 ResourceHostMsg_Request second_request
=
2430 CreateResourceRequest("GET", RESOURCE_TYPE_MAIN_FRAME
,
2431 GURL("http://example.com/foo"));
2432 request
.transferred_request_child_id
= filter_
->child_id();
2433 request
.transferred_request_request_id
= second_request_id
;
2435 ResourceHostMsg_RequestResource
second_transfer_request_msg(
2436 new_render_view_id
, new_second_request_id
, second_request
);
2437 host_
.OnMessageReceived(second_transfer_request_msg
, second_filter
.get());
2438 base::MessageLoop::current()->RunUntilIdle();
2440 // Check generated messages.
2441 ResourceIPCAccumulator::ClassifiedMessages msgs
;
2442 accum_
.GetClassifiedMessages(&msgs
);
2444 ASSERT_EQ(2U, msgs
.size());
2445 CheckSuccessfulRequest(msgs
[0], kResponseBody
);
2448 // Test transferred navigations with text/plain, which causes
2449 // BufferedResourceHandler to buffer the response to sniff the content
2450 // before the transfer occurs.
2451 TEST_F(ResourceDispatcherHostTest
, TransferNavigationText
) {
2452 // This test expects the cross site request to be leaked, so it can transfer
2453 // the request directly.
2454 CrossSiteResourceHandler::SetLeakRequestsForTesting(true);
2456 EXPECT_EQ(0, host_
.pending_requests());
2458 int render_view_id
= 0;
2461 // Configure initial request.
2462 SetResponse("HTTP/1.1 302 Found\n"
2463 "Location: http://other.com/blech\n\n");
2465 HandleScheme("http");
2467 // Temporarily replace ContentBrowserClient with one that will trigger the
2468 // transfer navigation code paths.
2469 TransfersAllNavigationsContentBrowserClient new_client
;
2470 ContentBrowserClient
* old_client
= SetBrowserClientForTesting(&new_client
);
2472 MakeTestRequestWithResourceType(filter_
.get(), render_view_id
, request_id
,
2473 GURL("http://example.com/blah"),
2474 RESOURCE_TYPE_MAIN_FRAME
);
2476 // Now that we're blocked on the redirect, update the response and unblock by
2477 // telling the AsyncResourceHandler to follow the redirect. Use a text/plain
2478 // MIME type, which causes BufferedResourceHandler to buffer it before the
2480 const std::string kResponseBody
= "hello world";
2481 SetResponse("HTTP/1.1 200 OK\n"
2482 "Content-Type: text/plain\n\n",
2484 ResourceHostMsg_FollowRedirect
redirect_msg(request_id
);
2485 host_
.OnMessageReceived(redirect_msg
, filter_
.get());
2486 base::MessageLoop::current()->RunUntilIdle();
2488 // Flush all the pending requests to get the response through the
2489 // BufferedResourceHandler.
2490 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2492 // Restore, now that we've set up a transfer.
2493 SetBrowserClientForTesting(old_client
);
2495 // This second filter is used to emulate a second process.
2496 scoped_refptr
<ForwardingFilter
> second_filter
= MakeForwardingFilter();
2498 int new_render_view_id
= 1;
2499 int new_request_id
= 2;
2501 ResourceHostMsg_Request request
=
2502 CreateResourceRequest("GET", RESOURCE_TYPE_MAIN_FRAME
,
2503 GURL("http://other.com/blech"));
2504 request
.transferred_request_child_id
= filter_
->child_id();
2505 request
.transferred_request_request_id
= request_id
;
2507 ResourceHostMsg_RequestResource
transfer_request_msg(
2508 new_render_view_id
, new_request_id
, request
);
2509 host_
.OnMessageReceived(transfer_request_msg
, second_filter
.get());
2510 base::MessageLoop::current()->RunUntilIdle();
2512 // Check generated messages.
2513 ResourceIPCAccumulator::ClassifiedMessages msgs
;
2514 accum_
.GetClassifiedMessages(&msgs
);
2516 ASSERT_EQ(2U, msgs
.size());
2517 EXPECT_EQ(ResourceMsg_ReceivedRedirect::ID
, msgs
[0][0].type());
2518 CheckSuccessfulRequest(msgs
[1], kResponseBody
);
2521 TEST_F(ResourceDispatcherHostTest
, TransferNavigationWithProcessCrash
) {
2522 // This test expects the cross site request to be leaked, so it can transfer
2523 // the request directly.
2524 CrossSiteResourceHandler::SetLeakRequestsForTesting(true);
2526 EXPECT_EQ(0, host_
.pending_requests());
2528 int render_view_id
= 0;
2530 int first_child_id
= -1;
2532 // Configure initial request.
2533 SetResponse("HTTP/1.1 302 Found\n"
2534 "Location: http://other.com/blech\n\n");
2535 const std::string kResponseBody
= "hello world";
2537 HandleScheme("http");
2539 // Temporarily replace ContentBrowserClient with one that will trigger the
2540 // transfer navigation code paths.
2541 TransfersAllNavigationsContentBrowserClient new_client
;
2542 ContentBrowserClient
* old_client
= SetBrowserClientForTesting(&new_client
);
2544 // Create a first filter that can be deleted before the second one starts.
2546 scoped_refptr
<ForwardingFilter
> first_filter
= MakeForwardingFilter();
2547 first_child_id
= first_filter
->child_id();
2549 ResourceHostMsg_Request first_request
=
2550 CreateResourceRequest("GET", RESOURCE_TYPE_MAIN_FRAME
,
2551 GURL("http://example.com/blah"));
2553 ResourceHostMsg_RequestResource
first_request_msg(
2554 render_view_id
, request_id
, first_request
);
2555 host_
.OnMessageReceived(first_request_msg
, first_filter
.get());
2556 base::MessageLoop::current()->RunUntilIdle();
2558 // Now that we're blocked on the redirect, update the response and unblock
2559 // by telling the AsyncResourceHandler to follow the redirect.
2560 SetResponse("HTTP/1.1 200 OK\n"
2561 "Content-Type: text/html\n\n",
2563 ResourceHostMsg_FollowRedirect
redirect_msg(request_id
);
2564 host_
.OnMessageReceived(redirect_msg
, first_filter
.get());
2565 base::MessageLoop::current()->RunUntilIdle();
2567 // Flush all the pending requests to get the response through the
2568 // BufferedResourceHandler.
2569 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2571 // The first filter is now deleted, as if the child process died.
2574 SetBrowserClientForTesting(old_client
);
2576 // Make sure we don't hold onto the ResourceMessageFilter after it is deleted.
2577 GlobalRequestID
first_global_request_id(first_child_id
, request_id
);
2579 // This second filter is used to emulate a second process.
2580 scoped_refptr
<ForwardingFilter
> second_filter
= MakeForwardingFilter();
2582 int new_render_view_id
= 1;
2583 int new_request_id
= 2;
2585 ResourceHostMsg_Request request
=
2586 CreateResourceRequest("GET", RESOURCE_TYPE_MAIN_FRAME
,
2587 GURL("http://other.com/blech"));
2588 request
.transferred_request_child_id
= first_child_id
;
2589 request
.transferred_request_request_id
= request_id
;
2592 child_ids_
.insert(second_filter
->child_id());
2593 ResourceHostMsg_RequestResource
transfer_request_msg(
2594 new_render_view_id
, new_request_id
, request
);
2595 host_
.OnMessageReceived(transfer_request_msg
, second_filter
.get());
2596 base::MessageLoop::current()->RunUntilIdle();
2598 // Check generated messages.
2599 ResourceIPCAccumulator::ClassifiedMessages msgs
;
2600 accum_
.GetClassifiedMessages(&msgs
);
2602 ASSERT_EQ(2U, msgs
.size());
2603 EXPECT_EQ(ResourceMsg_ReceivedRedirect::ID
, msgs
[0][0].type());
2604 CheckSuccessfulRequest(msgs
[1], kResponseBody
);
2607 TEST_F(ResourceDispatcherHostTest
, TransferNavigationWithTwoRedirects
) {
2608 // This test expects the cross site request to be leaked, so it can transfer
2609 // the request directly.
2610 CrossSiteResourceHandler::SetLeakRequestsForTesting(true);
2612 EXPECT_EQ(0, host_
.pending_requests());
2614 int render_view_id
= 0;
2617 // Configure initial request.
2618 SetResponse("HTTP/1.1 302 Found\n"
2619 "Location: http://other.com/blech\n\n");
2621 HandleScheme("http");
2623 // Temporarily replace ContentBrowserClient with one that will trigger the
2624 // transfer navigation code paths.
2625 TransfersAllNavigationsContentBrowserClient new_client
;
2626 ContentBrowserClient
* old_client
= SetBrowserClientForTesting(&new_client
);
2628 MakeTestRequestWithResourceType(filter_
.get(), render_view_id
, request_id
,
2629 GURL("http://example.com/blah"),
2630 RESOURCE_TYPE_MAIN_FRAME
);
2632 // Now that we're blocked on the redirect, simulate hitting another redirect.
2633 SetResponse("HTTP/1.1 302 Found\n"
2634 "Location: http://other.com/blerg\n\n");
2635 ResourceHostMsg_FollowRedirect
redirect_msg(request_id
);
2636 host_
.OnMessageReceived(redirect_msg
, filter_
.get());
2637 base::MessageLoop::current()->RunUntilIdle();
2639 // Now that we're blocked on the second redirect, update the response and
2640 // unblock by telling the AsyncResourceHandler to follow the redirect.
2641 // Again, use text/plain to force BufferedResourceHandler to buffer before
2643 const std::string kResponseBody
= "hello world";
2644 SetResponse("HTTP/1.1 200 OK\n"
2645 "Content-Type: text/plain\n\n",
2647 ResourceHostMsg_FollowRedirect
redirect_msg2(request_id
);
2648 host_
.OnMessageReceived(redirect_msg2
, filter_
.get());
2649 base::MessageLoop::current()->RunUntilIdle();
2651 // Flush all the pending requests to get the response through the
2652 // BufferedResourceHandler.
2653 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2656 SetBrowserClientForTesting(old_client
);
2658 // This second filter is used to emulate a second process.
2659 scoped_refptr
<ForwardingFilter
> second_filter
= MakeForwardingFilter();
2661 int new_render_view_id
= 1;
2662 int new_request_id
= 2;
2664 ResourceHostMsg_Request request
=
2665 CreateResourceRequest("GET", RESOURCE_TYPE_MAIN_FRAME
,
2666 GURL("http://other.com/blech"));
2667 request
.transferred_request_child_id
= filter_
->child_id();
2668 request
.transferred_request_request_id
= request_id
;
2671 child_ids_
.insert(second_filter
->child_id());
2672 ResourceHostMsg_RequestResource
transfer_request_msg(
2673 new_render_view_id
, new_request_id
, request
);
2674 host_
.OnMessageReceived(transfer_request_msg
, second_filter
.get());
2676 // Verify that we update the ResourceRequestInfo.
2677 GlobalRequestID
global_request_id(second_filter
->child_id(), new_request_id
);
2678 const ResourceRequestInfoImpl
* info
= ResourceRequestInfoImpl::ForRequest(
2679 host_
.GetURLRequest(global_request_id
));
2680 EXPECT_EQ(second_filter
->child_id(), info
->GetChildID());
2681 EXPECT_EQ(new_render_view_id
, info
->GetRouteID());
2682 EXPECT_EQ(new_request_id
, info
->GetRequestID());
2683 EXPECT_EQ(second_filter
.get(), info
->filter());
2685 // Let request complete.
2686 base::MessageLoop::current()->RunUntilIdle();
2688 // Check generated messages.
2689 ResourceIPCAccumulator::ClassifiedMessages msgs
;
2690 accum_
.GetClassifiedMessages(&msgs
);
2692 ASSERT_EQ(2U, msgs
.size());
2693 EXPECT_EQ(ResourceMsg_ReceivedRedirect::ID
, msgs
[0][0].type());
2694 CheckSuccessfulRequest(msgs
[1], kResponseBody
);
2697 TEST_F(ResourceDispatcherHostTest
, UnknownURLScheme
) {
2698 EXPECT_EQ(0, host_
.pending_requests());
2700 HandleScheme("http");
2702 MakeTestRequestWithResourceType(filter_
.get(), 0, 1, GURL("foo://bar"),
2703 RESOURCE_TYPE_MAIN_FRAME
);
2705 // Flush all pending requests.
2706 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2708 // Sort all the messages we saw by request.
2709 ResourceIPCAccumulator::ClassifiedMessages msgs
;
2710 accum_
.GetClassifiedMessages(&msgs
);
2712 // We should have gotten one RequestComplete message.
2713 ASSERT_EQ(1U, msgs
[0].size());
2714 EXPECT_EQ(ResourceMsg_RequestComplete::ID
, msgs
[0][0].type());
2716 // The RequestComplete message should have the error code of
2717 // ERR_UNKNOWN_URL_SCHEME.
2718 CheckRequestCompleteErrorCode(msgs
[0][0], net::ERR_UNKNOWN_URL_SCHEME
);
2721 TEST_F(ResourceDispatcherHostTest
, DataReceivedACKs
) {
2722 EXPECT_EQ(0, host_
.pending_requests());
2724 SendDataReceivedACKs(true);
2726 HandleScheme("big-job");
2727 MakeTestRequest(0, 1, GURL("big-job:0123456789,1000000"));
2729 base::RunLoop().RunUntilIdle();
2731 // Sort all the messages we saw by request.
2732 ResourceIPCAccumulator::ClassifiedMessages msgs
;
2733 accum_
.GetClassifiedMessages(&msgs
);
2735 size_t size
= msgs
[0].size();
2737 EXPECT_EQ(ResourceMsg_ReceivedResponse::ID
, msgs
[0][0].type());
2738 EXPECT_EQ(ResourceMsg_SetDataBuffer::ID
, msgs
[0][1].type());
2739 for (size_t i
= 2; i
< size
- 1; ++i
)
2740 EXPECT_EQ(ResourceMsg_DataReceived::ID
, msgs
[0][i
].type());
2741 EXPECT_EQ(ResourceMsg_RequestComplete::ID
, msgs
[0][size
- 1].type());
2744 // Request a very large detachable resource and cancel part way. Some of the
2745 // data should have been sent to the renderer, but not all.
2746 TEST_F(ResourceDispatcherHostTest
, DataSentBeforeDetach
) {
2747 EXPECT_EQ(0, host_
.pending_requests());
2749 int render_view_id
= 0;
2752 std::string
raw_headers("HTTP\n"
2753 "Content-type: image/jpeg\n\n");
2754 std::string
response_data("01234567890123456789\x01foobar");
2756 // Create a response larger than kMaxAllocationSize (currently 32K). Note
2757 // that if this increase beyond 512K we'll need to make the response longer.
2758 const int kAllocSize
= 1024*512;
2759 response_data
.resize(kAllocSize
, ' ');
2761 SetResponse(raw_headers
, response_data
);
2762 job_factory_
->SetDelayedCompleteJobGeneration(true);
2763 HandleScheme("http");
2765 MakeTestRequestWithResourceType(filter_
.get(), render_view_id
, request_id
,
2766 GURL("http://example.com/blah"),
2767 RESOURCE_TYPE_PREFETCH
);
2769 // Get a bit of data before cancelling.
2770 EXPECT_TRUE(net::URLRequestTestJob::ProcessOnePendingMessage());
2772 // Simulate a cancellation coming from the renderer.
2773 ResourceHostMsg_CancelRequest
msg(request_id
);
2774 host_
.OnMessageReceived(msg
, filter_
.get());
2776 EXPECT_EQ(1, host_
.pending_requests());
2778 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2780 // Sort all the messages we saw by request.
2781 ResourceIPCAccumulator::ClassifiedMessages msgs
;
2782 accum_
.GetClassifiedMessages(&msgs
);
2784 EXPECT_EQ(4U, msgs
[0].size());
2786 // Figure out how many bytes were received by the renderer.
2790 ExtractDataOffsetAndLength(msgs
[0][2], &data_offset
, &data_length
));
2791 EXPECT_LT(0, data_length
);
2792 EXPECT_GT(kAllocSize
, data_length
);
2794 // Verify the data that was received before cancellation. The request should
2795 // have appeared to cancel, however.
2796 CheckSuccessfulRequestWithErrorCode(
2798 std::string(response_data
.begin(), response_data
.begin() + data_length
),
2802 TEST_F(ResourceDispatcherHostTest
, DelayedDataReceivedACKs
) {
2803 EXPECT_EQ(0, host_
.pending_requests());
2805 HandleScheme("big-job");
2806 MakeTestRequest(0, 1, GURL("big-job:0123456789,1000000"));
2808 base::RunLoop().RunUntilIdle();
2810 // Sort all the messages we saw by request.
2811 ResourceIPCAccumulator::ClassifiedMessages msgs
;
2812 accum_
.GetClassifiedMessages(&msgs
);
2814 // We expect 1x ReceivedResponse, 1x SetDataBuffer, Nx ReceivedData messages.
2815 EXPECT_EQ(ResourceMsg_ReceivedResponse::ID
, msgs
[0][0].type());
2816 EXPECT_EQ(ResourceMsg_SetDataBuffer::ID
, msgs
[0][1].type());
2817 for (size_t i
= 2; i
< msgs
[0].size(); ++i
)
2818 EXPECT_EQ(ResourceMsg_DataReceived::ID
, msgs
[0][i
].type());
2820 // NOTE: If we fail the above checks then it means that we probably didn't
2821 // load a big enough response to trigger the delay mechanism we are trying to
2824 msgs
[0].erase(msgs
[0].begin());
2825 msgs
[0].erase(msgs
[0].begin());
2827 // ACK all DataReceived messages until we find a RequestComplete message.
2828 bool complete
= false;
2830 for (size_t i
= 0; i
< msgs
[0].size(); ++i
) {
2831 if (msgs
[0][i
].type() == ResourceMsg_RequestComplete::ID
) {
2836 EXPECT_EQ(ResourceMsg_DataReceived::ID
, msgs
[0][i
].type());
2838 ResourceHostMsg_DataReceived_ACK
msg(1);
2839 host_
.OnMessageReceived(msg
, filter_
.get());
2842 base::MessageLoop::current()->RunUntilIdle();
2845 accum_
.GetClassifiedMessages(&msgs
);
2849 // Flakyness of this test might indicate memory corruption issues with
2850 // for example the ResourceBuffer of AsyncResourceHandler.
2851 TEST_F(ResourceDispatcherHostTest
, DataReceivedUnexpectedACKs
) {
2852 EXPECT_EQ(0, host_
.pending_requests());
2854 HandleScheme("big-job");
2855 MakeTestRequest(0, 1, GURL("big-job:0123456789,1000000"));
2857 base::RunLoop().RunUntilIdle();
2859 // Sort all the messages we saw by request.
2860 ResourceIPCAccumulator::ClassifiedMessages msgs
;
2861 accum_
.GetClassifiedMessages(&msgs
);
2863 // We expect 1x ReceivedResponse, 1x SetDataBuffer, Nx ReceivedData messages.
2864 EXPECT_EQ(ResourceMsg_ReceivedResponse::ID
, msgs
[0][0].type());
2865 EXPECT_EQ(ResourceMsg_SetDataBuffer::ID
, msgs
[0][1].type());
2866 for (size_t i
= 2; i
< msgs
[0].size(); ++i
)
2867 EXPECT_EQ(ResourceMsg_DataReceived::ID
, msgs
[0][i
].type());
2869 // NOTE: If we fail the above checks then it means that we probably didn't
2870 // load a big enough response to trigger the delay mechanism.
2872 // Send some unexpected ACKs.
2873 for (size_t i
= 0; i
< 128; ++i
) {
2874 ResourceHostMsg_DataReceived_ACK
msg(1);
2875 host_
.OnMessageReceived(msg
, filter_
.get());
2878 msgs
[0].erase(msgs
[0].begin());
2879 msgs
[0].erase(msgs
[0].begin());
2881 // ACK all DataReceived messages until we find a RequestComplete message.
2882 bool complete
= false;
2884 for (size_t i
= 0; i
< msgs
[0].size(); ++i
) {
2885 if (msgs
[0][i
].type() == ResourceMsg_RequestComplete::ID
) {
2890 EXPECT_EQ(ResourceMsg_DataReceived::ID
, msgs
[0][i
].type());
2892 ResourceHostMsg_DataReceived_ACK
msg(1);
2893 host_
.OnMessageReceived(msg
, filter_
.get());
2896 base::MessageLoop::current()->RunUntilIdle();
2899 accum_
.GetClassifiedMessages(&msgs
);
2903 // Tests the dispatcher host's temporary file management.
2904 TEST_F(ResourceDispatcherHostTest
, RegisterDownloadedTempFile
) {
2905 const int kRequestID
= 1;
2907 // Create a temporary file.
2908 base::FilePath file_path
;
2909 ASSERT_TRUE(base::CreateTemporaryFile(&file_path
));
2910 scoped_refptr
<ShareableFileReference
> deletable_file
=
2911 ShareableFileReference::GetOrCreate(
2913 ShareableFileReference::DELETE_ON_FINAL_RELEASE
,
2914 BrowserThread::GetMessageLoopProxyForThread(
2915 BrowserThread::FILE).get());
2918 EXPECT_FALSE(ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
2919 filter_
->child_id(), file_path
));
2921 // Register it for a resource request.
2922 host_
.RegisterDownloadedTempFile(filter_
->child_id(), kRequestID
, file_path
);
2924 // Should be readable now.
2925 EXPECT_TRUE(ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
2926 filter_
->child_id(), file_path
));
2928 // The child releases from the request.
2929 ResourceHostMsg_ReleaseDownloadedFile
release_msg(kRequestID
);
2930 host_
.OnMessageReceived(release_msg
, filter_
.get());
2932 // Still readable because there is another reference to the file. (The child
2933 // may take additional blob references.)
2934 EXPECT_TRUE(ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
2935 filter_
->child_id(), file_path
));
2937 // Release extra references and wait for the file to be deleted. (This relies
2938 // on the delete happening on the FILE thread which is mapped to main thread
2940 deletable_file
= NULL
;
2941 base::RunLoop().RunUntilIdle();
2943 // The file is no longer readable to the child and has been deleted.
2944 EXPECT_FALSE(ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
2945 filter_
->child_id(), file_path
));
2946 EXPECT_FALSE(base::PathExists(file_path
));
2949 // Tests that temporary files held on behalf of child processes are released
2950 // when the child process dies.
2951 TEST_F(ResourceDispatcherHostTest
, ReleaseTemporiesOnProcessExit
) {
2952 const int kRequestID
= 1;
2954 // Create a temporary file.
2955 base::FilePath file_path
;
2956 ASSERT_TRUE(base::CreateTemporaryFile(&file_path
));
2957 scoped_refptr
<ShareableFileReference
> deletable_file
=
2958 ShareableFileReference::GetOrCreate(
2960 ShareableFileReference::DELETE_ON_FINAL_RELEASE
,
2961 BrowserThread::GetMessageLoopProxyForThread(
2962 BrowserThread::FILE).get());
2964 // Register it for a resource request.
2965 host_
.RegisterDownloadedTempFile(filter_
->child_id(), kRequestID
, file_path
);
2966 deletable_file
= NULL
;
2968 // Should be readable now.
2969 EXPECT_TRUE(ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
2970 filter_
->child_id(), file_path
));
2972 // Let the process die.
2973 filter_
->OnChannelClosing();
2974 base::RunLoop().RunUntilIdle();
2976 // The file is no longer readable to the child and has been deleted.
2977 EXPECT_FALSE(ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
2978 filter_
->child_id(), file_path
));
2979 EXPECT_FALSE(base::PathExists(file_path
));
2982 TEST_F(ResourceDispatcherHostTest
, DownloadToFile
) {
2983 // Make a request which downloads to file.
2984 ResourceHostMsg_Request request
= CreateResourceRequest(
2985 "GET", RESOURCE_TYPE_SUB_RESOURCE
, net::URLRequestTestJob::test_url_1());
2986 request
.download_to_file
= true;
2987 ResourceHostMsg_RequestResource
request_msg(0, 1, request
);
2988 host_
.OnMessageReceived(request_msg
, filter_
.get());
2990 // Running the message loop until idle does not work because
2991 // RedirectToFileResourceHandler posts things to base::WorkerPool. Instead,
2992 // wait for the ResourceMsg_RequestComplete to go out. Then run the event loop
2993 // until idle so the loader is gone.
2994 WaitForRequestComplete();
2995 base::RunLoop().RunUntilIdle();
2996 EXPECT_EQ(0, host_
.pending_requests());
2998 ResourceIPCAccumulator::ClassifiedMessages msgs
;
2999 accum_
.GetClassifiedMessages(&msgs
);
3001 ASSERT_EQ(1U, msgs
.size());
3002 const std::vector
<IPC::Message
>& messages
= msgs
[0];
3004 // The request should contain the following messages:
3005 // ReceivedResponse (indicates headers received and filename)
3006 // DataDownloaded* (bytes downloaded and total length)
3007 // RequestComplete (request is done)
3010 ResourceResponseHead response_head
;
3011 GetResponseHead(messages
, &response_head
);
3012 ASSERT_FALSE(response_head
.download_file_path
.empty());
3015 size_t total_len
= 0;
3016 for (size_t i
= 1; i
< messages
.size() - 1; i
++) {
3017 ASSERT_EQ(ResourceMsg_DataDownloaded::ID
, messages
[i
].type());
3018 base::PickleIterator
iter(messages
[i
]);
3019 int request_id
, data_len
;
3020 ASSERT_TRUE(IPC::ReadParam(&messages
[i
], &iter
, &request_id
));
3021 ASSERT_TRUE(IPC::ReadParam(&messages
[i
], &iter
, &data_len
));
3022 total_len
+= data_len
;
3024 EXPECT_EQ(net::URLRequestTestJob::test_data_1().size(), total_len
);
3027 CheckRequestCompleteErrorCode(messages
.back(), net::OK
);
3029 // Verify that the data ended up in the temporary file.
3030 std::string contents
;
3031 ASSERT_TRUE(base::ReadFileToString(response_head
.download_file_path
,
3033 EXPECT_EQ(net::URLRequestTestJob::test_data_1(), contents
);
3035 // The file should be readable by the child.
3036 EXPECT_TRUE(ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
3037 filter_
->child_id(), response_head
.download_file_path
));
3039 // When the renderer releases the file, it should be deleted. Again,
3040 // RunUntilIdle doesn't work because base::WorkerPool is involved.
3041 ShareableFileReleaseWaiter
waiter(response_head
.download_file_path
);
3042 ResourceHostMsg_ReleaseDownloadedFile
release_msg(1);
3043 host_
.OnMessageReceived(release_msg
, filter_
.get());
3045 // The release callback runs before the delete is scheduled, so pump the
3046 // message loop for the delete itself. (This relies on the delete happening on
3047 // the FILE thread which is mapped to main thread in this test.)
3048 base::RunLoop().RunUntilIdle();
3050 EXPECT_FALSE(base::PathExists(response_head
.download_file_path
));
3051 EXPECT_FALSE(ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
3052 filter_
->child_id(), response_head
.download_file_path
));
3055 // Tests GetLoadInfoForAllRoutes when there are no pending requests.
3056 TEST_F(ResourceDispatcherHostTest
, LoadInfoNoRequests
) {
3057 scoped_ptr
<LoadInfoMap
> load_info_map
= RunLoadInfoTest(nullptr, 0);
3058 EXPECT_EQ(0u, load_info_map
->size());
3061 // Tests GetLoadInfoForAllRoutes when there are 3 requests from the same
3062 // RenderView. The second one is farthest along.
3063 TEST_F(ResourceDispatcherHostTest
, LoadInfo
) {
3064 const GlobalRoutingID
kId(filter_
->child_id(), 0);
3065 LoadInfoTestRequestInfo request_info
[] = {
3068 net::LOAD_STATE_SENDING_REQUEST
,
3069 net::UploadProgress(0, 0)},
3072 net::LOAD_STATE_READING_RESPONSE
,
3073 net::UploadProgress(0, 0)},
3076 net::LOAD_STATE_SENDING_REQUEST
,
3077 net::UploadProgress(0, 0)},
3079 scoped_ptr
<LoadInfoMap
> load_info_map
=
3080 RunLoadInfoTest(request_info
, arraysize(request_info
));
3081 ASSERT_EQ(1u, load_info_map
->size());
3082 ASSERT_TRUE(load_info_map
->find(kId
) != load_info_map
->end());
3083 EXPECT_EQ(GURL("test://2/"), (*load_info_map
)[kId
].url
);
3084 EXPECT_EQ(net::LOAD_STATE_READING_RESPONSE
,
3085 (*load_info_map
)[kId
].load_state
.state
);
3086 EXPECT_EQ(0u, (*load_info_map
)[kId
].upload_position
);
3087 EXPECT_EQ(0u, (*load_info_map
)[kId
].upload_size
);
3090 // Tests GetLoadInfoForAllRoutes when there are 2 requests with the same
3091 // priority. The first one (Which will have the lowest ID) should be returned.
3092 TEST_F(ResourceDispatcherHostTest
, LoadInfoSamePriority
) {
3093 const GlobalRoutingID
kId(filter_
->child_id(), 0);
3094 LoadInfoTestRequestInfo request_info
[] = {
3097 net::LOAD_STATE_IDLE
,
3098 net::UploadProgress(0, 0)},
3101 net::LOAD_STATE_IDLE
,
3102 net::UploadProgress(0, 0)},
3104 scoped_ptr
<LoadInfoMap
> load_info_map
=
3105 RunLoadInfoTest(request_info
, arraysize(request_info
));
3106 ASSERT_EQ(1u, load_info_map
->size());
3107 ASSERT_TRUE(load_info_map
->find(kId
) != load_info_map
->end());
3108 EXPECT_EQ(GURL("test://1/"), (*load_info_map
)[kId
].url
);
3109 EXPECT_EQ(net::LOAD_STATE_IDLE
, (*load_info_map
)[kId
].load_state
.state
);
3110 EXPECT_EQ(0u, (*load_info_map
)[kId
].upload_position
);
3111 EXPECT_EQ(0u, (*load_info_map
)[kId
].upload_size
);
3114 // Tests GetLoadInfoForAllRoutes when a request is uploading a body.
3115 TEST_F(ResourceDispatcherHostTest
, LoadInfoUploadProgress
) {
3116 const GlobalRoutingID
kId(filter_
->child_id(), 0);
3117 LoadInfoTestRequestInfo request_info
[] = {
3120 net::LOAD_STATE_READING_RESPONSE
,
3121 net::UploadProgress(0, 0)},
3124 net::LOAD_STATE_READING_RESPONSE
,
3125 net::UploadProgress(1000, 1000)},
3128 net::LOAD_STATE_SENDING_REQUEST
,
3129 net::UploadProgress(50, 100)},
3132 net::LOAD_STATE_READING_RESPONSE
,
3133 net::UploadProgress(1000, 1000)},
3136 net::LOAD_STATE_READING_RESPONSE
,
3137 net::UploadProgress(0, 0)},
3139 scoped_ptr
<LoadInfoMap
> load_info_map
=
3140 RunLoadInfoTest(request_info
, arraysize(request_info
));
3141 ASSERT_EQ(1u, load_info_map
->size());
3142 ASSERT_TRUE(load_info_map
->find(kId
) != load_info_map
->end());
3143 EXPECT_EQ(GURL("test://2/"), (*load_info_map
)[kId
].url
);
3144 EXPECT_EQ(net::LOAD_STATE_SENDING_REQUEST
,
3145 (*load_info_map
)[kId
].load_state
.state
);
3146 EXPECT_EQ(50u, (*load_info_map
)[kId
].upload_position
);
3147 EXPECT_EQ(100u, (*load_info_map
)[kId
].upload_size
);
3150 // Tests GetLoadInfoForAllRoutes when there are 4 requests from 2 different
3151 // RenderViews. Also tests the case where the first / last requests are the
3152 // most interesting ones.
3153 TEST_F(ResourceDispatcherHostTest
, LoadInfoTwoRenderViews
) {
3154 const GlobalRoutingID
kId1(filter_
->child_id(), 0);
3155 const GlobalRoutingID
kId2(filter_
->child_id(), 1);
3156 LoadInfoTestRequestInfo request_info
[] = {
3159 net::LOAD_STATE_CONNECTING
,
3160 net::UploadProgress(0, 0)},
3163 net::LOAD_STATE_IDLE
,
3164 net::UploadProgress(0, 0)},
3167 net::LOAD_STATE_IDLE
,
3168 net::UploadProgress(0, 0)},
3171 net::LOAD_STATE_CONNECTING
,
3172 net::UploadProgress(0, 0)},
3174 scoped_ptr
<LoadInfoMap
> load_info_map
=
3175 RunLoadInfoTest(request_info
, arraysize(request_info
));
3176 ASSERT_EQ(2u, load_info_map
->size());
3178 ASSERT_TRUE(load_info_map
->find(kId1
) != load_info_map
->end());
3179 EXPECT_EQ(GURL("test://1/"), (*load_info_map
)[kId1
].url
);
3180 EXPECT_EQ(net::LOAD_STATE_CONNECTING
,
3181 (*load_info_map
)[kId1
].load_state
.state
);
3182 EXPECT_EQ(0u, (*load_info_map
)[kId1
].upload_position
);
3183 EXPECT_EQ(0u, (*load_info_map
)[kId1
].upload_size
);
3185 ASSERT_TRUE(load_info_map
->find(kId2
) != load_info_map
->end());
3186 EXPECT_EQ(GURL("test://4/"), (*load_info_map
)[kId2
].url
);
3187 EXPECT_EQ(net::LOAD_STATE_CONNECTING
,
3188 (*load_info_map
)[kId2
].load_state
.state
);
3189 EXPECT_EQ(0u, (*load_info_map
)[kId2
].upload_position
);
3190 EXPECT_EQ(0u, (*load_info_map
)[kId2
].upload_size
);
3193 net::URLRequestJob
* TestURLRequestJobFactory::MaybeCreateJobWithProtocolHandler(
3194 const std::string
& scheme
,
3195 net::URLRequest
* request
,
3196 net::NetworkDelegate
* network_delegate
) const {
3197 url_request_jobs_created_count_
++;
3198 if (test_fixture_
->wait_for_request_create_loop_
)
3199 test_fixture_
->wait_for_request_create_loop_
->Quit();
3200 if (test_fixture_
->loader_test_request_info_
) {
3201 DCHECK_EQ(test_fixture_
->loader_test_request_info_
->url
, request
->url());
3202 scoped_ptr
<LoadInfoTestRequestInfo
> info
=
3203 test_fixture_
->loader_test_request_info_
.Pass();
3204 return new URLRequestLoadInfoJob(request
, network_delegate
,
3205 info
->load_state
, info
->upload_progress
);
3207 if (test_fixture_
->response_headers_
.empty()) {
3209 return new URLRequestTestDelayedStartJob(request
, network_delegate
);
3210 } else if (delay_complete_
) {
3211 return new URLRequestTestDelayedCompletionJob(request
,
3213 } else if (network_start_notification_
) {
3214 return new URLRequestTestDelayedNetworkJob(request
, network_delegate
);
3215 } else if (scheme
== "big-job") {
3216 return new URLRequestBigJob(request
, network_delegate
);
3218 return new net::URLRequestTestJob(request
, network_delegate
);
3222 return new URLRequestTestDelayedStartJob(
3223 request
, network_delegate
,
3224 test_fixture_
->response_headers_
, test_fixture_
->response_data_
,
3226 } else if (delay_complete_
) {
3227 return new URLRequestTestDelayedCompletionJob(
3228 request
, network_delegate
,
3229 test_fixture_
->response_headers_
, test_fixture_
->response_data_
,
3232 return new net::URLRequestTestJob(
3233 request
, network_delegate
,
3234 test_fixture_
->response_headers_
, test_fixture_
->response_data_
,
3240 net::URLRequestJob
* TestURLRequestJobFactory::MaybeInterceptRedirect(
3241 net::URLRequest
* request
,
3242 net::NetworkDelegate
* network_delegate
,
3243 const GURL
& location
) const {
3247 net::URLRequestJob
* TestURLRequestJobFactory::MaybeInterceptResponse(
3248 net::URLRequest
* request
,
3249 net::NetworkDelegate
* network_delegate
) const {
3253 } // namespace content