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/memory/scoped_vector.h"
12 #include "base/memory/shared_memory.h"
13 #include "base/message_loop/message_loop.h"
14 #include "base/pickle.h"
15 #include "base/run_loop.h"
16 #include "base/strings/string_number_conversions.h"
17 #include "base/strings/string_split.h"
18 #include "content/browser/browser_thread_impl.h"
19 #include "content/browser/child_process_security_policy_impl.h"
20 #include "content/browser/loader/cross_site_resource_handler.h"
21 #include "content/browser/loader/detachable_resource_handler.h"
22 #include "content/browser/loader/resource_dispatcher_host_impl.h"
23 #include "content/browser/loader/resource_loader.h"
24 #include "content/browser/loader/resource_message_filter.h"
25 #include "content/browser/loader/resource_request_info_impl.h"
26 #include "content/common/appcache_interfaces.h"
27 #include "content/common/child_process_host_impl.h"
28 #include "content/common/resource_messages.h"
29 #include "content/common/view_messages.h"
30 #include "content/public/browser/global_request_id.h"
31 #include "content/public/browser/resource_context.h"
32 #include "content/public/browser/resource_dispatcher_host_delegate.h"
33 #include "content/public/browser/resource_request_info.h"
34 #include "content/public/browser/resource_throttle.h"
35 #include "content/public/common/process_type.h"
36 #include "content/public/common/resource_response.h"
37 #include "content/public/test/test_browser_context.h"
38 #include "content/public/test/test_browser_thread_bundle.h"
39 #include "content/test/test_content_browser_client.h"
40 #include "net/base/elements_upload_data_stream.h"
41 #include "net/base/net_errors.h"
42 #include "net/base/request_priority.h"
43 #include "net/base/upload_bytes_element_reader.h"
44 #include "net/http/http_util.h"
45 #include "net/url_request/url_request.h"
46 #include "net/url_request/url_request_context.h"
47 #include "net/url_request/url_request_job.h"
48 #include "net/url_request/url_request_job_factory.h"
49 #include "net/url_request/url_request_simple_job.h"
50 #include "net/url_request/url_request_test_job.h"
51 #include "net/url_request/url_request_test_util.h"
52 #include "storage/browser/blob/shareable_file_reference.h"
53 #include "testing/gtest/include/gtest/gtest.h"
55 // TODO(eroman): Write unit tests for SafeBrowsing that exercise
56 // SafeBrowsingResourceHandler.
58 using storage::ShareableFileReference
;
64 // Returns the resource response header structure for this request.
65 void GetResponseHead(const std::vector
<IPC::Message
>& messages
,
66 ResourceResponseHead
* response_head
) {
67 ASSERT_GE(messages
.size(), 2U);
69 // The first messages should be received response.
70 ASSERT_EQ(ResourceMsg_ReceivedResponse::ID
, messages
[0].type());
72 PickleIterator
iter(messages
[0]);
74 ASSERT_TRUE(IPC::ReadParam(&messages
[0], &iter
, &request_id
));
75 ASSERT_TRUE(IPC::ReadParam(&messages
[0], &iter
, response_head
));
78 void GenerateIPCMessage(
79 scoped_refptr
<ResourceMessageFilter
> filter
,
80 scoped_ptr
<IPC::Message
> message
) {
81 ResourceDispatcherHostImpl::Get()->OnMessageReceived(
82 *message
, filter
.get());
85 // On Windows, ResourceMsg_SetDataBuffer supplies a HANDLE which is not
86 // automatically released.
88 // See ResourceDispatcher::ReleaseResourcesInDataMessage.
90 // TODO(davidben): It would be nice if the behavior for base::SharedMemoryHandle
91 // were more like it is in POSIX where the received fds are tracked in a
92 // ref-counted core that closes them if not extracted.
93 void ReleaseHandlesInMessage(const IPC::Message
& message
) {
94 if (message
.type() == ResourceMsg_SetDataBuffer::ID
) {
95 PickleIterator
iter(message
);
97 CHECK(iter
.ReadInt(&request_id
));
98 base::SharedMemoryHandle shm_handle
;
99 if (IPC::ParamTraits
<base::SharedMemoryHandle
>::Read(&message
,
102 if (base::SharedMemory::IsHandleValid(shm_handle
))
103 base::SharedMemory::CloseHandle(shm_handle
);
110 static int RequestIDForMessage(const IPC::Message
& msg
) {
112 switch (msg
.type()) {
113 case ResourceMsg_UploadProgress::ID
:
114 case ResourceMsg_ReceivedResponse::ID
:
115 case ResourceMsg_ReceivedRedirect::ID
:
116 case ResourceMsg_SetDataBuffer::ID
:
117 case ResourceMsg_DataReceived::ID
:
118 case ResourceMsg_DataDownloaded::ID
:
119 case ResourceMsg_RequestComplete::ID
: {
120 bool result
= PickleIterator(msg
).ReadInt(&request_id
);
128 static ResourceHostMsg_Request
CreateResourceRequest(const char* method
,
131 ResourceHostMsg_Request request
;
132 request
.method
= std::string(method
);
134 request
.first_party_for_cookies
= url
; // bypass third-party cookie blocking
135 request
.referrer_policy
= blink::WebReferrerPolicyDefault
;
136 request
.load_flags
= 0;
137 request
.origin_pid
= 0;
138 request
.resource_type
= type
;
139 request
.request_context
= 0;
140 request
.appcache_host_id
= kAppCacheNoHostId
;
141 request
.download_to_file
= false;
142 request
.should_reset_appcache
= false;
143 request
.is_main_frame
= true;
144 request
.parent_is_main_frame
= false;
145 request
.parent_render_frame_id
= -1;
146 request
.transition_type
= ui::PAGE_TRANSITION_LINK
;
147 request
.allow_download
= true;
151 // Spin up the message loop to kick off the request.
152 static void KickOffRequest() {
153 base::MessageLoop::current()->RunUntilIdle();
156 // We may want to move this to a shared space if it is useful for something else
157 class ResourceIPCAccumulator
{
159 ~ResourceIPCAccumulator() {
160 for (size_t i
= 0; i
< messages_
.size(); i
++) {
161 ReleaseHandlesInMessage(messages_
[i
]);
165 // On Windows, takes ownership of SharedMemoryHandles in |msg|.
166 void AddMessage(const IPC::Message
& msg
) {
167 messages_
.push_back(msg
);
170 // This groups the messages by their request ID. The groups will be in order
171 // that the first message for each request ID was received, and the messages
172 // within the groups will be in the order that they appeared.
173 // Note that this clears messages_. The caller takes ownership of any
174 // SharedMemoryHandles in messages placed into |msgs|.
175 typedef std::vector
< std::vector
<IPC::Message
> > ClassifiedMessages
;
176 void GetClassifiedMessages(ClassifiedMessages
* msgs
);
179 std::vector
<IPC::Message
> messages_
;
182 // This is very inefficient as a result of repeatedly extracting the ID, use
184 void ResourceIPCAccumulator::GetClassifiedMessages(ClassifiedMessages
* msgs
) {
185 while (!messages_
.empty()) {
186 // Ignore unknown message types as it is valid for code to generated other
187 // IPCs as side-effects that we are not testing here.
188 int cur_id
= RequestIDForMessage(messages_
[0]);
190 std::vector
<IPC::Message
> cur_requests
;
191 cur_requests
.push_back(messages_
[0]);
192 // find all other messages with this ID
193 for (int i
= 1; i
< static_cast<int>(messages_
.size()); i
++) {
194 int id
= RequestIDForMessage(messages_
[i
]);
196 cur_requests
.push_back(messages_
[i
]);
197 messages_
.erase(messages_
.begin() + i
);
201 msgs
->push_back(cur_requests
);
203 messages_
.erase(messages_
.begin());
207 // This is used to emulate different sub-processes, since this filter will
208 // have a different ID than the original.
209 class TestFilter
: public ResourceMessageFilter
{
211 explicit TestFilter(ResourceContext
* resource_context
)
212 : ResourceMessageFilter(
213 ChildProcessHostImpl::GenerateChildProcessUniqueId(),
214 PROCESS_TYPE_RENDERER
, NULL
, NULL
, NULL
, NULL
, NULL
,
215 base::Bind(&TestFilter::GetContexts
, base::Unretained(this))),
216 resource_context_(resource_context
),
218 received_after_canceled_(0) {
219 ChildProcessSecurityPolicyImpl::GetInstance()->Add(child_id());
220 set_peer_process_for_testing(base::Process::Current());
223 void set_canceled(bool canceled
) { canceled_
= canceled
; }
224 int received_after_canceled() const { return received_after_canceled_
; }
226 // ResourceMessageFilter override
227 bool Send(IPC::Message
* msg
) override
{
228 // No messages should be received when the process has been canceled.
230 received_after_canceled_
++;
231 ReleaseHandlesInMessage(*msg
);
236 ResourceContext
* resource_context() { return resource_context_
; }
239 ~TestFilter() override
{}
242 void GetContexts(const ResourceHostMsg_Request
& request
,
243 ResourceContext
** resource_context
,
244 net::URLRequestContext
** request_context
) {
245 *resource_context
= resource_context_
;
246 *request_context
= resource_context_
->GetRequestContext();
249 ResourceContext
* resource_context_
;
251 int received_after_canceled_
;
253 DISALLOW_COPY_AND_ASSIGN(TestFilter
);
257 // This class forwards the incoming messages to the ResourceDispatcherHostTest.
258 // For the test, we want all the incoming messages to go to the same place,
259 // which is why this forwards.
260 class ForwardingFilter
: public TestFilter
{
262 explicit ForwardingFilter(IPC::Sender
* dest
,
263 ResourceContext
* resource_context
)
264 : TestFilter(resource_context
),
268 // TestFilter override
269 bool Send(IPC::Message
* msg
) override
{ return dest_
->Send(msg
); }
272 ~ForwardingFilter() override
{}
276 DISALLOW_COPY_AND_ASSIGN(ForwardingFilter
);
279 // This class is a variation on URLRequestTestJob that will call
280 // URLRequest::WillStartUsingNetwork before starting.
281 class URLRequestTestDelayedNetworkJob
: public net::URLRequestTestJob
{
283 URLRequestTestDelayedNetworkJob(net::URLRequest
* request
,
284 net::NetworkDelegate
* network_delegate
)
285 : net::URLRequestTestJob(request
, network_delegate
) {}
287 // Only start if not deferred for network start.
288 void Start() override
{
290 NotifyBeforeNetworkStart(&defer
);
293 net::URLRequestTestJob::Start();
296 void ResumeNetworkStart() override
{ net::URLRequestTestJob::StartAsync(); }
299 ~URLRequestTestDelayedNetworkJob() override
{}
301 DISALLOW_COPY_AND_ASSIGN(URLRequestTestDelayedNetworkJob
);
304 // This class is a variation on URLRequestTestJob in that it does
305 // not complete start upon entry, only when specifically told to.
306 class URLRequestTestDelayedStartJob
: public net::URLRequestTestJob
{
308 URLRequestTestDelayedStartJob(net::URLRequest
* request
,
309 net::NetworkDelegate
* network_delegate
)
310 : net::URLRequestTestJob(request
, network_delegate
) {
313 URLRequestTestDelayedStartJob(net::URLRequest
* request
,
314 net::NetworkDelegate
* network_delegate
,
316 : net::URLRequestTestJob(request
, network_delegate
, auto_advance
) {
319 URLRequestTestDelayedStartJob(net::URLRequest
* request
,
320 net::NetworkDelegate
* network_delegate
,
321 const std::string
& response_headers
,
322 const std::string
& response_data
,
324 : net::URLRequestTestJob(request
,
332 // Do nothing until you're told to.
333 void Start() override
{}
335 // Finish starting a URL request whose job is an instance of
336 // URLRequestTestDelayedStartJob. It is illegal to call this routine
337 // with a URLRequest that does not use URLRequestTestDelayedStartJob.
338 static void CompleteStart(net::URLRequest
* request
) {
339 for (URLRequestTestDelayedStartJob
* job
= list_head_
;
342 if (job
->request() == request
) {
343 job
->net::URLRequestTestJob::Start();
350 static bool DelayedStartQueueEmpty() {
354 static void ClearQueue() {
357 << "Unreleased entries on URLRequestTestDelayedStartJob delay queue"
358 << "; may result in leaks.";
364 ~URLRequestTestDelayedStartJob() override
{
365 for (URLRequestTestDelayedStartJob
** job
= &list_head_
; *job
;
366 job
= &(*job
)->next_
) {
368 *job
= (*job
)->next_
;
381 static URLRequestTestDelayedStartJob
* list_head_
;
382 URLRequestTestDelayedStartJob
* next_
;
385 URLRequestTestDelayedStartJob
*
386 URLRequestTestDelayedStartJob::list_head_
= NULL
;
388 // This class is a variation on URLRequestTestJob in that it
389 // returns IO_pending errors before every read, not just the first one.
390 class URLRequestTestDelayedCompletionJob
: public net::URLRequestTestJob
{
392 URLRequestTestDelayedCompletionJob(net::URLRequest
* request
,
393 net::NetworkDelegate
* network_delegate
)
394 : net::URLRequestTestJob(request
, network_delegate
) {}
395 URLRequestTestDelayedCompletionJob(net::URLRequest
* request
,
396 net::NetworkDelegate
* network_delegate
,
398 : net::URLRequestTestJob(request
, network_delegate
, auto_advance
) {}
399 URLRequestTestDelayedCompletionJob(net::URLRequest
* request
,
400 net::NetworkDelegate
* network_delegate
,
401 const std::string
& response_headers
,
402 const std::string
& response_data
,
404 : net::URLRequestTestJob(request
,
411 ~URLRequestTestDelayedCompletionJob() override
{}
414 bool NextReadAsync() override
{ return true; }
417 class URLRequestBigJob
: public net::URLRequestSimpleJob
{
419 URLRequestBigJob(net::URLRequest
* request
,
420 net::NetworkDelegate
* network_delegate
)
421 : net::URLRequestSimpleJob(request
, network_delegate
) {
424 // URLRequestSimpleJob implementation:
425 int GetData(std::string
* mime_type
,
426 std::string
* charset
,
428 const net::CompletionCallback
& callback
) const override
{
429 *mime_type
= "text/plain";
434 if (!ParseURL(request_
->url(), &text
, &count
))
435 return net::ERR_INVALID_URL
;
437 data
->reserve(text
.size() * count
);
438 for (int i
= 0; i
< count
; ++i
)
444 base::TaskRunner
* GetTaskRunner() const override
{
445 return base::MessageLoopProxy::current().get();
449 ~URLRequestBigJob() override
{}
451 // big-job:substring,N
452 static bool ParseURL(const GURL
& url
, std::string
* text
, int* count
) {
453 std::vector
<std::string
> parts
;
454 base::SplitString(url
.path(), ',', &parts
);
456 if (parts
.size() != 2)
460 return base::StringToInt(parts
[1], count
);
464 // URLRequestJob used to test GetLoadInfoForAllRoutes. The LoadState and
465 // UploadProgress values are set for the jobs at the time of creation, and
466 // the jobs will never actually do anything.
467 class URLRequestLoadInfoJob
: public net::URLRequestJob
{
469 URLRequestLoadInfoJob(net::URLRequest
* request
,
470 net::NetworkDelegate
* network_delegate
,
471 const net::LoadState
& load_state
,
472 const net::UploadProgress
& upload_progress
)
473 : net::URLRequestJob(request
, network_delegate
),
474 load_state_(load_state
),
475 upload_progress_(upload_progress
) {}
477 // net::URLRequestJob implementation:
478 void Start() override
{}
479 net::LoadState
GetLoadState() const override
{ return load_state_
; }
480 net::UploadProgress
GetUploadProgress() const override
{
481 return upload_progress_
;
485 ~URLRequestLoadInfoJob() override
{}
487 // big-job:substring,N
488 static bool ParseURL(const GURL
& url
, std::string
* text
, int* count
) {
489 std::vector
<std::string
> parts
;
490 base::SplitString(url
.path(), ',', &parts
);
492 if (parts
.size() != 2)
496 return base::StringToInt(parts
[1], count
);
499 const net::LoadState load_state_
;
500 const net::UploadProgress upload_progress_
;
503 class ResourceDispatcherHostTest
;
505 class TestURLRequestJobFactory
: public net::URLRequestJobFactory
{
507 explicit TestURLRequestJobFactory(ResourceDispatcherHostTest
* test_fixture
)
508 : test_fixture_(test_fixture
),
510 delay_complete_(false),
511 network_start_notification_(false),
512 url_request_jobs_created_count_(0) {
515 void HandleScheme(const std::string
& scheme
) {
516 supported_schemes_
.insert(scheme
);
519 int url_request_jobs_created_count() const {
520 return url_request_jobs_created_count_
;
523 void SetDelayedStartJobGeneration(bool delay_job_start
) {
524 delay_start_
= delay_job_start
;
527 void SetDelayedCompleteJobGeneration(bool delay_job_complete
) {
528 delay_complete_
= delay_job_complete
;
531 void SetNetworkStartNotificationJobGeneration(bool notification
) {
532 network_start_notification_
= notification
;
535 net::URLRequestJob
* MaybeCreateJobWithProtocolHandler(
536 const std::string
& scheme
,
537 net::URLRequest
* request
,
538 net::NetworkDelegate
* network_delegate
) const override
;
540 net::URLRequestJob
* MaybeInterceptRedirect(
541 net::URLRequest
* request
,
542 net::NetworkDelegate
* network_delegate
,
543 const GURL
& location
) const override
;
545 net::URLRequestJob
* MaybeInterceptResponse(
546 net::URLRequest
* request
,
547 net::NetworkDelegate
* network_delegate
) const override
;
549 bool IsHandledProtocol(const std::string
& scheme
) const override
{
550 return supported_schemes_
.count(scheme
) > 0;
553 bool IsHandledURL(const GURL
& url
) const override
{
554 return supported_schemes_
.count(url
.scheme()) > 0;
557 bool IsSafeRedirectTarget(const GURL
& location
) const override
{
562 ResourceDispatcherHostTest
* test_fixture_
;
564 bool delay_complete_
;
565 bool network_start_notification_
;
566 mutable int url_request_jobs_created_count_
;
567 std::set
<std::string
> supported_schemes_
;
569 DISALLOW_COPY_AND_ASSIGN(TestURLRequestJobFactory
);
572 // Associated with an URLRequest to determine if the URLRequest gets deleted.
573 class TestUserData
: public base::SupportsUserData::Data
{
575 explicit TestUserData(bool* was_deleted
)
576 : was_deleted_(was_deleted
) {
579 ~TestUserData() override
{ *was_deleted_
= true; }
585 class TransfersAllNavigationsContentBrowserClient
586 : public TestContentBrowserClient
{
588 bool ShouldSwapProcessesForRedirect(ResourceContext
* resource_context
,
589 const GURL
& current_url
,
590 const GURL
& new_url
) override
{
595 enum GenericResourceThrottleFlags
{
597 DEFER_STARTING_REQUEST
= 1 << 0,
598 DEFER_PROCESSING_RESPONSE
= 1 << 1,
599 CANCEL_BEFORE_START
= 1 << 2,
600 DEFER_NETWORK_START
= 1 << 3
603 // Throttle that tracks the current throttle blocking a request. Only one
604 // can throttle any request at a time.
605 class GenericResourceThrottle
: public ResourceThrottle
{
607 // The value is used to indicate that the throttle should not provide
608 // a error code when cancelling a request. net::OK is used, because this
609 // is not an error code.
610 static const int USE_DEFAULT_CANCEL_ERROR_CODE
= net::OK
;
612 GenericResourceThrottle(int flags
, int code
)
614 error_code_for_cancellation_(code
) {
617 ~GenericResourceThrottle() override
{
618 if (active_throttle_
== this)
619 active_throttle_
= NULL
;
622 // ResourceThrottle implementation:
623 void WillStartRequest(bool* defer
) override
{
624 ASSERT_EQ(NULL
, active_throttle_
);
625 if (flags_
& DEFER_STARTING_REQUEST
) {
626 active_throttle_
= this;
630 if (flags_
& CANCEL_BEFORE_START
) {
631 if (error_code_for_cancellation_
== USE_DEFAULT_CANCEL_ERROR_CODE
) {
632 controller()->Cancel();
634 controller()->CancelWithError(error_code_for_cancellation_
);
639 void WillProcessResponse(bool* defer
) override
{
640 ASSERT_EQ(NULL
, active_throttle_
);
641 if (flags_
& DEFER_PROCESSING_RESPONSE
) {
642 active_throttle_
= this;
647 void WillStartUsingNetwork(bool* defer
) override
{
648 ASSERT_EQ(NULL
, active_throttle_
);
650 if (flags_
& DEFER_NETWORK_START
) {
651 active_throttle_
= this;
656 const char* GetNameForLogging() const override
{
657 return "GenericResourceThrottle";
661 ASSERT_TRUE(this == active_throttle_
);
662 active_throttle_
= NULL
;
663 controller()->Resume();
666 static GenericResourceThrottle
* active_throttle() {
667 return active_throttle_
;
671 int flags_
; // bit-wise union of GenericResourceThrottleFlags.
672 int error_code_for_cancellation_
;
674 // The currently active throttle, if any.
675 static GenericResourceThrottle
* active_throttle_
;
678 GenericResourceThrottle
* GenericResourceThrottle::active_throttle_
= NULL
;
680 class TestResourceDispatcherHostDelegate
681 : public ResourceDispatcherHostDelegate
{
683 TestResourceDispatcherHostDelegate()
684 : create_two_throttles_(false),
686 error_code_for_cancellation_(
687 GenericResourceThrottle::USE_DEFAULT_CANCEL_ERROR_CODE
) {
690 void set_url_request_user_data(base::SupportsUserData::Data
* user_data
) {
691 user_data_
.reset(user_data
);
694 void set_flags(int value
) {
698 void set_error_code_for_cancellation(int code
) {
699 error_code_for_cancellation_
= code
;
702 void set_create_two_throttles(bool create_two_throttles
) {
703 create_two_throttles_
= create_two_throttles
;
706 // ResourceDispatcherHostDelegate implementation:
708 void RequestBeginning(net::URLRequest
* request
,
709 ResourceContext
* resource_context
,
710 AppCacheService
* appcache_service
,
711 ResourceType resource_type
,
712 ScopedVector
<ResourceThrottle
>* throttles
) override
{
714 const void* key
= user_data_
.get();
715 request
->SetUserData(key
, user_data_
.release());
718 if (flags_
!= NONE
) {
719 throttles
->push_back(new GenericResourceThrottle(
720 flags_
, error_code_for_cancellation_
));
721 if (create_two_throttles_
)
722 throttles
->push_back(new GenericResourceThrottle(
723 flags_
, error_code_for_cancellation_
));
728 bool create_two_throttles_
;
730 int error_code_for_cancellation_
;
731 scoped_ptr
<base::SupportsUserData::Data
> user_data_
;
734 // Waits for a ShareableFileReference to be released.
735 class ShareableFileReleaseWaiter
{
737 ShareableFileReleaseWaiter(const base::FilePath
& path
) {
738 scoped_refptr
<ShareableFileReference
> file
=
739 ShareableFileReference::Get(path
);
740 file
->AddFinalReleaseCallback(
741 base::Bind(&ShareableFileReleaseWaiter::Released
,
742 base::Unretained(this)));
750 void Released(const base::FilePath
& path
) {
756 DISALLOW_COPY_AND_ASSIGN(ShareableFileReleaseWaiter
);
759 // Information used to create resource requests that use URLRequestLoadInfoJobs.
760 // The child_id is just that of ResourceDispatcherHostTest::filter_.
761 struct LoadInfoTestRequestInfo
{
764 net::LoadState load_state
;
765 net::UploadProgress upload_progress
;
768 class ResourceDispatcherHostTest
: public testing::Test
,
771 typedef ResourceDispatcherHostImpl::LoadInfo LoadInfo
;
772 typedef ResourceDispatcherHostImpl::LoadInfoMap LoadInfoMap
;
774 ResourceDispatcherHostTest()
775 : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP
),
777 send_data_received_acks_(false) {
778 browser_context_
.reset(new TestBrowserContext());
779 BrowserContext::EnsureResourceContextInitialized(browser_context_
.get());
780 base::RunLoop().RunUntilIdle();
781 filter_
= MakeForwardingFilter();
782 // TODO(cbentzel): Better way to get URLRequestContext?
783 net::URLRequestContext
* request_context
=
784 browser_context_
->GetResourceContext()->GetRequestContext();
785 job_factory_
.reset(new TestURLRequestJobFactory(this));
786 request_context
->set_job_factory(job_factory_
.get());
787 request_context
->set_network_delegate(&network_delegate_
);
790 // IPC::Sender implementation
791 bool Send(IPC::Message
* msg
) override
{
792 accum_
.AddMessage(*msg
);
794 if (send_data_received_acks_
&&
795 msg
->type() == ResourceMsg_DataReceived::ID
) {
796 GenerateDataReceivedACK(*msg
);
799 if (wait_for_request_complete_loop_
&&
800 msg
->type() == ResourceMsg_RequestComplete::ID
) {
801 wait_for_request_complete_loop_
->Quit();
804 // Do not release handles in it yet; the accumulator owns them now.
809 scoped_ptr
<LoadInfoMap
> RunLoadInfoTest(LoadInfoTestRequestInfo
* request_info
,
810 size_t num_requests
) {
811 for (size_t i
= 0; i
< num_requests
; ++i
) {
812 loader_test_request_info_
.reset(
813 new LoadInfoTestRequestInfo(request_info
[i
]));
814 wait_for_request_create_loop_
.reset(new base::RunLoop());
815 MakeTestRequest(request_info
[i
].route_id
, i
+ 1, request_info
[i
].url
);
816 wait_for_request_create_loop_
->Run();
817 wait_for_request_create_loop_
.reset();
819 return ResourceDispatcherHostImpl::Get()->GetLoadInfoForAllRoutes();
823 friend class TestURLRequestJobFactory
;
826 void SetUp() override
{
827 ChildProcessSecurityPolicyImpl::GetInstance()->Add(0);
828 HandleScheme("test");
831 void TearDown() override
{
832 EXPECT_TRUE(URLRequestTestDelayedStartJob::DelayedStartQueueEmpty());
833 URLRequestTestDelayedStartJob::ClearQueue();
835 for (std::set
<int>::iterator it
= child_ids_
.begin();
836 it
!= child_ids_
.end(); ++it
) {
837 host_
.CancelRequestsForProcess(*it
);
842 ChildProcessSecurityPolicyImpl::GetInstance()->Remove(0);
844 // Flush the message loop to make application verifiers happy.
845 if (ResourceDispatcherHostImpl::Get())
846 ResourceDispatcherHostImpl::Get()->CancelRequestsForContext(
847 browser_context_
->GetResourceContext());
849 browser_context_
.reset();
850 base::RunLoop().RunUntilIdle();
853 // Creates a new ForwardingFilter and registers it with |child_ids_| so as not
854 // to leak per-child state on test shutdown.
855 ForwardingFilter
* MakeForwardingFilter() {
856 ForwardingFilter
* filter
=
857 new ForwardingFilter(this, browser_context_
->GetResourceContext());
858 child_ids_
.insert(filter
->child_id());
862 // Creates a request using the current test object as the filter and
863 // SubResource as the resource type.
864 void MakeTestRequest(int render_view_id
,
868 // Generates a request using the given filter and resource type.
869 void MakeTestRequestWithResourceType(ResourceMessageFilter
* filter
,
875 void CancelRequest(int request_id
);
876 void RendererCancelRequest(int request_id
) {
877 ResourceMessageFilter
* old_filter
= SetFilter(filter_
.get());
878 host_
.OnCancelRequest(request_id
);
879 SetFilter(old_filter
);
882 void CompleteStartRequest(int request_id
);
883 void CompleteStartRequest(ResourceMessageFilter
* filter
, int request_id
);
885 net::TestNetworkDelegate
* network_delegate() { return &network_delegate_
; }
887 void EnsureSchemeIsAllowed(const std::string
& scheme
) {
888 ChildProcessSecurityPolicyImpl
* policy
=
889 ChildProcessSecurityPolicyImpl::GetInstance();
890 if (!policy
->IsWebSafeScheme(scheme
))
891 policy
->RegisterWebSafeScheme(scheme
);
894 // Sets a particular response for any request from now on. To switch back to
895 // the default bahavior, pass an empty |headers|. |headers| should be raw-
896 // formatted (NULLs instead of EOLs).
897 void SetResponse(const std::string
& headers
, const std::string
& data
) {
898 response_headers_
= net::HttpUtil::AssembleRawHeaders(headers
.data(),
900 response_data_
= data
;
902 void SetResponse(const std::string
& headers
) {
903 SetResponse(headers
, std::string());
906 void SendDataReceivedACKs(bool send_acks
) {
907 send_data_received_acks_
= send_acks
;
910 // Intercepts requests for the given protocol.
911 void HandleScheme(const std::string
& scheme
) {
912 job_factory_
->HandleScheme(scheme
);
913 EnsureSchemeIsAllowed(scheme
);
916 void GenerateDataReceivedACK(const IPC::Message
& msg
) {
917 EXPECT_EQ(ResourceMsg_DataReceived::ID
, msg
.type());
920 bool result
= PickleIterator(msg
).ReadInt(&request_id
);
922 scoped_ptr
<IPC::Message
> ack(
923 new ResourceHostMsg_DataReceived_ACK(request_id
));
925 base::MessageLoop::current()->PostTask(
927 base::Bind(&GenerateIPCMessage
, filter_
, base::Passed(&ack
)));
930 // Setting filters for testing renderer messages.
931 // Returns the previous filter.
932 ResourceMessageFilter
* SetFilter(ResourceMessageFilter
* new_filter
) {
933 ResourceMessageFilter
* old_filter
= host_
.filter_
;
934 host_
.filter_
= new_filter
;
938 void WaitForRequestComplete() {
939 DCHECK(!wait_for_request_complete_loop_
);
940 wait_for_request_complete_loop_
.reset(new base::RunLoop
);
941 wait_for_request_complete_loop_
->Run();
942 wait_for_request_complete_loop_
.reset();
945 scoped_ptr
<LoadInfoTestRequestInfo
> loader_test_request_info_
;
946 scoped_ptr
<base::RunLoop
> wait_for_request_create_loop_
;
948 content::TestBrowserThreadBundle thread_bundle_
;
949 scoped_ptr
<TestBrowserContext
> browser_context_
;
950 scoped_ptr
<TestURLRequestJobFactory
> job_factory_
;
951 scoped_refptr
<ForwardingFilter
> filter_
;
952 net::TestNetworkDelegate network_delegate_
;
953 ResourceDispatcherHostImpl host_
;
954 ResourceIPCAccumulator accum_
;
955 std::string response_headers_
;
956 std::string response_data_
;
958 net::URLRequest::ProtocolFactory
* old_factory_
;
959 bool send_data_received_acks_
;
960 std::set
<int> child_ids_
;
961 scoped_ptr
<base::RunLoop
> wait_for_request_complete_loop_
;
964 void ResourceDispatcherHostTest::MakeTestRequest(int render_view_id
,
967 MakeTestRequestWithResourceType(filter_
.get(), render_view_id
, request_id
,
968 url
, RESOURCE_TYPE_SUB_RESOURCE
);
971 void ResourceDispatcherHostTest::MakeTestRequestWithResourceType(
972 ResourceMessageFilter
* filter
,
977 ResourceHostMsg_Request request
=
978 CreateResourceRequest("GET", type
, url
);
979 ResourceHostMsg_RequestResource
msg(render_view_id
, request_id
, request
);
980 host_
.OnMessageReceived(msg
, filter
);
984 void ResourceDispatcherHostTest::CancelRequest(int request_id
) {
985 host_
.CancelRequest(filter_
->child_id(), request_id
);
988 void ResourceDispatcherHostTest::CompleteStartRequest(int request_id
) {
989 CompleteStartRequest(filter_
.get(), request_id
);
992 void ResourceDispatcherHostTest::CompleteStartRequest(
993 ResourceMessageFilter
* filter
,
995 GlobalRequestID
gid(filter
->child_id(), request_id
);
996 net::URLRequest
* req
= host_
.GetURLRequest(gid
);
999 URLRequestTestDelayedStartJob::CompleteStart(req
);
1002 void CheckRequestCompleteErrorCode(const IPC::Message
& message
,
1003 int expected_error_code
) {
1004 // Verify the expected error code was received.
1008 ASSERT_EQ(ResourceMsg_RequestComplete::ID
, message
.type());
1010 PickleIterator
iter(message
);
1011 ASSERT_TRUE(IPC::ReadParam(&message
, &iter
, &request_id
));
1012 ASSERT_TRUE(IPC::ReadParam(&message
, &iter
, &error_code
));
1013 ASSERT_EQ(expected_error_code
, error_code
);
1016 testing::AssertionResult
ExtractDataOffsetAndLength(const IPC::Message
& message
,
1019 PickleIterator
iter(message
);
1021 if (!IPC::ReadParam(&message
, &iter
, &request_id
))
1022 return testing::AssertionFailure() << "Could not read request_id";
1023 if (!IPC::ReadParam(&message
, &iter
, data_offset
))
1024 return testing::AssertionFailure() << "Could not read data_offset";
1025 if (!IPC::ReadParam(&message
, &iter
, data_length
))
1026 return testing::AssertionFailure() << "Could not read data_length";
1027 return testing::AssertionSuccess();
1030 void CheckSuccessfulRequestWithErrorCode(
1031 const std::vector
<IPC::Message
>& messages
,
1032 const std::string
& reference_data
,
1033 int expected_error
) {
1034 // A successful request will have received 4 messages:
1035 // ReceivedResponse (indicates headers received)
1036 // SetDataBuffer (contains shared memory handle)
1037 // DataReceived (data offset and length into shared memory)
1038 // RequestComplete (request is done)
1040 // This function verifies that we received 4 messages and that they are
1041 // appropriate. It allows for an error code other than net::OK if the request
1042 // should successfully receive data and then abort, e.g., on cancel.
1043 ASSERT_EQ(4U, messages
.size());
1045 // The first messages should be received response
1046 ASSERT_EQ(ResourceMsg_ReceivedResponse::ID
, messages
[0].type());
1048 ASSERT_EQ(ResourceMsg_SetDataBuffer::ID
, messages
[1].type());
1050 PickleIterator
iter(messages
[1]);
1052 ASSERT_TRUE(IPC::ReadParam(&messages
[1], &iter
, &request_id
));
1053 base::SharedMemoryHandle shm_handle
;
1054 ASSERT_TRUE(IPC::ReadParam(&messages
[1], &iter
, &shm_handle
));
1056 ASSERT_TRUE(IPC::ReadParam(&messages
[1], &iter
, &shm_size
));
1058 // Followed by the data, currently we only do the data in one chunk, but
1059 // should probably test multiple chunks later
1060 ASSERT_EQ(ResourceMsg_DataReceived::ID
, messages
[2].type());
1065 ExtractDataOffsetAndLength(messages
[2], &data_offset
, &data_length
));
1067 ASSERT_EQ(reference_data
.size(), static_cast<size_t>(data_length
));
1068 ASSERT_GE(shm_size
, data_length
);
1070 base::SharedMemory
shared_mem(shm_handle
, true); // read only
1071 shared_mem
.Map(data_length
);
1072 const char* data
= static_cast<char*>(shared_mem
.memory()) + data_offset
;
1073 ASSERT_EQ(0, memcmp(reference_data
.c_str(), data
, data_length
));
1075 // The last message should be all data received.
1076 CheckRequestCompleteErrorCode(messages
[3], expected_error
);
1079 void CheckSuccessfulRequest(const std::vector
<IPC::Message
>& messages
,
1080 const std::string
& reference_data
) {
1081 CheckSuccessfulRequestWithErrorCode(messages
, reference_data
, net::OK
);
1084 void CheckSuccessfulRedirect(const std::vector
<IPC::Message
>& messages
,
1085 const std::string
& reference_data
) {
1086 ASSERT_EQ(5U, messages
.size());
1087 ASSERT_EQ(ResourceMsg_ReceivedRedirect::ID
, messages
[0].type());
1089 const std::vector
<IPC::Message
> second_req_msgs
=
1090 std::vector
<IPC::Message
>(messages
.begin() + 1, messages
.end());
1091 CheckSuccessfulRequest(second_req_msgs
, reference_data
);
1094 void CheckFailedRequest(const std::vector
<IPC::Message
>& messages
,
1095 const std::string
& reference_data
,
1096 int expected_error
) {
1097 ASSERT_LT(0U, messages
.size());
1098 ASSERT_GE(2U, messages
.size());
1099 size_t failure_index
= messages
.size() - 1;
1101 if (messages
.size() == 2) {
1102 EXPECT_EQ(ResourceMsg_ReceivedResponse::ID
, messages
[0].type());
1105 CheckRequestCompleteErrorCode(messages
[failure_index
], expected_error
);
1108 // Tests whether many messages get dispatched properly.
1109 TEST_F(ResourceDispatcherHostTest
, TestMany
) {
1110 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
1111 MakeTestRequest(0, 2, net::URLRequestTestJob::test_url_2());
1112 MakeTestRequest(0, 3, net::URLRequestTestJob::test_url_3());
1113 MakeTestRequestWithResourceType(filter_
.get(), 0, 4,
1114 net::URLRequestTestJob::test_url_4(),
1115 RESOURCE_TYPE_PREFETCH
); // detachable type
1116 MakeTestRequest(0, 5, net::URLRequestTestJob::test_url_redirect_to_url_2());
1118 // Finish the redirection
1119 ResourceHostMsg_FollowRedirect
redirect_msg(5);
1120 host_
.OnMessageReceived(redirect_msg
, filter_
.get());
1121 base::MessageLoop::current()->RunUntilIdle();
1123 // flush all the pending requests
1124 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1126 // sorts out all the messages we saw by request
1127 ResourceIPCAccumulator::ClassifiedMessages msgs
;
1128 accum_
.GetClassifiedMessages(&msgs
);
1130 // there are five requests, so we should have gotten them classified as such
1131 ASSERT_EQ(5U, msgs
.size());
1133 CheckSuccessfulRequest(msgs
[0], net::URLRequestTestJob::test_data_1());
1134 CheckSuccessfulRequest(msgs
[1], net::URLRequestTestJob::test_data_2());
1135 CheckSuccessfulRequest(msgs
[2], net::URLRequestTestJob::test_data_3());
1136 CheckSuccessfulRequest(msgs
[3], net::URLRequestTestJob::test_data_4());
1137 CheckSuccessfulRedirect(msgs
[4], net::URLRequestTestJob::test_data_2());
1140 // Tests whether messages get canceled properly. We issue four requests,
1141 // cancel two of them, and make sure that each sent the proper notifications.
1142 TEST_F(ResourceDispatcherHostTest
, Cancel
) {
1143 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
1144 MakeTestRequest(0, 2, net::URLRequestTestJob::test_url_2());
1145 MakeTestRequest(0, 3, net::URLRequestTestJob::test_url_3());
1147 MakeTestRequestWithResourceType(filter_
.get(), 0, 4,
1148 net::URLRequestTestJob::test_url_4(),
1149 RESOURCE_TYPE_PREFETCH
); // detachable type
1153 // Cancel request must come from the renderer for a detachable resource to
1155 RendererCancelRequest(4);
1157 // The handler should have been detached now.
1158 GlobalRequestID
global_request_id(filter_
->child_id(), 4);
1159 ResourceRequestInfoImpl
* info
= ResourceRequestInfoImpl::ForRequest(
1160 host_
.GetURLRequest(global_request_id
));
1161 ASSERT_TRUE(info
->detachable_handler()->is_detached());
1163 // flush all the pending requests
1164 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1165 base::MessageLoop::current()->RunUntilIdle();
1167 // Everything should be out now.
1168 EXPECT_EQ(0, host_
.pending_requests());
1170 ResourceIPCAccumulator::ClassifiedMessages msgs
;
1171 accum_
.GetClassifiedMessages(&msgs
);
1173 // there are four requests, so we should have gotten them classified as such
1174 ASSERT_EQ(4U, msgs
.size());
1176 CheckSuccessfulRequest(msgs
[0], net::URLRequestTestJob::test_data_1());
1177 CheckSuccessfulRequest(msgs
[2], net::URLRequestTestJob::test_data_3());
1179 // Check that request 2 and 4 got canceled, as far as the renderer is
1180 // concerned. Request 2 will have been deleted.
1181 ASSERT_EQ(1U, msgs
[1].size());
1182 ASSERT_EQ(ResourceMsg_ReceivedResponse::ID
, msgs
[1][0].type());
1184 ASSERT_EQ(2U, msgs
[3].size());
1185 ASSERT_EQ(ResourceMsg_ReceivedResponse::ID
, msgs
[3][0].type());
1186 CheckRequestCompleteErrorCode(msgs
[3][1], net::ERR_ABORTED
);
1188 // However, request 4 should have actually gone to completion. (Only request 2
1190 EXPECT_EQ(4, network_delegate()->completed_requests());
1191 EXPECT_EQ(1, network_delegate()->canceled_requests());
1192 EXPECT_EQ(0, network_delegate()->error_count());
1195 // Shows that detachable requests will timeout if the request takes too long to
1197 TEST_F(ResourceDispatcherHostTest
, DetachedResourceTimesOut
) {
1198 MakeTestRequestWithResourceType(filter_
.get(), 0, 1,
1199 net::URLRequestTestJob::test_url_2(),
1200 RESOURCE_TYPE_PREFETCH
); // detachable type
1201 GlobalRequestID
global_request_id(filter_
->child_id(), 1);
1202 ResourceRequestInfoImpl
* info
= ResourceRequestInfoImpl::ForRequest(
1203 host_
.GetURLRequest(global_request_id
));
1204 ASSERT_TRUE(info
->detachable_handler());
1205 info
->detachable_handler()->set_cancel_delay(
1206 base::TimeDelta::FromMilliseconds(200));
1207 base::MessageLoop::current()->RunUntilIdle();
1209 RendererCancelRequest(1);
1211 // From the renderer's perspective, the request was cancelled.
1212 ResourceIPCAccumulator::ClassifiedMessages msgs
;
1213 accum_
.GetClassifiedMessages(&msgs
);
1214 ASSERT_EQ(1U, msgs
.size());
1215 ASSERT_EQ(2U, msgs
[0].size());
1216 ASSERT_EQ(ResourceMsg_ReceivedResponse::ID
, msgs
[0][0].type());
1217 CheckRequestCompleteErrorCode(msgs
[0][1], net::ERR_ABORTED
);
1219 // But it continues detached.
1220 EXPECT_EQ(1, host_
.pending_requests());
1221 EXPECT_TRUE(info
->detachable_handler()->is_detached());
1223 // Wait until after the delay timer times out before we start processing any
1225 base::OneShotTimer
<base::MessageLoop
> timer
;
1226 timer
.Start(FROM_HERE
, base::TimeDelta::FromMilliseconds(210),
1227 base::MessageLoop::current(), &base::MessageLoop::QuitWhenIdle
);
1228 base::MessageLoop::current()->Run();
1230 // The prefetch should be cancelled by now.
1231 EXPECT_EQ(0, host_
.pending_requests());
1232 EXPECT_EQ(1, network_delegate()->completed_requests());
1233 EXPECT_EQ(1, network_delegate()->canceled_requests());
1234 EXPECT_EQ(0, network_delegate()->error_count());
1237 // If the filter has disappeared then detachable resources should continue to
1239 TEST_F(ResourceDispatcherHostTest
, DeletedFilterDetached
) {
1240 // test_url_1's data is available synchronously, so use 2 and 3.
1241 ResourceHostMsg_Request request_prefetch
= CreateResourceRequest(
1242 "GET", RESOURCE_TYPE_PREFETCH
, net::URLRequestTestJob::test_url_2());
1243 ResourceHostMsg_Request request_ping
= CreateResourceRequest(
1244 "GET", RESOURCE_TYPE_PING
, net::URLRequestTestJob::test_url_3());
1246 ResourceHostMsg_RequestResource
msg_prefetch(0, 1, request_prefetch
);
1247 host_
.OnMessageReceived(msg_prefetch
, filter_
.get());
1248 ResourceHostMsg_RequestResource
msg_ping(0, 2, request_ping
);
1249 host_
.OnMessageReceived(msg_ping
, filter_
.get());
1251 // Remove the filter before processing the requests by simulating channel
1253 ResourceRequestInfoImpl
* info_prefetch
= ResourceRequestInfoImpl::ForRequest(
1254 host_
.GetURLRequest(GlobalRequestID(filter_
->child_id(), 1)));
1255 ResourceRequestInfoImpl
* info_ping
= ResourceRequestInfoImpl::ForRequest(
1256 host_
.GetURLRequest(GlobalRequestID(filter_
->child_id(), 2)));
1257 DCHECK_EQ(filter_
.get(), info_prefetch
->filter());
1258 DCHECK_EQ(filter_
.get(), info_ping
->filter());
1259 filter_
->OnChannelClosing();
1260 info_prefetch
->filter_
.reset();
1261 info_ping
->filter_
.reset();
1263 // From the renderer's perspective, the requests were cancelled.
1264 ResourceIPCAccumulator::ClassifiedMessages msgs
;
1265 accum_
.GetClassifiedMessages(&msgs
);
1266 ASSERT_EQ(2U, msgs
.size());
1267 CheckRequestCompleteErrorCode(msgs
[0][0], net::ERR_ABORTED
);
1268 CheckRequestCompleteErrorCode(msgs
[1][0], net::ERR_ABORTED
);
1270 // But it continues detached.
1271 EXPECT_EQ(2, host_
.pending_requests());
1272 EXPECT_TRUE(info_prefetch
->detachable_handler()->is_detached());
1273 EXPECT_TRUE(info_ping
->detachable_handler()->is_detached());
1277 // Make sure the requests weren't canceled early.
1278 EXPECT_EQ(2, host_
.pending_requests());
1280 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1281 base::MessageLoop::current()->RunUntilIdle();
1283 EXPECT_EQ(0, host_
.pending_requests());
1284 EXPECT_EQ(2, network_delegate()->completed_requests());
1285 EXPECT_EQ(0, network_delegate()->canceled_requests());
1286 EXPECT_EQ(0, network_delegate()->error_count());
1289 // If the filter has disappeared (original process dies) then detachable
1290 // resources should continue to load, even when redirected.
1291 TEST_F(ResourceDispatcherHostTest
, DeletedFilterDetachedRedirect
) {
1292 ResourceHostMsg_Request request
= CreateResourceRequest(
1293 "GET", RESOURCE_TYPE_PREFETCH
,
1294 net::URLRequestTestJob::test_url_redirect_to_url_2());
1296 ResourceHostMsg_RequestResource
msg(0, 1, request
);
1297 host_
.OnMessageReceived(msg
, filter_
.get());
1299 // Remove the filter before processing the request by simulating channel
1301 GlobalRequestID
global_request_id(filter_
->child_id(), 1);
1302 ResourceRequestInfoImpl
* info
= ResourceRequestInfoImpl::ForRequest(
1303 host_
.GetURLRequest(global_request_id
));
1304 info
->filter_
->OnChannelClosing();
1305 info
->filter_
.reset();
1307 // From the renderer's perspective, the request was cancelled.
1308 ResourceIPCAccumulator::ClassifiedMessages msgs
;
1309 accum_
.GetClassifiedMessages(&msgs
);
1310 ASSERT_EQ(1U, msgs
.size());
1311 CheckRequestCompleteErrorCode(msgs
[0][0], net::ERR_ABORTED
);
1313 // But it continues detached.
1314 EXPECT_EQ(1, host_
.pending_requests());
1315 EXPECT_TRUE(info
->detachable_handler()->is_detached());
1317 // Verify no redirects before resetting the filter.
1318 net::URLRequest
* url_request
= host_
.GetURLRequest(global_request_id
);
1319 EXPECT_EQ(1u, url_request
->url_chain().size());
1322 // Verify that a redirect was followed.
1323 EXPECT_EQ(2u, url_request
->url_chain().size());
1325 // Make sure the request wasn't canceled early.
1326 EXPECT_EQ(1, host_
.pending_requests());
1328 // Finish up the request.
1329 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1330 base::MessageLoop::current()->RunUntilIdle();
1332 EXPECT_EQ(0, host_
.pending_requests());
1333 EXPECT_EQ(1, network_delegate()->completed_requests());
1334 EXPECT_EQ(0, network_delegate()->canceled_requests());
1335 EXPECT_EQ(0, network_delegate()->error_count());
1338 TEST_F(ResourceDispatcherHostTest
, CancelWhileStartIsDeferred
) {
1339 bool was_deleted
= false;
1341 // Arrange to have requests deferred before starting.
1342 TestResourceDispatcherHostDelegate delegate
;
1343 delegate
.set_flags(DEFER_STARTING_REQUEST
);
1344 delegate
.set_url_request_user_data(new TestUserData(&was_deleted
));
1345 host_
.SetDelegate(&delegate
);
1347 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
1348 // We cancel from the renderer because all non-renderer cancels delete
1349 // the request synchronously.
1350 RendererCancelRequest(1);
1352 // Our TestResourceThrottle should not have been deleted yet. This is to
1353 // ensure that destruction of the URLRequest happens asynchronously to
1354 // calling CancelRequest.
1355 EXPECT_FALSE(was_deleted
);
1357 base::MessageLoop::current()->RunUntilIdle();
1359 EXPECT_TRUE(was_deleted
);
1362 TEST_F(ResourceDispatcherHostTest
, DetachWhileStartIsDeferred
) {
1363 bool was_deleted
= false;
1365 // Arrange to have requests deferred before starting.
1366 TestResourceDispatcherHostDelegate delegate
;
1367 delegate
.set_flags(DEFER_STARTING_REQUEST
);
1368 delegate
.set_url_request_user_data(new TestUserData(&was_deleted
));
1369 host_
.SetDelegate(&delegate
);
1371 MakeTestRequestWithResourceType(filter_
.get(), 0, 1,
1372 net::URLRequestTestJob::test_url_1(),
1373 RESOURCE_TYPE_PREFETCH
); // detachable type
1374 // Cancel request must come from the renderer for a detachable resource to
1376 RendererCancelRequest(1);
1378 // Even after driving the event loop, the request has not been deleted.
1379 EXPECT_FALSE(was_deleted
);
1381 // However, it is still throttled because the defer happened above the
1382 // DetachableResourceHandler.
1383 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1384 base::MessageLoop::current()->RunUntilIdle();
1385 EXPECT_FALSE(was_deleted
);
1387 // Resume the request.
1388 GenericResourceThrottle
* throttle
=
1389 GenericResourceThrottle::active_throttle();
1390 ASSERT_TRUE(throttle
);
1393 // Now, the request completes.
1394 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1395 base::MessageLoop::current()->RunUntilIdle();
1396 EXPECT_TRUE(was_deleted
);
1397 EXPECT_EQ(1, network_delegate()->completed_requests());
1398 EXPECT_EQ(0, network_delegate()->canceled_requests());
1399 EXPECT_EQ(0, network_delegate()->error_count());
1402 // Tests if cancel is called in ResourceThrottle::WillStartRequest, then the
1403 // URLRequest will not be started.
1404 TEST_F(ResourceDispatcherHostTest
, CancelInResourceThrottleWillStartRequest
) {
1405 TestResourceDispatcherHostDelegate delegate
;
1406 delegate
.set_flags(CANCEL_BEFORE_START
);
1407 host_
.SetDelegate(&delegate
);
1409 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
1411 // flush all the pending requests
1412 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1413 base::MessageLoop::current()->RunUntilIdle();
1415 ResourceIPCAccumulator::ClassifiedMessages msgs
;
1416 accum_
.GetClassifiedMessages(&msgs
);
1418 // Check that request got canceled.
1419 ASSERT_EQ(1U, msgs
[0].size());
1420 CheckRequestCompleteErrorCode(msgs
[0][0], net::ERR_ABORTED
);
1422 // Make sure URLRequest is never started.
1423 EXPECT_EQ(0, job_factory_
->url_request_jobs_created_count());
1426 TEST_F(ResourceDispatcherHostTest
, PausedStartError
) {
1427 // Arrange to have requests deferred before processing response headers.
1428 TestResourceDispatcherHostDelegate delegate
;
1429 delegate
.set_flags(DEFER_PROCESSING_RESPONSE
);
1430 host_
.SetDelegate(&delegate
);
1432 job_factory_
->SetDelayedStartJobGeneration(true);
1433 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_error());
1434 CompleteStartRequest(1);
1436 // flush all the pending requests
1437 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1438 base::MessageLoop::current()->RunUntilIdle();
1440 EXPECT_EQ(0, host_
.pending_requests());
1443 // Test the WillStartUsingNetwork throttle.
1444 TEST_F(ResourceDispatcherHostTest
, ThrottleNetworkStart
) {
1445 // Arrange to have requests deferred before processing response headers.
1446 TestResourceDispatcherHostDelegate delegate
;
1447 delegate
.set_flags(DEFER_NETWORK_START
);
1448 host_
.SetDelegate(&delegate
);
1450 job_factory_
->SetNetworkStartNotificationJobGeneration(true);
1451 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_2());
1453 // Should have deferred for network start.
1454 GenericResourceThrottle
* first_throttle
=
1455 GenericResourceThrottle::active_throttle();
1456 ASSERT_TRUE(first_throttle
);
1457 EXPECT_EQ(0, network_delegate()->completed_requests());
1458 EXPECT_EQ(1, host_
.pending_requests());
1460 first_throttle
->Resume();
1462 // Flush all the pending requests.
1463 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1464 base::MessageLoop::current()->RunUntilIdle();
1466 EXPECT_EQ(1, network_delegate()->completed_requests());
1467 EXPECT_EQ(0, host_
.pending_requests());
1470 TEST_F(ResourceDispatcherHostTest
, ThrottleAndResumeTwice
) {
1471 // Arrange to have requests deferred before starting.
1472 TestResourceDispatcherHostDelegate delegate
;
1473 delegate
.set_flags(DEFER_STARTING_REQUEST
);
1474 delegate
.set_create_two_throttles(true);
1475 host_
.SetDelegate(&delegate
);
1477 // Make sure the first throttle blocked the request, and then resume.
1478 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
1479 GenericResourceThrottle
* first_throttle
=
1480 GenericResourceThrottle::active_throttle();
1481 ASSERT_TRUE(first_throttle
);
1482 first_throttle
->Resume();
1484 // Make sure the second throttle blocked the request, and then resume.
1485 ASSERT_TRUE(GenericResourceThrottle::active_throttle());
1486 ASSERT_NE(first_throttle
, GenericResourceThrottle::active_throttle());
1487 GenericResourceThrottle::active_throttle()->Resume();
1489 ASSERT_FALSE(GenericResourceThrottle::active_throttle());
1491 // The request is started asynchronously.
1492 base::MessageLoop::current()->RunUntilIdle();
1494 // Flush all the pending requests.
1495 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1497 EXPECT_EQ(0, host_
.pending_requests());
1499 // Make sure the request completed successfully.
1500 ResourceIPCAccumulator::ClassifiedMessages msgs
;
1501 accum_
.GetClassifiedMessages(&msgs
);
1502 ASSERT_EQ(1U, msgs
.size());
1503 CheckSuccessfulRequest(msgs
[0], net::URLRequestTestJob::test_data_1());
1507 // Tests that the delegate can cancel a request and provide a error code.
1508 TEST_F(ResourceDispatcherHostTest
, CancelInDelegate
) {
1509 TestResourceDispatcherHostDelegate delegate
;
1510 delegate
.set_flags(CANCEL_BEFORE_START
);
1511 delegate
.set_error_code_for_cancellation(net::ERR_ACCESS_DENIED
);
1512 host_
.SetDelegate(&delegate
);
1514 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
1515 // The request will get cancelled by the throttle.
1517 // flush all the pending requests
1518 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1519 base::MessageLoop::current()->RunUntilIdle();
1521 ResourceIPCAccumulator::ClassifiedMessages msgs
;
1522 accum_
.GetClassifiedMessages(&msgs
);
1524 // Check the cancellation
1525 ASSERT_EQ(1U, msgs
.size());
1526 ASSERT_EQ(1U, msgs
[0].size());
1528 CheckRequestCompleteErrorCode(msgs
[0][0], net::ERR_ACCESS_DENIED
);
1531 // Tests CancelRequestsForProcess
1532 TEST_F(ResourceDispatcherHostTest
, TestProcessCancel
) {
1533 scoped_refptr
<TestFilter
> test_filter
= new TestFilter(
1534 browser_context_
->GetResourceContext());
1535 child_ids_
.insert(test_filter
->child_id());
1537 // request 1 goes to the test delegate
1538 ResourceHostMsg_Request request
= CreateResourceRequest(
1539 "GET", RESOURCE_TYPE_SUB_RESOURCE
, net::URLRequestTestJob::test_url_1());
1541 MakeTestRequestWithResourceType(test_filter
.get(), 0, 1,
1542 net::URLRequestTestJob::test_url_1(),
1543 RESOURCE_TYPE_SUB_RESOURCE
);
1545 // request 2 goes to us
1546 MakeTestRequest(0, 2, net::URLRequestTestJob::test_url_2());
1548 // request 3 goes to the test delegate
1549 MakeTestRequestWithResourceType(test_filter
.get(), 0, 3,
1550 net::URLRequestTestJob::test_url_3(),
1551 RESOURCE_TYPE_SUB_RESOURCE
);
1553 // request 4 goes to us
1554 MakeTestRequestWithResourceType(filter_
.get(), 0, 4,
1555 net::URLRequestTestJob::test_url_4(),
1556 RESOURCE_TYPE_PREFETCH
); // detachable type
1559 // Make sure all requests have finished stage one. test_url_1 will have
1561 base::MessageLoop::current()->RunUntilIdle();
1564 // Now that the async IO path is in place, the IO always completes on the
1565 // initial call; so the requests have already completed. This basically
1566 // breaks the whole test.
1567 //EXPECT_EQ(3, host_.pending_requests());
1569 // Process test_url_2 and test_url_3 for one level so one callback is called.
1570 // We'll cancel test_url_4 (detachable) before processing it to verify that it
1571 // delays the cancel.
1572 for (int i
= 0; i
< 2; i
++)
1573 EXPECT_TRUE(net::URLRequestTestJob::ProcessOnePendingMessage());
1575 // Cancel the requests to the test process.
1576 host_
.CancelRequestsForProcess(filter_
->child_id());
1577 test_filter
->set_canceled(true);
1579 // The requests should all be cancelled, except request 4, which is detached.
1580 EXPECT_EQ(1, host_
.pending_requests());
1581 GlobalRequestID
global_request_id(filter_
->child_id(), 4);
1582 ResourceRequestInfoImpl
* info
= ResourceRequestInfoImpl::ForRequest(
1583 host_
.GetURLRequest(global_request_id
));
1584 ASSERT_TRUE(info
->detachable_handler()->is_detached());
1586 // Flush all the pending requests.
1587 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1589 EXPECT_EQ(0, host_
.pending_requests());
1591 // The test delegate should not have gotten any messages after being canceled.
1592 ASSERT_EQ(0, test_filter
->received_after_canceled());
1594 // There should be two results.
1595 ResourceIPCAccumulator::ClassifiedMessages msgs
;
1596 accum_
.GetClassifiedMessages(&msgs
);
1597 ASSERT_EQ(2U, msgs
.size());
1598 CheckSuccessfulRequest(msgs
[0], net::URLRequestTestJob::test_data_2());
1599 // The detachable request was cancelled by the renderer before it
1600 // finished. From the perspective of the renderer, it should have cancelled.
1601 ASSERT_EQ(2U, msgs
[1].size());
1602 ASSERT_EQ(ResourceMsg_ReceivedResponse::ID
, msgs
[1][0].type());
1603 CheckRequestCompleteErrorCode(msgs
[1][1], net::ERR_ABORTED
);
1604 // But it completed anyway. For the network stack, no requests were canceled.
1605 EXPECT_EQ(4, network_delegate()->completed_requests());
1606 EXPECT_EQ(0, network_delegate()->canceled_requests());
1607 EXPECT_EQ(0, network_delegate()->error_count());
1610 TEST_F(ResourceDispatcherHostTest
, TestProcessCancelDetachedTimesOut
) {
1611 MakeTestRequestWithResourceType(filter_
.get(), 0, 1,
1612 net::URLRequestTestJob::test_url_4(),
1613 RESOURCE_TYPE_PREFETCH
); // detachable type
1614 GlobalRequestID
global_request_id(filter_
->child_id(), 1);
1615 ResourceRequestInfoImpl
* info
= ResourceRequestInfoImpl::ForRequest(
1616 host_
.GetURLRequest(global_request_id
));
1617 ASSERT_TRUE(info
->detachable_handler());
1618 info
->detachable_handler()->set_cancel_delay(
1619 base::TimeDelta::FromMilliseconds(200));
1620 base::MessageLoop::current()->RunUntilIdle();
1622 // Cancel the requests to the test process.
1623 host_
.CancelRequestsForProcess(filter_
->child_id());
1624 EXPECT_EQ(1, host_
.pending_requests());
1626 // Wait until after the delay timer times out before we start processing any
1628 base::OneShotTimer
<base::MessageLoop
> timer
;
1629 timer
.Start(FROM_HERE
, base::TimeDelta::FromMilliseconds(210),
1630 base::MessageLoop::current(), &base::MessageLoop::QuitWhenIdle
);
1631 base::MessageLoop::current()->Run();
1633 // The prefetch should be cancelled by now.
1634 EXPECT_EQ(0, host_
.pending_requests());
1636 // In case any messages are still to be processed.
1637 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1638 base::MessageLoop::current()->RunUntilIdle();
1640 ResourceIPCAccumulator::ClassifiedMessages msgs
;
1641 accum_
.GetClassifiedMessages(&msgs
);
1643 ASSERT_EQ(1U, msgs
.size());
1645 // The request should have cancelled.
1646 ASSERT_EQ(2U, msgs
[0].size());
1647 ASSERT_EQ(ResourceMsg_ReceivedResponse::ID
, msgs
[0][0].type());
1648 CheckRequestCompleteErrorCode(msgs
[0][1], net::ERR_ABORTED
);
1649 // And not run to completion.
1650 EXPECT_EQ(1, network_delegate()->completed_requests());
1651 EXPECT_EQ(1, network_delegate()->canceled_requests());
1652 EXPECT_EQ(0, network_delegate()->error_count());
1655 // Tests blocking and resuming requests.
1656 TEST_F(ResourceDispatcherHostTest
, TestBlockingResumingRequests
) {
1657 host_
.BlockRequestsForRoute(filter_
->child_id(), 1);
1658 host_
.BlockRequestsForRoute(filter_
->child_id(), 2);
1659 host_
.BlockRequestsForRoute(filter_
->child_id(), 3);
1661 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
1662 MakeTestRequest(1, 2, net::URLRequestTestJob::test_url_2());
1663 MakeTestRequest(0, 3, net::URLRequestTestJob::test_url_3());
1664 MakeTestRequest(1, 4, net::URLRequestTestJob::test_url_1());
1665 MakeTestRequest(2, 5, net::URLRequestTestJob::test_url_2());
1666 MakeTestRequest(3, 6, net::URLRequestTestJob::test_url_3());
1668 // Flush all the pending requests
1669 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1671 // Sort out all the messages we saw by request
1672 ResourceIPCAccumulator::ClassifiedMessages msgs
;
1673 accum_
.GetClassifiedMessages(&msgs
);
1675 // All requests but the 2 for the RVH 0 should have been blocked.
1676 ASSERT_EQ(2U, msgs
.size());
1678 CheckSuccessfulRequest(msgs
[0], net::URLRequestTestJob::test_data_1());
1679 CheckSuccessfulRequest(msgs
[1], net::URLRequestTestJob::test_data_3());
1681 // Resume requests for RVH 1 and flush pending requests.
1682 host_
.ResumeBlockedRequestsForRoute(filter_
->child_id(), 1);
1684 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1687 accum_
.GetClassifiedMessages(&msgs
);
1688 ASSERT_EQ(2U, msgs
.size());
1689 CheckSuccessfulRequest(msgs
[0], net::URLRequestTestJob::test_data_2());
1690 CheckSuccessfulRequest(msgs
[1], net::URLRequestTestJob::test_data_1());
1692 // Test that new requests are not blocked for RVH 1.
1693 MakeTestRequest(1, 7, net::URLRequestTestJob::test_url_1());
1694 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1696 accum_
.GetClassifiedMessages(&msgs
);
1697 ASSERT_EQ(1U, msgs
.size());
1698 CheckSuccessfulRequest(msgs
[0], net::URLRequestTestJob::test_data_1());
1700 // Now resumes requests for all RVH (2 and 3).
1701 host_
.ResumeBlockedRequestsForRoute(filter_
->child_id(), 2);
1702 host_
.ResumeBlockedRequestsForRoute(filter_
->child_id(), 3);
1704 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1707 accum_
.GetClassifiedMessages(&msgs
);
1708 ASSERT_EQ(2U, msgs
.size());
1709 CheckSuccessfulRequest(msgs
[0], net::URLRequestTestJob::test_data_2());
1710 CheckSuccessfulRequest(msgs
[1], net::URLRequestTestJob::test_data_3());
1713 // Tests blocking and canceling requests.
1714 TEST_F(ResourceDispatcherHostTest
, TestBlockingCancelingRequests
) {
1715 host_
.BlockRequestsForRoute(filter_
->child_id(), 1);
1717 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
1718 MakeTestRequest(1, 2, net::URLRequestTestJob::test_url_2());
1719 MakeTestRequest(0, 3, net::URLRequestTestJob::test_url_3());
1720 MakeTestRequest(1, 4, net::URLRequestTestJob::test_url_1());
1721 // Blocked detachable resources should not delay cancellation.
1722 MakeTestRequestWithResourceType(filter_
.get(), 1, 5,
1723 net::URLRequestTestJob::test_url_4(),
1724 RESOURCE_TYPE_PREFETCH
); // detachable type
1726 // Flush all the pending requests.
1727 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1729 // Sort out all the messages we saw by request.
1730 ResourceIPCAccumulator::ClassifiedMessages msgs
;
1731 accum_
.GetClassifiedMessages(&msgs
);
1733 // The 2 requests for the RVH 0 should have been processed.
1734 ASSERT_EQ(2U, msgs
.size());
1736 CheckSuccessfulRequest(msgs
[0], net::URLRequestTestJob::test_data_1());
1737 CheckSuccessfulRequest(msgs
[1], net::URLRequestTestJob::test_data_3());
1739 // Cancel requests for RVH 1.
1740 host_
.CancelBlockedRequestsForRoute(filter_
->child_id(), 1);
1742 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1745 accum_
.GetClassifiedMessages(&msgs
);
1746 ASSERT_EQ(0U, msgs
.size());
1749 // Tests that blocked requests are canceled if their associated process dies.
1750 TEST_F(ResourceDispatcherHostTest
, TestBlockedRequestsProcessDies
) {
1751 // This second filter is used to emulate a second process.
1752 scoped_refptr
<ForwardingFilter
> second_filter
= MakeForwardingFilter();
1754 host_
.BlockRequestsForRoute(second_filter
->child_id(), 0);
1756 MakeTestRequestWithResourceType(filter_
.get(), 0, 1,
1757 net::URLRequestTestJob::test_url_1(),
1758 RESOURCE_TYPE_SUB_RESOURCE
);
1759 MakeTestRequestWithResourceType(second_filter
.get(), 0, 2,
1760 net::URLRequestTestJob::test_url_2(),
1761 RESOURCE_TYPE_SUB_RESOURCE
);
1762 MakeTestRequestWithResourceType(filter_
.get(), 0, 3,
1763 net::URLRequestTestJob::test_url_3(),
1764 RESOURCE_TYPE_SUB_RESOURCE
);
1765 MakeTestRequestWithResourceType(second_filter
.get(), 0, 4,
1766 net::URLRequestTestJob::test_url_1(),
1767 RESOURCE_TYPE_SUB_RESOURCE
);
1768 MakeTestRequestWithResourceType(second_filter
.get(), 0, 5,
1769 net::URLRequestTestJob::test_url_4(),
1770 RESOURCE_TYPE_PREFETCH
); // detachable type
1772 // Simulate process death.
1773 host_
.CancelRequestsForProcess(second_filter
->child_id());
1775 // Flush all the pending requests.
1776 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1778 // Sort out all the messages we saw by request.
1779 ResourceIPCAccumulator::ClassifiedMessages msgs
;
1780 accum_
.GetClassifiedMessages(&msgs
);
1782 // The 2 requests for the RVH 0 should have been processed. Note that
1783 // blocked detachable requests are canceled without delay.
1784 ASSERT_EQ(2U, msgs
.size());
1786 CheckSuccessfulRequest(msgs
[0], net::URLRequestTestJob::test_data_1());
1787 CheckSuccessfulRequest(msgs
[1], net::URLRequestTestJob::test_data_3());
1789 EXPECT_TRUE(host_
.blocked_loaders_map_
.empty());
1792 // Tests that blocked requests don't leak when the ResourceDispatcherHost goes
1793 // away. Note that we rely on Purify for finding the leaks if any.
1794 // If this test turns the Purify bot red, check the ResourceDispatcherHost
1795 // destructor to make sure the blocked requests are deleted.
1796 TEST_F(ResourceDispatcherHostTest
, TestBlockedRequestsDontLeak
) {
1797 // This second filter is used to emulate a second process.
1798 scoped_refptr
<ForwardingFilter
> second_filter
= MakeForwardingFilter();
1800 host_
.BlockRequestsForRoute(filter_
->child_id(), 1);
1801 host_
.BlockRequestsForRoute(filter_
->child_id(), 2);
1802 host_
.BlockRequestsForRoute(second_filter
->child_id(), 1);
1804 MakeTestRequestWithResourceType(filter_
.get(), 0, 1,
1805 net::URLRequestTestJob::test_url_1(),
1806 RESOURCE_TYPE_SUB_RESOURCE
);
1807 MakeTestRequestWithResourceType(filter_
.get(), 1, 2,
1808 net::URLRequestTestJob::test_url_2(),
1809 RESOURCE_TYPE_SUB_RESOURCE
);
1810 MakeTestRequestWithResourceType(filter_
.get(), 0, 3,
1811 net::URLRequestTestJob::test_url_3(),
1812 RESOURCE_TYPE_SUB_RESOURCE
);
1813 MakeTestRequestWithResourceType(second_filter
.get(), 1, 4,
1814 net::URLRequestTestJob::test_url_1(),
1815 RESOURCE_TYPE_SUB_RESOURCE
);
1816 MakeTestRequestWithResourceType(filter_
.get(), 2, 5,
1817 net::URLRequestTestJob::test_url_2(),
1818 RESOURCE_TYPE_SUB_RESOURCE
);
1819 MakeTestRequestWithResourceType(filter_
.get(), 2, 6,
1820 net::URLRequestTestJob::test_url_3(),
1821 RESOURCE_TYPE_SUB_RESOURCE
);
1822 MakeTestRequestWithResourceType(filter_
.get(), 0, 7,
1823 net::URLRequestTestJob::test_url_4(),
1824 RESOURCE_TYPE_PREFETCH
); // detachable type
1825 MakeTestRequestWithResourceType(second_filter
.get(), 1, 8,
1826 net::URLRequestTestJob::test_url_4(),
1827 RESOURCE_TYPE_PREFETCH
); // detachable type
1829 host_
.CancelRequestsForProcess(filter_
->child_id());
1830 host_
.CancelRequestsForProcess(second_filter
->child_id());
1832 // Flush all the pending requests.
1833 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1836 // Test the private helper method "CalculateApproximateMemoryCost()".
1837 TEST_F(ResourceDispatcherHostTest
, CalculateApproximateMemoryCost
) {
1838 net::URLRequestContext context
;
1839 scoped_ptr
<net::URLRequest
> req(context
.CreateRequest(
1840 GURL("http://www.google.com"), net::DEFAULT_PRIORITY
, NULL
, NULL
));
1843 ResourceDispatcherHostImpl::CalculateApproximateMemoryCost(req
.get()));
1845 // Add 9 bytes of referrer.
1846 req
->SetReferrer("123456789");
1849 ResourceDispatcherHostImpl::CalculateApproximateMemoryCost(req
.get()));
1851 // Add 33 bytes of upload content.
1852 std::string upload_content
;
1853 upload_content
.resize(33);
1854 std::fill(upload_content
.begin(), upload_content
.end(), 'x');
1855 scoped_ptr
<net::UploadElementReader
> reader(new net::UploadBytesElementReader(
1856 upload_content
.data(), upload_content
.size()));
1858 net::ElementsUploadDataStream::CreateWithReader(reader
.Pass(), 0));
1860 // Since the upload throttling is disabled, this has no effect on the cost.
1863 ResourceDispatcherHostImpl::CalculateApproximateMemoryCost(req
.get()));
1866 // Test that too much memory for outstanding requests for a particular
1867 // render_process_host_id causes requests to fail.
1868 TEST_F(ResourceDispatcherHostTest
, TooMuchOutstandingRequestsMemory
) {
1869 // Expected cost of each request as measured by
1870 // ResourceDispatcherHost::CalculateApproximateMemoryCost().
1871 int kMemoryCostOfTest2Req
=
1872 ResourceDispatcherHostImpl::kAvgBytesPerOutstandingRequest
+
1873 std::string("GET").size() +
1874 net::URLRequestTestJob::test_url_2().spec().size();
1876 // Tighten the bound on the ResourceDispatcherHost, to speed things up.
1877 int kMaxCostPerProcess
= 440000;
1878 host_
.set_max_outstanding_requests_cost_per_process(kMaxCostPerProcess
);
1880 // Determine how many instance of test_url_2() we can request before
1881 // throttling kicks in.
1882 size_t kMaxRequests
= kMaxCostPerProcess
/ kMemoryCostOfTest2Req
;
1884 // This second filter is used to emulate a second process.
1885 scoped_refptr
<ForwardingFilter
> second_filter
= MakeForwardingFilter();
1887 // Saturate the number of outstanding requests for our process.
1888 for (size_t i
= 0; i
< kMaxRequests
; ++i
) {
1889 MakeTestRequestWithResourceType(filter_
.get(), 0, i
+ 1,
1890 net::URLRequestTestJob::test_url_2(),
1891 RESOURCE_TYPE_SUB_RESOURCE
);
1894 // Issue two more requests for our process -- these should fail immediately.
1895 MakeTestRequestWithResourceType(filter_
.get(), 0, kMaxRequests
+ 1,
1896 net::URLRequestTestJob::test_url_2(),
1897 RESOURCE_TYPE_SUB_RESOURCE
);
1898 MakeTestRequestWithResourceType(filter_
.get(), 0, kMaxRequests
+ 2,
1899 net::URLRequestTestJob::test_url_2(),
1900 RESOURCE_TYPE_SUB_RESOURCE
);
1902 // Issue two requests for the second process -- these should succeed since
1903 // it is just process 0 that is saturated.
1904 MakeTestRequestWithResourceType(second_filter
.get(), 0, kMaxRequests
+ 3,
1905 net::URLRequestTestJob::test_url_2(),
1906 RESOURCE_TYPE_SUB_RESOURCE
);
1907 MakeTestRequestWithResourceType(second_filter
.get(), 0, kMaxRequests
+ 4,
1908 net::URLRequestTestJob::test_url_2(),
1909 RESOURCE_TYPE_SUB_RESOURCE
);
1911 // Flush all the pending requests.
1912 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1913 base::MessageLoop::current()->RunUntilIdle();
1915 // Sorts out all the messages we saw by request.
1916 ResourceIPCAccumulator::ClassifiedMessages msgs
;
1917 accum_
.GetClassifiedMessages(&msgs
);
1919 // We issued (kMaxRequests + 4) total requests.
1920 ASSERT_EQ(kMaxRequests
+ 4, msgs
.size());
1922 // Check that the first kMaxRequests succeeded.
1923 for (size_t i
= 0; i
< kMaxRequests
; ++i
)
1924 CheckSuccessfulRequest(msgs
[i
], net::URLRequestTestJob::test_data_2());
1926 // Check that the subsequent two requests (kMaxRequests + 1) and
1927 // (kMaxRequests + 2) were failed, since the per-process bound was reached.
1928 for (int i
= 0; i
< 2; ++i
) {
1929 // Should have sent a single RequestComplete message.
1930 int index
= kMaxRequests
+ i
;
1931 CheckFailedRequest(msgs
[index
], net::URLRequestTestJob::test_data_2(),
1932 net::ERR_INSUFFICIENT_RESOURCES
);
1935 // The final 2 requests should have succeeded.
1936 CheckSuccessfulRequest(msgs
[kMaxRequests
+ 2],
1937 net::URLRequestTestJob::test_data_2());
1938 CheckSuccessfulRequest(msgs
[kMaxRequests
+ 3],
1939 net::URLRequestTestJob::test_data_2());
1942 // Test that when too many requests are outstanding for a particular
1943 // render_process_host_id, any subsequent request from it fails. Also verify
1944 // that the global limit is honored.
1945 TEST_F(ResourceDispatcherHostTest
, TooManyOutstandingRequests
) {
1946 // Tighten the bound on the ResourceDispatcherHost, to speed things up.
1947 const size_t kMaxRequestsPerProcess
= 2;
1948 host_
.set_max_num_in_flight_requests_per_process(kMaxRequestsPerProcess
);
1949 const size_t kMaxRequests
= 3;
1950 host_
.set_max_num_in_flight_requests(kMaxRequests
);
1952 // Needed to emulate additional processes.
1953 scoped_refptr
<ForwardingFilter
> second_filter
= MakeForwardingFilter();
1954 scoped_refptr
<ForwardingFilter
> third_filter
= MakeForwardingFilter();
1956 // Saturate the number of outstanding requests for our process.
1957 for (size_t i
= 0; i
< kMaxRequestsPerProcess
; ++i
) {
1958 MakeTestRequestWithResourceType(filter_
.get(), 0, i
+ 1,
1959 net::URLRequestTestJob::test_url_2(),
1960 RESOURCE_TYPE_SUB_RESOURCE
);
1963 // Issue another request for our process -- this should fail immediately.
1964 MakeTestRequestWithResourceType(filter_
.get(), 0, kMaxRequestsPerProcess
+ 1,
1965 net::URLRequestTestJob::test_url_2(),
1966 RESOURCE_TYPE_SUB_RESOURCE
);
1968 // Issue a request for the second process -- this should succeed, because it
1969 // is just process 0 that is saturated.
1970 MakeTestRequestWithResourceType(
1971 second_filter
.get(), 0, kMaxRequestsPerProcess
+ 2,
1972 net::URLRequestTestJob::test_url_2(), RESOURCE_TYPE_SUB_RESOURCE
);
1974 // Issue a request for the third process -- this should fail, because the
1975 // global limit has been reached.
1976 MakeTestRequestWithResourceType(
1977 third_filter
.get(), 0, kMaxRequestsPerProcess
+ 3,
1978 net::URLRequestTestJob::test_url_2(), RESOURCE_TYPE_SUB_RESOURCE
);
1980 // Flush all the pending requests.
1981 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1982 base::MessageLoop::current()->RunUntilIdle();
1984 // Sorts out all the messages we saw by request.
1985 ResourceIPCAccumulator::ClassifiedMessages msgs
;
1986 accum_
.GetClassifiedMessages(&msgs
);
1988 // The processes issued the following requests:
1989 // #1 issued kMaxRequestsPerProcess that passed + 1 that failed
1990 // #2 issued 1 request that passed
1991 // #3 issued 1 request that failed
1992 ASSERT_EQ((kMaxRequestsPerProcess
+ 1) + 1 + 1, msgs
.size());
1994 for (size_t i
= 0; i
< kMaxRequestsPerProcess
; ++i
)
1995 CheckSuccessfulRequest(msgs
[i
], net::URLRequestTestJob::test_data_2());
1997 CheckFailedRequest(msgs
[kMaxRequestsPerProcess
+ 0],
1998 net::URLRequestTestJob::test_data_2(),
1999 net::ERR_INSUFFICIENT_RESOURCES
);
2000 CheckSuccessfulRequest(msgs
[kMaxRequestsPerProcess
+ 1],
2001 net::URLRequestTestJob::test_data_2());
2002 CheckFailedRequest(msgs
[kMaxRequestsPerProcess
+ 2],
2003 net::URLRequestTestJob::test_data_2(),
2004 net::ERR_INSUFFICIENT_RESOURCES
);
2007 // Tests that we sniff the mime type for a simple request.
2008 TEST_F(ResourceDispatcherHostTest
, MimeSniffed
) {
2009 std::string
raw_headers("HTTP/1.1 200 OK\n\n");
2010 std::string
response_data("<html><title>Test One</title></html>");
2011 SetResponse(raw_headers
, response_data
);
2013 HandleScheme("http");
2014 MakeTestRequest(0, 1, GURL("http:bla"));
2016 // Flush all pending requests.
2017 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2019 // Sorts out all the messages we saw by request.
2020 ResourceIPCAccumulator::ClassifiedMessages msgs
;
2021 accum_
.GetClassifiedMessages(&msgs
);
2022 ASSERT_EQ(1U, msgs
.size());
2024 ResourceResponseHead response_head
;
2025 GetResponseHead(msgs
[0], &response_head
);
2026 ASSERT_EQ("text/html", response_head
.mime_type
);
2029 // Tests that we don't sniff the mime type when the server provides one.
2030 TEST_F(ResourceDispatcherHostTest
, MimeNotSniffed
) {
2031 std::string
raw_headers("HTTP/1.1 200 OK\n"
2032 "Content-type: image/jpeg\n\n");
2033 std::string
response_data("<html><title>Test One</title></html>");
2034 SetResponse(raw_headers
, response_data
);
2036 HandleScheme("http");
2037 MakeTestRequest(0, 1, GURL("http:bla"));
2039 // Flush all pending requests.
2040 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2042 // Sorts out all the messages we saw by request.
2043 ResourceIPCAccumulator::ClassifiedMessages msgs
;
2044 accum_
.GetClassifiedMessages(&msgs
);
2045 ASSERT_EQ(1U, msgs
.size());
2047 ResourceResponseHead response_head
;
2048 GetResponseHead(msgs
[0], &response_head
);
2049 ASSERT_EQ("image/jpeg", response_head
.mime_type
);
2052 // Tests that we don't sniff the mime type when there is no message body.
2053 TEST_F(ResourceDispatcherHostTest
, MimeNotSniffed2
) {
2054 SetResponse("HTTP/1.1 304 Not Modified\n\n");
2056 HandleScheme("http");
2057 MakeTestRequest(0, 1, GURL("http:bla"));
2059 // Flush all pending requests.
2060 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2062 // Sorts out all the messages we saw by request.
2063 ResourceIPCAccumulator::ClassifiedMessages msgs
;
2064 accum_
.GetClassifiedMessages(&msgs
);
2065 ASSERT_EQ(1U, msgs
.size());
2067 ResourceResponseHead response_head
;
2068 GetResponseHead(msgs
[0], &response_head
);
2069 ASSERT_EQ("", response_head
.mime_type
);
2072 TEST_F(ResourceDispatcherHostTest
, MimeSniff204
) {
2073 SetResponse("HTTP/1.1 204 No Content\n\n");
2075 HandleScheme("http");
2076 MakeTestRequest(0, 1, GURL("http:bla"));
2078 // Flush all pending requests.
2079 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2081 // Sorts out all the messages we saw by request.
2082 ResourceIPCAccumulator::ClassifiedMessages msgs
;
2083 accum_
.GetClassifiedMessages(&msgs
);
2084 ASSERT_EQ(1U, msgs
.size());
2086 ResourceResponseHead response_head
;
2087 GetResponseHead(msgs
[0], &response_head
);
2088 ASSERT_EQ("text/plain", response_head
.mime_type
);
2091 TEST_F(ResourceDispatcherHostTest
, MimeSniffEmpty
) {
2092 SetResponse("HTTP/1.1 200 OK\n\n");
2094 HandleScheme("http");
2095 MakeTestRequest(0, 1, GURL("http:bla"));
2097 // Flush all pending requests.
2098 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2100 // Sorts out all the messages we saw by request.
2101 ResourceIPCAccumulator::ClassifiedMessages msgs
;
2102 accum_
.GetClassifiedMessages(&msgs
);
2103 ASSERT_EQ(1U, msgs
.size());
2105 ResourceResponseHead response_head
;
2106 GetResponseHead(msgs
[0], &response_head
);
2107 ASSERT_EQ("text/plain", response_head
.mime_type
);
2110 // Tests for crbug.com/31266 (Non-2xx + application/octet-stream).
2111 TEST_F(ResourceDispatcherHostTest
, ForbiddenDownload
) {
2112 std::string
raw_headers("HTTP/1.1 403 Forbidden\n"
2113 "Content-disposition: attachment; filename=blah\n"
2114 "Content-type: application/octet-stream\n\n");
2115 std::string
response_data("<html><title>Test One</title></html>");
2116 SetResponse(raw_headers
, response_data
);
2118 HandleScheme("http");
2120 // Only MAIN_FRAMEs can trigger a download.
2121 MakeTestRequestWithResourceType(filter_
.get(), 0, 1, GURL("http:bla"),
2122 RESOURCE_TYPE_MAIN_FRAME
);
2124 // Flush all pending requests.
2125 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2126 base::MessageLoop::current()->RunUntilIdle();
2128 // Sorts out all the messages we saw by request.
2129 ResourceIPCAccumulator::ClassifiedMessages msgs
;
2130 accum_
.GetClassifiedMessages(&msgs
);
2132 // We should have gotten one RequestComplete message.
2133 ASSERT_EQ(1U, msgs
.size());
2134 ASSERT_EQ(1U, msgs
[0].size());
2135 EXPECT_EQ(ResourceMsg_RequestComplete::ID
, msgs
[0][0].type());
2137 // The RequestComplete message should have had the error code of
2138 // ERR_INVALID_RESPONSE.
2139 CheckRequestCompleteErrorCode(msgs
[0][0], net::ERR_INVALID_RESPONSE
);
2142 // Test for http://crbug.com/76202 . We don't want to destroy a
2143 // download request prematurely when processing a cancellation from
2145 TEST_F(ResourceDispatcherHostTest
, IgnoreCancelForDownloads
) {
2146 EXPECT_EQ(0, host_
.pending_requests());
2148 int render_view_id
= 0;
2151 std::string
raw_headers("HTTP\n"
2152 "Content-disposition: attachment; filename=foo\n\n");
2153 std::string
response_data("01234567890123456789\x01foobar");
2155 // Get past sniffing metrics in the BufferedResourceHandler. Note that
2156 // if we don't get past the sniffing metrics, the result will be that
2157 // the BufferedResourceHandler won't have figured out that it's a download,
2158 // won't have constructed a DownloadResourceHandler, and and the request
2159 // will be successfully canceled below, failing the test.
2160 response_data
.resize(1025, ' ');
2162 SetResponse(raw_headers
, response_data
);
2163 job_factory_
->SetDelayedCompleteJobGeneration(true);
2164 HandleScheme("http");
2166 MakeTestRequestWithResourceType(filter_
.get(), render_view_id
, request_id
,
2167 GURL("http://example.com/blah"),
2168 RESOURCE_TYPE_MAIN_FRAME
);
2169 // Return some data so that the request is identified as a download
2170 // and the proper resource handlers are created.
2171 EXPECT_TRUE(net::URLRequestTestJob::ProcessOnePendingMessage());
2173 // And now simulate a cancellation coming from the renderer.
2174 ResourceHostMsg_CancelRequest
msg(request_id
);
2175 host_
.OnMessageReceived(msg
, filter_
.get());
2177 // Since the request had already started processing as a download,
2178 // the cancellation above should have been ignored and the request
2179 // should still be alive.
2180 EXPECT_EQ(1, host_
.pending_requests());
2182 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2185 TEST_F(ResourceDispatcherHostTest
, CancelRequestsForContext
) {
2186 EXPECT_EQ(0, host_
.pending_requests());
2188 int render_view_id
= 0;
2191 std::string
raw_headers("HTTP\n"
2192 "Content-disposition: attachment; filename=foo\n\n");
2193 std::string
response_data("01234567890123456789\x01foobar");
2194 // Get past sniffing metrics.
2195 response_data
.resize(1025, ' ');
2197 SetResponse(raw_headers
, response_data
);
2198 job_factory_
->SetDelayedCompleteJobGeneration(true);
2199 HandleScheme("http");
2201 MakeTestRequestWithResourceType(filter_
.get(), render_view_id
, request_id
,
2202 GURL("http://example.com/blah"),
2203 RESOURCE_TYPE_MAIN_FRAME
);
2204 // Return some data so that the request is identified as a download
2205 // and the proper resource handlers are created.
2206 EXPECT_TRUE(net::URLRequestTestJob::ProcessOnePendingMessage());
2208 // And now simulate a cancellation coming from the renderer.
2209 ResourceHostMsg_CancelRequest
msg(request_id
);
2210 host_
.OnMessageReceived(msg
, filter_
.get());
2212 // Since the request had already started processing as a download,
2213 // the cancellation above should have been ignored and the request
2214 // should still be alive.
2215 EXPECT_EQ(1, host_
.pending_requests());
2217 // Cancelling by other methods shouldn't work either.
2218 host_
.CancelRequestsForProcess(render_view_id
);
2219 EXPECT_EQ(1, host_
.pending_requests());
2221 // Cancelling by context should work.
2222 host_
.CancelRequestsForContext(filter_
->resource_context());
2223 EXPECT_EQ(0, host_
.pending_requests());
2226 TEST_F(ResourceDispatcherHostTest
, CancelRequestsForContextDetached
) {
2227 EXPECT_EQ(0, host_
.pending_requests());
2229 int render_view_id
= 0;
2232 MakeTestRequestWithResourceType(filter_
.get(), render_view_id
, request_id
,
2233 net::URLRequestTestJob::test_url_4(),
2234 RESOURCE_TYPE_PREFETCH
); // detachable type
2236 // Simulate a cancel coming from the renderer.
2237 RendererCancelRequest(request_id
);
2239 // Since the request had already started processing as detachable,
2240 // the cancellation above should have been ignored and the request
2241 // should have been detached.
2242 EXPECT_EQ(1, host_
.pending_requests());
2244 // Cancelling by other methods should also leave it detached.
2245 host_
.CancelRequestsForProcess(render_view_id
);
2246 EXPECT_EQ(1, host_
.pending_requests());
2248 // Cancelling by context should work.
2249 host_
.CancelRequestsForContext(filter_
->resource_context());
2250 EXPECT_EQ(0, host_
.pending_requests());
2253 // Test the cancelling of requests that are being transferred to a new renderer
2254 // due to a redirection.
2255 TEST_F(ResourceDispatcherHostTest
, CancelRequestsForContextTransferred
) {
2256 EXPECT_EQ(0, host_
.pending_requests());
2258 int render_view_id
= 0;
2261 std::string
raw_headers("HTTP/1.1 200 OK\n"
2262 "Content-Type: text/html; charset=utf-8\n\n");
2263 std::string
response_data("<html>foobar</html>");
2265 SetResponse(raw_headers
, response_data
);
2266 HandleScheme("http");
2268 MakeTestRequestWithResourceType(filter_
.get(), render_view_id
, request_id
,
2269 GURL("http://example.com/blah"),
2270 RESOURCE_TYPE_MAIN_FRAME
);
2273 GlobalRequestID
global_request_id(filter_
->child_id(), request_id
);
2274 host_
.MarkAsTransferredNavigation(global_request_id
);
2276 // And now simulate a cancellation coming from the renderer.
2277 ResourceHostMsg_CancelRequest
msg(request_id
);
2278 host_
.OnMessageReceived(msg
, filter_
.get());
2280 // Since the request is marked as being transferred,
2281 // the cancellation above should have been ignored and the request
2282 // should still be alive.
2283 EXPECT_EQ(1, host_
.pending_requests());
2285 // Cancelling by other methods shouldn't work either.
2286 host_
.CancelRequestsForProcess(render_view_id
);
2287 EXPECT_EQ(1, host_
.pending_requests());
2289 // Cancelling by context should work.
2290 host_
.CancelRequestsForContext(filter_
->resource_context());
2291 EXPECT_EQ(0, host_
.pending_requests());
2294 // Test transferred navigations with text/html, which doesn't trigger any
2295 // content sniffing.
2296 TEST_F(ResourceDispatcherHostTest
, TransferNavigationHtml
) {
2297 // This test expects the cross site request to be leaked, so it can transfer
2298 // the request directly.
2299 CrossSiteResourceHandler::SetLeakRequestsForTesting(true);
2301 EXPECT_EQ(0, host_
.pending_requests());
2303 int render_view_id
= 0;
2306 // Configure initial request.
2307 SetResponse("HTTP/1.1 302 Found\n"
2308 "Location: http://other.com/blech\n\n");
2310 HandleScheme("http");
2312 // Temporarily replace ContentBrowserClient with one that will trigger the
2313 // transfer navigation code paths.
2314 TransfersAllNavigationsContentBrowserClient new_client
;
2315 ContentBrowserClient
* old_client
= SetBrowserClientForTesting(&new_client
);
2317 MakeTestRequestWithResourceType(filter_
.get(), render_view_id
, request_id
,
2318 GURL("http://example.com/blah"),
2319 RESOURCE_TYPE_MAIN_FRAME
);
2321 // Now that we're blocked on the redirect, update the response and unblock by
2322 // telling the AsyncResourceHandler to follow the redirect.
2323 const std::string kResponseBody
= "hello world";
2324 SetResponse("HTTP/1.1 200 OK\n"
2325 "Content-Type: text/html\n\n",
2327 ResourceHostMsg_FollowRedirect
redirect_msg(request_id
);
2328 host_
.OnMessageReceived(redirect_msg
, filter_
.get());
2329 base::MessageLoop::current()->RunUntilIdle();
2331 // Flush all the pending requests to get the response through the
2332 // BufferedResourceHandler.
2333 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2335 // Restore, now that we've set up a transfer.
2336 SetBrowserClientForTesting(old_client
);
2338 // This second filter is used to emulate a second process.
2339 scoped_refptr
<ForwardingFilter
> second_filter
= MakeForwardingFilter();
2341 int new_render_view_id
= 1;
2342 int new_request_id
= 2;
2344 ResourceHostMsg_Request request
=
2345 CreateResourceRequest("GET", RESOURCE_TYPE_MAIN_FRAME
,
2346 GURL("http://other.com/blech"));
2347 request
.transferred_request_child_id
= filter_
->child_id();
2348 request
.transferred_request_request_id
= request_id
;
2350 ResourceHostMsg_RequestResource
transfer_request_msg(
2351 new_render_view_id
, new_request_id
, request
);
2352 host_
.OnMessageReceived(transfer_request_msg
, second_filter
.get());
2353 base::MessageLoop::current()->RunUntilIdle();
2355 // Check generated messages.
2356 ResourceIPCAccumulator::ClassifiedMessages msgs
;
2357 accum_
.GetClassifiedMessages(&msgs
);
2359 ASSERT_EQ(2U, msgs
.size());
2360 EXPECT_EQ(ResourceMsg_ReceivedRedirect::ID
, msgs
[0][0].type());
2361 CheckSuccessfulRequest(msgs
[1], kResponseBody
);
2364 // Test transferring two navigations with text/html, to ensure the resource
2365 // accounting works.
2366 TEST_F(ResourceDispatcherHostTest
, TransferTwoNavigationsHtml
) {
2367 // This test expects the cross site request to be leaked, so it can transfer
2368 // the request directly.
2369 CrossSiteResourceHandler::SetLeakRequestsForTesting(true);
2371 EXPECT_EQ(0, host_
.pending_requests());
2373 int render_view_id
= 0;
2376 // Configure initial request.
2377 const std::string kResponseBody
= "hello world";
2378 SetResponse("HTTP/1.1 200 OK\n"
2379 "Content-Type: text/html\n\n",
2382 HandleScheme("http");
2384 // Temporarily replace ContentBrowserClient with one that will trigger the
2385 // transfer navigation code paths.
2386 TransfersAllNavigationsContentBrowserClient new_client
;
2387 ContentBrowserClient
* old_client
= SetBrowserClientForTesting(&new_client
);
2389 // Make the first request.
2390 MakeTestRequestWithResourceType(filter_
.get(), render_view_id
, request_id
,
2391 GURL("http://example.com/blah"),
2392 RESOURCE_TYPE_MAIN_FRAME
);
2394 // Make a second request from the same process.
2395 int second_request_id
= 2;
2396 MakeTestRequestWithResourceType(filter_
.get(), render_view_id
,
2398 GURL("http://example.com/foo"),
2399 RESOURCE_TYPE_MAIN_FRAME
);
2401 // Flush all the pending requests to get the response through the
2402 // BufferedResourceHandler.
2403 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2405 // Restore, now that we've set up a transfer.
2406 SetBrowserClientForTesting(old_client
);
2408 // This second filter is used to emulate a second process.
2409 scoped_refptr
<ForwardingFilter
> second_filter
= MakeForwardingFilter();
2411 // Transfer the first request.
2412 int new_render_view_id
= 1;
2413 int new_request_id
= 5;
2414 ResourceHostMsg_Request request
=
2415 CreateResourceRequest("GET", RESOURCE_TYPE_MAIN_FRAME
,
2416 GURL("http://example.com/blah"));
2417 request
.transferred_request_child_id
= filter_
->child_id();
2418 request
.transferred_request_request_id
= request_id
;
2420 ResourceHostMsg_RequestResource
transfer_request_msg(
2421 new_render_view_id
, new_request_id
, request
);
2422 host_
.OnMessageReceived(transfer_request_msg
, second_filter
.get());
2423 base::MessageLoop::current()->RunUntilIdle();
2425 // Transfer the second request.
2426 int new_second_request_id
= 6;
2427 ResourceHostMsg_Request second_request
=
2428 CreateResourceRequest("GET", RESOURCE_TYPE_MAIN_FRAME
,
2429 GURL("http://example.com/foo"));
2430 request
.transferred_request_child_id
= filter_
->child_id();
2431 request
.transferred_request_request_id
= second_request_id
;
2433 ResourceHostMsg_RequestResource
second_transfer_request_msg(
2434 new_render_view_id
, new_second_request_id
, second_request
);
2435 host_
.OnMessageReceived(second_transfer_request_msg
, second_filter
.get());
2436 base::MessageLoop::current()->RunUntilIdle();
2438 // Check generated messages.
2439 ResourceIPCAccumulator::ClassifiedMessages msgs
;
2440 accum_
.GetClassifiedMessages(&msgs
);
2442 ASSERT_EQ(2U, msgs
.size());
2443 CheckSuccessfulRequest(msgs
[0], kResponseBody
);
2446 // Test transferred navigations with text/plain, which causes
2447 // BufferedResourceHandler to buffer the response to sniff the content
2448 // before the transfer occurs.
2449 TEST_F(ResourceDispatcherHostTest
, TransferNavigationText
) {
2450 // This test expects the cross site request to be leaked, so it can transfer
2451 // the request directly.
2452 CrossSiteResourceHandler::SetLeakRequestsForTesting(true);
2454 EXPECT_EQ(0, host_
.pending_requests());
2456 int render_view_id
= 0;
2459 // Configure initial request.
2460 SetResponse("HTTP/1.1 302 Found\n"
2461 "Location: http://other.com/blech\n\n");
2463 HandleScheme("http");
2465 // Temporarily replace ContentBrowserClient with one that will trigger the
2466 // transfer navigation code paths.
2467 TransfersAllNavigationsContentBrowserClient new_client
;
2468 ContentBrowserClient
* old_client
= SetBrowserClientForTesting(&new_client
);
2470 MakeTestRequestWithResourceType(filter_
.get(), render_view_id
, request_id
,
2471 GURL("http://example.com/blah"),
2472 RESOURCE_TYPE_MAIN_FRAME
);
2474 // Now that we're blocked on the redirect, update the response and unblock by
2475 // telling the AsyncResourceHandler to follow the redirect. Use a text/plain
2476 // MIME type, which causes BufferedResourceHandler to buffer it before the
2478 const std::string kResponseBody
= "hello world";
2479 SetResponse("HTTP/1.1 200 OK\n"
2480 "Content-Type: text/plain\n\n",
2482 ResourceHostMsg_FollowRedirect
redirect_msg(request_id
);
2483 host_
.OnMessageReceived(redirect_msg
, filter_
.get());
2484 base::MessageLoop::current()->RunUntilIdle();
2486 // Flush all the pending requests to get the response through the
2487 // BufferedResourceHandler.
2488 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2490 // Restore, now that we've set up a transfer.
2491 SetBrowserClientForTesting(old_client
);
2493 // This second filter is used to emulate a second process.
2494 scoped_refptr
<ForwardingFilter
> second_filter
= MakeForwardingFilter();
2496 int new_render_view_id
= 1;
2497 int new_request_id
= 2;
2499 ResourceHostMsg_Request request
=
2500 CreateResourceRequest("GET", RESOURCE_TYPE_MAIN_FRAME
,
2501 GURL("http://other.com/blech"));
2502 request
.transferred_request_child_id
= filter_
->child_id();
2503 request
.transferred_request_request_id
= request_id
;
2505 ResourceHostMsg_RequestResource
transfer_request_msg(
2506 new_render_view_id
, new_request_id
, request
);
2507 host_
.OnMessageReceived(transfer_request_msg
, second_filter
.get());
2508 base::MessageLoop::current()->RunUntilIdle();
2510 // Check generated messages.
2511 ResourceIPCAccumulator::ClassifiedMessages msgs
;
2512 accum_
.GetClassifiedMessages(&msgs
);
2514 ASSERT_EQ(2U, msgs
.size());
2515 EXPECT_EQ(ResourceMsg_ReceivedRedirect::ID
, msgs
[0][0].type());
2516 CheckSuccessfulRequest(msgs
[1], kResponseBody
);
2519 TEST_F(ResourceDispatcherHostTest
, TransferNavigationWithProcessCrash
) {
2520 // This test expects the cross site request to be leaked, so it can transfer
2521 // the request directly.
2522 CrossSiteResourceHandler::SetLeakRequestsForTesting(true);
2524 EXPECT_EQ(0, host_
.pending_requests());
2526 int render_view_id
= 0;
2528 int first_child_id
= -1;
2530 // Configure initial request.
2531 SetResponse("HTTP/1.1 302 Found\n"
2532 "Location: http://other.com/blech\n\n");
2533 const std::string kResponseBody
= "hello world";
2535 HandleScheme("http");
2537 // Temporarily replace ContentBrowserClient with one that will trigger the
2538 // transfer navigation code paths.
2539 TransfersAllNavigationsContentBrowserClient new_client
;
2540 ContentBrowserClient
* old_client
= SetBrowserClientForTesting(&new_client
);
2542 // Create a first filter that can be deleted before the second one starts.
2544 scoped_refptr
<ForwardingFilter
> first_filter
= MakeForwardingFilter();
2545 first_child_id
= first_filter
->child_id();
2547 ResourceHostMsg_Request first_request
=
2548 CreateResourceRequest("GET", RESOURCE_TYPE_MAIN_FRAME
,
2549 GURL("http://example.com/blah"));
2551 ResourceHostMsg_RequestResource
first_request_msg(
2552 render_view_id
, request_id
, first_request
);
2553 host_
.OnMessageReceived(first_request_msg
, first_filter
.get());
2554 base::MessageLoop::current()->RunUntilIdle();
2556 // Now that we're blocked on the redirect, update the response and unblock
2557 // by telling the AsyncResourceHandler to follow the redirect.
2558 SetResponse("HTTP/1.1 200 OK\n"
2559 "Content-Type: text/html\n\n",
2561 ResourceHostMsg_FollowRedirect
redirect_msg(request_id
);
2562 host_
.OnMessageReceived(redirect_msg
, first_filter
.get());
2563 base::MessageLoop::current()->RunUntilIdle();
2565 // Flush all the pending requests to get the response through the
2566 // BufferedResourceHandler.
2567 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2569 // The first filter is now deleted, as if the child process died.
2572 SetBrowserClientForTesting(old_client
);
2574 // Make sure we don't hold onto the ResourceMessageFilter after it is deleted.
2575 GlobalRequestID
first_global_request_id(first_child_id
, request_id
);
2577 // This second filter is used to emulate a second process.
2578 scoped_refptr
<ForwardingFilter
> second_filter
= MakeForwardingFilter();
2580 int new_render_view_id
= 1;
2581 int new_request_id
= 2;
2583 ResourceHostMsg_Request request
=
2584 CreateResourceRequest("GET", RESOURCE_TYPE_MAIN_FRAME
,
2585 GURL("http://other.com/blech"));
2586 request
.transferred_request_child_id
= first_child_id
;
2587 request
.transferred_request_request_id
= request_id
;
2590 child_ids_
.insert(second_filter
->child_id());
2591 ResourceHostMsg_RequestResource
transfer_request_msg(
2592 new_render_view_id
, new_request_id
, request
);
2593 host_
.OnMessageReceived(transfer_request_msg
, second_filter
.get());
2594 base::MessageLoop::current()->RunUntilIdle();
2596 // Check generated messages.
2597 ResourceIPCAccumulator::ClassifiedMessages msgs
;
2598 accum_
.GetClassifiedMessages(&msgs
);
2600 ASSERT_EQ(2U, msgs
.size());
2601 EXPECT_EQ(ResourceMsg_ReceivedRedirect::ID
, msgs
[0][0].type());
2602 CheckSuccessfulRequest(msgs
[1], kResponseBody
);
2605 TEST_F(ResourceDispatcherHostTest
, TransferNavigationWithTwoRedirects
) {
2606 // This test expects the cross site request to be leaked, so it can transfer
2607 // the request directly.
2608 CrossSiteResourceHandler::SetLeakRequestsForTesting(true);
2610 EXPECT_EQ(0, host_
.pending_requests());
2612 int render_view_id
= 0;
2615 // Configure initial request.
2616 SetResponse("HTTP/1.1 302 Found\n"
2617 "Location: http://other.com/blech\n\n");
2619 HandleScheme("http");
2621 // Temporarily replace ContentBrowserClient with one that will trigger the
2622 // transfer navigation code paths.
2623 TransfersAllNavigationsContentBrowserClient new_client
;
2624 ContentBrowserClient
* old_client
= SetBrowserClientForTesting(&new_client
);
2626 MakeTestRequestWithResourceType(filter_
.get(), render_view_id
, request_id
,
2627 GURL("http://example.com/blah"),
2628 RESOURCE_TYPE_MAIN_FRAME
);
2630 // Now that we're blocked on the redirect, simulate hitting another redirect.
2631 SetResponse("HTTP/1.1 302 Found\n"
2632 "Location: http://other.com/blerg\n\n");
2633 ResourceHostMsg_FollowRedirect
redirect_msg(request_id
);
2634 host_
.OnMessageReceived(redirect_msg
, filter_
.get());
2635 base::MessageLoop::current()->RunUntilIdle();
2637 // Now that we're blocked on the second redirect, update the response and
2638 // unblock by telling the AsyncResourceHandler to follow the redirect.
2639 // Again, use text/plain to force BufferedResourceHandler to buffer before
2641 const std::string kResponseBody
= "hello world";
2642 SetResponse("HTTP/1.1 200 OK\n"
2643 "Content-Type: text/plain\n\n",
2645 ResourceHostMsg_FollowRedirect
redirect_msg2(request_id
);
2646 host_
.OnMessageReceived(redirect_msg2
, filter_
.get());
2647 base::MessageLoop::current()->RunUntilIdle();
2649 // Flush all the pending requests to get the response through the
2650 // BufferedResourceHandler.
2651 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2654 SetBrowserClientForTesting(old_client
);
2656 // This second filter is used to emulate a second process.
2657 scoped_refptr
<ForwardingFilter
> second_filter
= MakeForwardingFilter();
2659 int new_render_view_id
= 1;
2660 int new_request_id
= 2;
2662 ResourceHostMsg_Request request
=
2663 CreateResourceRequest("GET", RESOURCE_TYPE_MAIN_FRAME
,
2664 GURL("http://other.com/blech"));
2665 request
.transferred_request_child_id
= filter_
->child_id();
2666 request
.transferred_request_request_id
= request_id
;
2669 child_ids_
.insert(second_filter
->child_id());
2670 ResourceHostMsg_RequestResource
transfer_request_msg(
2671 new_render_view_id
, new_request_id
, request
);
2672 host_
.OnMessageReceived(transfer_request_msg
, second_filter
.get());
2674 // Verify that we update the ResourceRequestInfo.
2675 GlobalRequestID
global_request_id(second_filter
->child_id(), new_request_id
);
2676 const ResourceRequestInfoImpl
* info
= ResourceRequestInfoImpl::ForRequest(
2677 host_
.GetURLRequest(global_request_id
));
2678 EXPECT_EQ(second_filter
->child_id(), info
->GetChildID());
2679 EXPECT_EQ(new_render_view_id
, info
->GetRouteID());
2680 EXPECT_EQ(new_request_id
, info
->GetRequestID());
2681 EXPECT_EQ(second_filter
.get(), info
->filter());
2683 // Let request complete.
2684 base::MessageLoop::current()->RunUntilIdle();
2686 // Check generated messages.
2687 ResourceIPCAccumulator::ClassifiedMessages msgs
;
2688 accum_
.GetClassifiedMessages(&msgs
);
2690 ASSERT_EQ(2U, msgs
.size());
2691 EXPECT_EQ(ResourceMsg_ReceivedRedirect::ID
, msgs
[0][0].type());
2692 CheckSuccessfulRequest(msgs
[1], kResponseBody
);
2695 TEST_F(ResourceDispatcherHostTest
, UnknownURLScheme
) {
2696 EXPECT_EQ(0, host_
.pending_requests());
2698 HandleScheme("http");
2700 MakeTestRequestWithResourceType(filter_
.get(), 0, 1, GURL("foo://bar"),
2701 RESOURCE_TYPE_MAIN_FRAME
);
2703 // Flush all pending requests.
2704 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2706 // Sort all the messages we saw by request.
2707 ResourceIPCAccumulator::ClassifiedMessages msgs
;
2708 accum_
.GetClassifiedMessages(&msgs
);
2710 // We should have gotten one RequestComplete message.
2711 ASSERT_EQ(1U, msgs
[0].size());
2712 EXPECT_EQ(ResourceMsg_RequestComplete::ID
, msgs
[0][0].type());
2714 // The RequestComplete message should have the error code of
2715 // ERR_UNKNOWN_URL_SCHEME.
2716 CheckRequestCompleteErrorCode(msgs
[0][0], net::ERR_UNKNOWN_URL_SCHEME
);
2719 TEST_F(ResourceDispatcherHostTest
, DataReceivedACKs
) {
2720 EXPECT_EQ(0, host_
.pending_requests());
2722 SendDataReceivedACKs(true);
2724 HandleScheme("big-job");
2725 MakeTestRequest(0, 1, GURL("big-job:0123456789,1000000"));
2727 base::RunLoop().RunUntilIdle();
2729 // Sort all the messages we saw by request.
2730 ResourceIPCAccumulator::ClassifiedMessages msgs
;
2731 accum_
.GetClassifiedMessages(&msgs
);
2733 size_t size
= msgs
[0].size();
2735 EXPECT_EQ(ResourceMsg_ReceivedResponse::ID
, msgs
[0][0].type());
2736 EXPECT_EQ(ResourceMsg_SetDataBuffer::ID
, msgs
[0][1].type());
2737 for (size_t i
= 2; i
< size
- 1; ++i
)
2738 EXPECT_EQ(ResourceMsg_DataReceived::ID
, msgs
[0][i
].type());
2739 EXPECT_EQ(ResourceMsg_RequestComplete::ID
, msgs
[0][size
- 1].type());
2742 // Request a very large detachable resource and cancel part way. Some of the
2743 // data should have been sent to the renderer, but not all.
2744 TEST_F(ResourceDispatcherHostTest
, DataSentBeforeDetach
) {
2745 EXPECT_EQ(0, host_
.pending_requests());
2747 int render_view_id
= 0;
2750 std::string
raw_headers("HTTP\n"
2751 "Content-type: image/jpeg\n\n");
2752 std::string
response_data("01234567890123456789\x01foobar");
2754 // Create a response larger than kMaxAllocationSize (currently 32K). Note
2755 // that if this increase beyond 512K we'll need to make the response longer.
2756 const int kAllocSize
= 1024*512;
2757 response_data
.resize(kAllocSize
, ' ');
2759 SetResponse(raw_headers
, response_data
);
2760 job_factory_
->SetDelayedCompleteJobGeneration(true);
2761 HandleScheme("http");
2763 MakeTestRequestWithResourceType(filter_
.get(), render_view_id
, request_id
,
2764 GURL("http://example.com/blah"),
2765 RESOURCE_TYPE_PREFETCH
);
2767 // Get a bit of data before cancelling.
2768 EXPECT_TRUE(net::URLRequestTestJob::ProcessOnePendingMessage());
2770 // Simulate a cancellation coming from the renderer.
2771 ResourceHostMsg_CancelRequest
msg(request_id
);
2772 host_
.OnMessageReceived(msg
, filter_
.get());
2774 EXPECT_EQ(1, host_
.pending_requests());
2776 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2778 // Sort all the messages we saw by request.
2779 ResourceIPCAccumulator::ClassifiedMessages msgs
;
2780 accum_
.GetClassifiedMessages(&msgs
);
2782 EXPECT_EQ(4U, msgs
[0].size());
2784 // Figure out how many bytes were received by the renderer.
2788 ExtractDataOffsetAndLength(msgs
[0][2], &data_offset
, &data_length
));
2789 EXPECT_LT(0, data_length
);
2790 EXPECT_GT(kAllocSize
, data_length
);
2792 // Verify the data that was received before cancellation. The request should
2793 // have appeared to cancel, however.
2794 CheckSuccessfulRequestWithErrorCode(
2796 std::string(response_data
.begin(), response_data
.begin() + data_length
),
2800 TEST_F(ResourceDispatcherHostTest
, DelayedDataReceivedACKs
) {
2801 EXPECT_EQ(0, host_
.pending_requests());
2803 HandleScheme("big-job");
2804 MakeTestRequest(0, 1, GURL("big-job:0123456789,1000000"));
2806 base::RunLoop().RunUntilIdle();
2808 // Sort all the messages we saw by request.
2809 ResourceIPCAccumulator::ClassifiedMessages msgs
;
2810 accum_
.GetClassifiedMessages(&msgs
);
2812 // We expect 1x ReceivedResponse, 1x SetDataBuffer, Nx ReceivedData messages.
2813 EXPECT_EQ(ResourceMsg_ReceivedResponse::ID
, msgs
[0][0].type());
2814 EXPECT_EQ(ResourceMsg_SetDataBuffer::ID
, msgs
[0][1].type());
2815 for (size_t i
= 2; i
< msgs
[0].size(); ++i
)
2816 EXPECT_EQ(ResourceMsg_DataReceived::ID
, msgs
[0][i
].type());
2818 // NOTE: If we fail the above checks then it means that we probably didn't
2819 // load a big enough response to trigger the delay mechanism we are trying to
2822 msgs
[0].erase(msgs
[0].begin());
2823 msgs
[0].erase(msgs
[0].begin());
2825 // ACK all DataReceived messages until we find a RequestComplete message.
2826 bool complete
= false;
2828 for (size_t i
= 0; i
< msgs
[0].size(); ++i
) {
2829 if (msgs
[0][i
].type() == ResourceMsg_RequestComplete::ID
) {
2834 EXPECT_EQ(ResourceMsg_DataReceived::ID
, msgs
[0][i
].type());
2836 ResourceHostMsg_DataReceived_ACK
msg(1);
2837 host_
.OnMessageReceived(msg
, filter_
.get());
2840 base::MessageLoop::current()->RunUntilIdle();
2843 accum_
.GetClassifiedMessages(&msgs
);
2847 // Flakyness of this test might indicate memory corruption issues with
2848 // for example the ResourceBuffer of AsyncResourceHandler.
2849 TEST_F(ResourceDispatcherHostTest
, DataReceivedUnexpectedACKs
) {
2850 EXPECT_EQ(0, host_
.pending_requests());
2852 HandleScheme("big-job");
2853 MakeTestRequest(0, 1, GURL("big-job:0123456789,1000000"));
2855 base::RunLoop().RunUntilIdle();
2857 // Sort all the messages we saw by request.
2858 ResourceIPCAccumulator::ClassifiedMessages msgs
;
2859 accum_
.GetClassifiedMessages(&msgs
);
2861 // We expect 1x ReceivedResponse, 1x SetDataBuffer, Nx ReceivedData messages.
2862 EXPECT_EQ(ResourceMsg_ReceivedResponse::ID
, msgs
[0][0].type());
2863 EXPECT_EQ(ResourceMsg_SetDataBuffer::ID
, msgs
[0][1].type());
2864 for (size_t i
= 2; i
< msgs
[0].size(); ++i
)
2865 EXPECT_EQ(ResourceMsg_DataReceived::ID
, msgs
[0][i
].type());
2867 // NOTE: If we fail the above checks then it means that we probably didn't
2868 // load a big enough response to trigger the delay mechanism.
2870 // Send some unexpected ACKs.
2871 for (size_t i
= 0; i
< 128; ++i
) {
2872 ResourceHostMsg_DataReceived_ACK
msg(1);
2873 host_
.OnMessageReceived(msg
, filter_
.get());
2876 msgs
[0].erase(msgs
[0].begin());
2877 msgs
[0].erase(msgs
[0].begin());
2879 // ACK all DataReceived messages until we find a RequestComplete message.
2880 bool complete
= false;
2882 for (size_t i
= 0; i
< msgs
[0].size(); ++i
) {
2883 if (msgs
[0][i
].type() == ResourceMsg_RequestComplete::ID
) {
2888 EXPECT_EQ(ResourceMsg_DataReceived::ID
, msgs
[0][i
].type());
2890 ResourceHostMsg_DataReceived_ACK
msg(1);
2891 host_
.OnMessageReceived(msg
, filter_
.get());
2894 base::MessageLoop::current()->RunUntilIdle();
2897 accum_
.GetClassifiedMessages(&msgs
);
2901 // Tests the dispatcher host's temporary file management.
2902 TEST_F(ResourceDispatcherHostTest
, RegisterDownloadedTempFile
) {
2903 const int kRequestID
= 1;
2905 // Create a temporary file.
2906 base::FilePath file_path
;
2907 ASSERT_TRUE(base::CreateTemporaryFile(&file_path
));
2908 scoped_refptr
<ShareableFileReference
> deletable_file
=
2909 ShareableFileReference::GetOrCreate(
2911 ShareableFileReference::DELETE_ON_FINAL_RELEASE
,
2912 BrowserThread::GetMessageLoopProxyForThread(
2913 BrowserThread::FILE).get());
2916 EXPECT_FALSE(ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
2917 filter_
->child_id(), file_path
));
2919 // Register it for a resource request.
2920 host_
.RegisterDownloadedTempFile(filter_
->child_id(), kRequestID
, file_path
);
2922 // Should be readable now.
2923 EXPECT_TRUE(ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
2924 filter_
->child_id(), file_path
));
2926 // The child releases from the request.
2927 ResourceHostMsg_ReleaseDownloadedFile
release_msg(kRequestID
);
2928 host_
.OnMessageReceived(release_msg
, filter_
.get());
2930 // Still readable because there is another reference to the file. (The child
2931 // may take additional blob references.)
2932 EXPECT_TRUE(ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
2933 filter_
->child_id(), file_path
));
2935 // Release extra references and wait for the file to be deleted. (This relies
2936 // on the delete happening on the FILE thread which is mapped to main thread
2938 deletable_file
= NULL
;
2939 base::RunLoop().RunUntilIdle();
2941 // The file is no longer readable to the child and has been deleted.
2942 EXPECT_FALSE(ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
2943 filter_
->child_id(), file_path
));
2944 EXPECT_FALSE(base::PathExists(file_path
));
2947 // Tests that temporary files held on behalf of child processes are released
2948 // when the child process dies.
2949 TEST_F(ResourceDispatcherHostTest
, ReleaseTemporiesOnProcessExit
) {
2950 const int kRequestID
= 1;
2952 // Create a temporary file.
2953 base::FilePath file_path
;
2954 ASSERT_TRUE(base::CreateTemporaryFile(&file_path
));
2955 scoped_refptr
<ShareableFileReference
> deletable_file
=
2956 ShareableFileReference::GetOrCreate(
2958 ShareableFileReference::DELETE_ON_FINAL_RELEASE
,
2959 BrowserThread::GetMessageLoopProxyForThread(
2960 BrowserThread::FILE).get());
2962 // Register it for a resource request.
2963 host_
.RegisterDownloadedTempFile(filter_
->child_id(), kRequestID
, file_path
);
2964 deletable_file
= NULL
;
2966 // Should be readable now.
2967 EXPECT_TRUE(ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
2968 filter_
->child_id(), file_path
));
2970 // Let the process die.
2971 filter_
->OnChannelClosing();
2972 base::RunLoop().RunUntilIdle();
2974 // The file is no longer readable to the child and has been deleted.
2975 EXPECT_FALSE(ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
2976 filter_
->child_id(), file_path
));
2977 EXPECT_FALSE(base::PathExists(file_path
));
2980 TEST_F(ResourceDispatcherHostTest
, DownloadToFile
) {
2981 // Make a request which downloads to file.
2982 ResourceHostMsg_Request request
= CreateResourceRequest(
2983 "GET", RESOURCE_TYPE_SUB_RESOURCE
, net::URLRequestTestJob::test_url_1());
2984 request
.download_to_file
= true;
2985 ResourceHostMsg_RequestResource
request_msg(0, 1, request
);
2986 host_
.OnMessageReceived(request_msg
, filter_
.get());
2988 // Running the message loop until idle does not work because
2989 // RedirectToFileResourceHandler posts things to base::WorkerPool. Instead,
2990 // wait for the ResourceMsg_RequestComplete to go out. Then run the event loop
2991 // until idle so the loader is gone.
2992 WaitForRequestComplete();
2993 base::RunLoop().RunUntilIdle();
2994 EXPECT_EQ(0, host_
.pending_requests());
2996 ResourceIPCAccumulator::ClassifiedMessages msgs
;
2997 accum_
.GetClassifiedMessages(&msgs
);
2999 ASSERT_EQ(1U, msgs
.size());
3000 const std::vector
<IPC::Message
>& messages
= msgs
[0];
3002 // The request should contain the following messages:
3003 // ReceivedResponse (indicates headers received and filename)
3004 // DataDownloaded* (bytes downloaded and total length)
3005 // RequestComplete (request is done)
3008 ResourceResponseHead response_head
;
3009 GetResponseHead(messages
, &response_head
);
3010 ASSERT_FALSE(response_head
.download_file_path
.empty());
3013 size_t total_len
= 0;
3014 for (size_t i
= 1; i
< messages
.size() - 1; i
++) {
3015 ASSERT_EQ(ResourceMsg_DataDownloaded::ID
, messages
[i
].type());
3016 PickleIterator
iter(messages
[i
]);
3017 int request_id
, data_len
;
3018 ASSERT_TRUE(IPC::ReadParam(&messages
[i
], &iter
, &request_id
));
3019 ASSERT_TRUE(IPC::ReadParam(&messages
[i
], &iter
, &data_len
));
3020 total_len
+= data_len
;
3022 EXPECT_EQ(net::URLRequestTestJob::test_data_1().size(), total_len
);
3025 CheckRequestCompleteErrorCode(messages
.back(), net::OK
);
3027 // Verify that the data ended up in the temporary file.
3028 std::string contents
;
3029 ASSERT_TRUE(base::ReadFileToString(response_head
.download_file_path
,
3031 EXPECT_EQ(net::URLRequestTestJob::test_data_1(), contents
);
3033 // The file should be readable by the child.
3034 EXPECT_TRUE(ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
3035 filter_
->child_id(), response_head
.download_file_path
));
3037 // When the renderer releases the file, it should be deleted. Again,
3038 // RunUntilIdle doesn't work because base::WorkerPool is involved.
3039 ShareableFileReleaseWaiter
waiter(response_head
.download_file_path
);
3040 ResourceHostMsg_ReleaseDownloadedFile
release_msg(1);
3041 host_
.OnMessageReceived(release_msg
, filter_
.get());
3043 // The release callback runs before the delete is scheduled, so pump the
3044 // message loop for the delete itself. (This relies on the delete happening on
3045 // the FILE thread which is mapped to main thread in this test.)
3046 base::RunLoop().RunUntilIdle();
3048 EXPECT_FALSE(base::PathExists(response_head
.download_file_path
));
3049 EXPECT_FALSE(ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
3050 filter_
->child_id(), response_head
.download_file_path
));
3053 // Tests GetLoadInfoForAllRoutes when there are no pending requests.
3054 TEST_F(ResourceDispatcherHostTest
, LoadInfoNoRequests
) {
3055 scoped_ptr
<LoadInfoMap
> load_info_map
= RunLoadInfoTest(nullptr, 0);
3056 EXPECT_EQ(0u, load_info_map
->size());
3059 // Tests GetLoadInfoForAllRoutes when there are 3 requests from the same
3060 // RenderView. The second one is farthest along.
3061 TEST_F(ResourceDispatcherHostTest
, LoadInfo
) {
3062 const GlobalRoutingID
kId(filter_
->child_id(), 0);
3063 LoadInfoTestRequestInfo request_info
[] = {
3066 net::LOAD_STATE_SENDING_REQUEST
,
3067 net::UploadProgress(0, 0)},
3070 net::LOAD_STATE_READING_RESPONSE
,
3071 net::UploadProgress(0, 0)},
3074 net::LOAD_STATE_SENDING_REQUEST
,
3075 net::UploadProgress(0, 0)},
3077 scoped_ptr
<LoadInfoMap
> load_info_map
=
3078 RunLoadInfoTest(request_info
, arraysize(request_info
));
3079 ASSERT_EQ(1u, load_info_map
->size());
3080 ASSERT_TRUE(load_info_map
->find(kId
) != load_info_map
->end());
3081 EXPECT_EQ(GURL("test://2/"), (*load_info_map
)[kId
].url
);
3082 EXPECT_EQ(net::LOAD_STATE_READING_RESPONSE
,
3083 (*load_info_map
)[kId
].load_state
.state
);
3084 EXPECT_EQ(0u, (*load_info_map
)[kId
].upload_position
);
3085 EXPECT_EQ(0u, (*load_info_map
)[kId
].upload_size
);
3088 // Tests GetLoadInfoForAllRoutes when there are 2 requests with the same
3089 // priority. The first one (Which will have the lowest ID) should be returned.
3090 TEST_F(ResourceDispatcherHostTest
, LoadInfoSamePriority
) {
3091 const GlobalRoutingID
kId(filter_
->child_id(), 0);
3092 LoadInfoTestRequestInfo request_info
[] = {
3095 net::LOAD_STATE_IDLE
,
3096 net::UploadProgress(0, 0)},
3099 net::LOAD_STATE_IDLE
,
3100 net::UploadProgress(0, 0)},
3102 scoped_ptr
<LoadInfoMap
> load_info_map
=
3103 RunLoadInfoTest(request_info
, arraysize(request_info
));
3104 ASSERT_EQ(1u, load_info_map
->size());
3105 ASSERT_TRUE(load_info_map
->find(kId
) != load_info_map
->end());
3106 EXPECT_EQ(GURL("test://1/"), (*load_info_map
)[kId
].url
);
3107 EXPECT_EQ(net::LOAD_STATE_IDLE
, (*load_info_map
)[kId
].load_state
.state
);
3108 EXPECT_EQ(0u, (*load_info_map
)[kId
].upload_position
);
3109 EXPECT_EQ(0u, (*load_info_map
)[kId
].upload_size
);
3112 // Tests GetLoadInfoForAllRoutes when a request is uploading a body.
3113 TEST_F(ResourceDispatcherHostTest
, LoadInfoUploadProgress
) {
3114 const GlobalRoutingID
kId(filter_
->child_id(), 0);
3115 LoadInfoTestRequestInfo request_info
[] = {
3118 net::LOAD_STATE_READING_RESPONSE
,
3119 net::UploadProgress(0, 0)},
3122 net::LOAD_STATE_READING_RESPONSE
,
3123 net::UploadProgress(1000, 1000)},
3126 net::LOAD_STATE_SENDING_REQUEST
,
3127 net::UploadProgress(50, 100)},
3130 net::LOAD_STATE_READING_RESPONSE
,
3131 net::UploadProgress(1000, 1000)},
3134 net::LOAD_STATE_READING_RESPONSE
,
3135 net::UploadProgress(0, 0)},
3137 scoped_ptr
<LoadInfoMap
> load_info_map
=
3138 RunLoadInfoTest(request_info
, arraysize(request_info
));
3139 ASSERT_EQ(1u, load_info_map
->size());
3140 ASSERT_TRUE(load_info_map
->find(kId
) != load_info_map
->end());
3141 EXPECT_EQ(GURL("test://2/"), (*load_info_map
)[kId
].url
);
3142 EXPECT_EQ(net::LOAD_STATE_SENDING_REQUEST
,
3143 (*load_info_map
)[kId
].load_state
.state
);
3144 EXPECT_EQ(50u, (*load_info_map
)[kId
].upload_position
);
3145 EXPECT_EQ(100u, (*load_info_map
)[kId
].upload_size
);
3148 // Tests GetLoadInfoForAllRoutes when there are 4 requests from 2 different
3149 // RenderViews. Also tests the case where the first / last requests are the
3150 // most interesting ones.
3151 TEST_F(ResourceDispatcherHostTest
, LoadInfoTwoRenderViews
) {
3152 const GlobalRoutingID
kId1(filter_
->child_id(), 0);
3153 const GlobalRoutingID
kId2(filter_
->child_id(), 1);
3154 LoadInfoTestRequestInfo request_info
[] = {
3157 net::LOAD_STATE_CONNECTING
,
3158 net::UploadProgress(0, 0)},
3161 net::LOAD_STATE_IDLE
,
3162 net::UploadProgress(0, 0)},
3165 net::LOAD_STATE_IDLE
,
3166 net::UploadProgress(0, 0)},
3169 net::LOAD_STATE_CONNECTING
,
3170 net::UploadProgress(0, 0)},
3172 scoped_ptr
<LoadInfoMap
> load_info_map
=
3173 RunLoadInfoTest(request_info
, arraysize(request_info
));
3174 ASSERT_EQ(2u, load_info_map
->size());
3176 ASSERT_TRUE(load_info_map
->find(kId1
) != load_info_map
->end());
3177 EXPECT_EQ(GURL("test://1/"), (*load_info_map
)[kId1
].url
);
3178 EXPECT_EQ(net::LOAD_STATE_CONNECTING
,
3179 (*load_info_map
)[kId1
].load_state
.state
);
3180 EXPECT_EQ(0u, (*load_info_map
)[kId1
].upload_position
);
3181 EXPECT_EQ(0u, (*load_info_map
)[kId1
].upload_size
);
3183 ASSERT_TRUE(load_info_map
->find(kId2
) != load_info_map
->end());
3184 EXPECT_EQ(GURL("test://4/"), (*load_info_map
)[kId2
].url
);
3185 EXPECT_EQ(net::LOAD_STATE_CONNECTING
,
3186 (*load_info_map
)[kId2
].load_state
.state
);
3187 EXPECT_EQ(0u, (*load_info_map
)[kId2
].upload_position
);
3188 EXPECT_EQ(0u, (*load_info_map
)[kId2
].upload_size
);
3191 net::URLRequestJob
* TestURLRequestJobFactory::MaybeCreateJobWithProtocolHandler(
3192 const std::string
& scheme
,
3193 net::URLRequest
* request
,
3194 net::NetworkDelegate
* network_delegate
) const {
3195 url_request_jobs_created_count_
++;
3196 if (test_fixture_
->wait_for_request_create_loop_
)
3197 test_fixture_
->wait_for_request_create_loop_
->Quit();
3198 if (test_fixture_
->loader_test_request_info_
) {
3199 DCHECK_EQ(test_fixture_
->loader_test_request_info_
->url
, request
->url());
3200 scoped_ptr
<LoadInfoTestRequestInfo
> info
=
3201 test_fixture_
->loader_test_request_info_
.Pass();
3202 return new URLRequestLoadInfoJob(request
, network_delegate
,
3203 info
->load_state
, info
->upload_progress
);
3205 if (test_fixture_
->response_headers_
.empty()) {
3207 return new URLRequestTestDelayedStartJob(request
, network_delegate
);
3208 } else if (delay_complete_
) {
3209 return new URLRequestTestDelayedCompletionJob(request
,
3211 } else if (network_start_notification_
) {
3212 return new URLRequestTestDelayedNetworkJob(request
, network_delegate
);
3213 } else if (scheme
== "big-job") {
3214 return new URLRequestBigJob(request
, network_delegate
);
3216 return new net::URLRequestTestJob(request
, network_delegate
);
3220 return new URLRequestTestDelayedStartJob(
3221 request
, network_delegate
,
3222 test_fixture_
->response_headers_
, test_fixture_
->response_data_
,
3224 } else if (delay_complete_
) {
3225 return new URLRequestTestDelayedCompletionJob(
3226 request
, network_delegate
,
3227 test_fixture_
->response_headers_
, test_fixture_
->response_data_
,
3230 return new net::URLRequestTestJob(
3231 request
, network_delegate
,
3232 test_fixture_
->response_headers_
, test_fixture_
->response_data_
,
3238 net::URLRequestJob
* TestURLRequestJobFactory::MaybeInterceptRedirect(
3239 net::URLRequest
* request
,
3240 net::NetworkDelegate
* network_delegate
,
3241 const GURL
& location
) const {
3245 net::URLRequestJob
* TestURLRequestJobFactory::MaybeInterceptResponse(
3246 net::URLRequest
* request
,
3247 net::NetworkDelegate
* network_delegate
) const {
3251 } // namespace content