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/common/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(message
.ReadInt(&iter
, &request_id
));
98 base::SharedMemoryHandle shm_handle
;
99 if (IPC::ParamTraits
<base::SharedMemoryHandle
>::Read(&message
,
102 if (base::SharedMemory::IsHandleValid(shm_handle
))
103 base::SharedMemory::CloseHandle(shm_handle
);
110 static int RequestIDForMessage(const IPC::Message
& msg
) {
112 switch (msg
.type()) {
113 case ResourceMsg_UploadProgress::ID
:
114 case ResourceMsg_ReceivedResponse::ID
:
115 case ResourceMsg_ReceivedRedirect::ID
:
116 case ResourceMsg_SetDataBuffer::ID
:
117 case ResourceMsg_DataReceived::ID
:
118 case ResourceMsg_DataDownloaded::ID
:
119 case ResourceMsg_RequestComplete::ID
: {
120 bool result
= PickleIterator(msg
).ReadInt(&request_id
);
128 static ResourceHostMsg_Request
CreateResourceRequest(const char* method
,
131 ResourceHostMsg_Request request
;
132 request
.method
= std::string(method
);
134 request
.first_party_for_cookies
= url
; // bypass third-party cookie blocking
135 request
.referrer_policy
= blink::WebReferrerPolicyDefault
;
136 request
.load_flags
= 0;
137 request
.origin_pid
= 0;
138 request
.resource_type
= type
;
139 request
.request_context
= 0;
140 request
.appcache_host_id
= kAppCacheNoHostId
;
141 request
.download_to_file
= false;
142 request
.is_main_frame
= true;
143 request
.parent_is_main_frame
= false;
144 request
.parent_render_frame_id
= -1;
145 request
.transition_type
= ui::PAGE_TRANSITION_LINK
;
146 request
.allow_download
= true;
150 // Spin up the message loop to kick off the request.
151 static void KickOffRequest() {
152 base::MessageLoop::current()->RunUntilIdle();
155 // We may want to move this to a shared space if it is useful for something else
156 class ResourceIPCAccumulator
{
158 ~ResourceIPCAccumulator() {
159 for (size_t i
= 0; i
< messages_
.size(); i
++) {
160 ReleaseHandlesInMessage(messages_
[i
]);
164 // On Windows, takes ownership of SharedMemoryHandles in |msg|.
165 void AddMessage(const IPC::Message
& msg
) {
166 messages_
.push_back(msg
);
169 // This groups the messages by their request ID. The groups will be in order
170 // that the first message for each request ID was received, and the messages
171 // within the groups will be in the order that they appeared.
172 // Note that this clears messages_. The caller takes ownership of any
173 // SharedMemoryHandles in messages placed into |msgs|.
174 typedef std::vector
< std::vector
<IPC::Message
> > ClassifiedMessages
;
175 void GetClassifiedMessages(ClassifiedMessages
* msgs
);
178 std::vector
<IPC::Message
> messages_
;
181 // This is very inefficient as a result of repeatedly extracting the ID, use
183 void ResourceIPCAccumulator::GetClassifiedMessages(ClassifiedMessages
* msgs
) {
184 while (!messages_
.empty()) {
185 // Ignore unknown message types as it is valid for code to generated other
186 // IPCs as side-effects that we are not testing here.
187 int cur_id
= RequestIDForMessage(messages_
[0]);
189 std::vector
<IPC::Message
> cur_requests
;
190 cur_requests
.push_back(messages_
[0]);
191 // find all other messages with this ID
192 for (int i
= 1; i
< static_cast<int>(messages_
.size()); i
++) {
193 int id
= RequestIDForMessage(messages_
[i
]);
195 cur_requests
.push_back(messages_
[i
]);
196 messages_
.erase(messages_
.begin() + i
);
200 msgs
->push_back(cur_requests
);
202 messages_
.erase(messages_
.begin());
206 // This is used to emulate different sub-processes, since this filter will
207 // have a different ID than the original.
208 class TestFilter
: public ResourceMessageFilter
{
210 explicit TestFilter(ResourceContext
* resource_context
)
211 : ResourceMessageFilter(
212 ChildProcessHostImpl::GenerateChildProcessUniqueId(),
213 PROCESS_TYPE_RENDERER
, NULL
, NULL
, NULL
, NULL
, NULL
,
214 base::Bind(&TestFilter::GetContexts
, base::Unretained(this))),
215 resource_context_(resource_context
),
217 received_after_canceled_(0) {
218 ChildProcessSecurityPolicyImpl::GetInstance()->Add(child_id());
219 set_peer_pid_for_testing(base::GetCurrentProcId());
222 void set_canceled(bool canceled
) { canceled_
= canceled
; }
223 int received_after_canceled() const { return received_after_canceled_
; }
225 // ResourceMessageFilter override
226 bool Send(IPC::Message
* msg
) override
{
227 // No messages should be received when the process has been canceled.
229 received_after_canceled_
++;
230 ReleaseHandlesInMessage(*msg
);
235 ResourceContext
* resource_context() { return resource_context_
; }
238 ~TestFilter() override
{}
241 void GetContexts(const ResourceHostMsg_Request
& request
,
242 ResourceContext
** resource_context
,
243 net::URLRequestContext
** request_context
) {
244 *resource_context
= resource_context_
;
245 *request_context
= resource_context_
->GetRequestContext();
248 ResourceContext
* resource_context_
;
250 int received_after_canceled_
;
252 DISALLOW_COPY_AND_ASSIGN(TestFilter
);
256 // This class forwards the incoming messages to the ResourceDispatcherHostTest.
257 // For the test, we want all the incoming messages to go to the same place,
258 // which is why this forwards.
259 class ForwardingFilter
: public TestFilter
{
261 explicit ForwardingFilter(IPC::Sender
* dest
,
262 ResourceContext
* resource_context
)
263 : TestFilter(resource_context
),
267 // TestFilter override
268 bool Send(IPC::Message
* msg
) override
{ return dest_
->Send(msg
); }
271 ~ForwardingFilter() override
{}
275 DISALLOW_COPY_AND_ASSIGN(ForwardingFilter
);
278 // This class is a variation on URLRequestTestJob that will call
279 // URLRequest::WillStartUsingNetwork before starting.
280 class URLRequestTestDelayedNetworkJob
: public net::URLRequestTestJob
{
282 URLRequestTestDelayedNetworkJob(net::URLRequest
* request
,
283 net::NetworkDelegate
* network_delegate
)
284 : net::URLRequestTestJob(request
, network_delegate
) {}
286 // Only start if not deferred for network start.
287 void Start() override
{
289 NotifyBeforeNetworkStart(&defer
);
292 net::URLRequestTestJob::Start();
295 void ResumeNetworkStart() override
{ net::URLRequestTestJob::StartAsync(); }
298 ~URLRequestTestDelayedNetworkJob() override
{}
300 DISALLOW_COPY_AND_ASSIGN(URLRequestTestDelayedNetworkJob
);
303 // This class is a variation on URLRequestTestJob in that it does
304 // not complete start upon entry, only when specifically told to.
305 class URLRequestTestDelayedStartJob
: public net::URLRequestTestJob
{
307 URLRequestTestDelayedStartJob(net::URLRequest
* request
,
308 net::NetworkDelegate
* network_delegate
)
309 : net::URLRequestTestJob(request
, network_delegate
) {
312 URLRequestTestDelayedStartJob(net::URLRequest
* request
,
313 net::NetworkDelegate
* network_delegate
,
315 : net::URLRequestTestJob(request
, network_delegate
, auto_advance
) {
318 URLRequestTestDelayedStartJob(net::URLRequest
* request
,
319 net::NetworkDelegate
* network_delegate
,
320 const std::string
& response_headers
,
321 const std::string
& response_data
,
323 : net::URLRequestTestJob(request
,
331 // Do nothing until you're told to.
332 void Start() override
{}
334 // Finish starting a URL request whose job is an instance of
335 // URLRequestTestDelayedStartJob. It is illegal to call this routine
336 // with a URLRequest that does not use URLRequestTestDelayedStartJob.
337 static void CompleteStart(net::URLRequest
* request
) {
338 for (URLRequestTestDelayedStartJob
* job
= list_head_
;
341 if (job
->request() == request
) {
342 job
->net::URLRequestTestJob::Start();
349 static bool DelayedStartQueueEmpty() {
353 static void ClearQueue() {
356 << "Unreleased entries on URLRequestTestDelayedStartJob delay queue"
357 << "; may result in leaks.";
363 ~URLRequestTestDelayedStartJob() override
{
364 for (URLRequestTestDelayedStartJob
** job
= &list_head_
; *job
;
365 job
= &(*job
)->next_
) {
367 *job
= (*job
)->next_
;
380 static URLRequestTestDelayedStartJob
* list_head_
;
381 URLRequestTestDelayedStartJob
* next_
;
384 URLRequestTestDelayedStartJob
*
385 URLRequestTestDelayedStartJob::list_head_
= NULL
;
387 // This class is a variation on URLRequestTestJob in that it
388 // returns IO_pending errors before every read, not just the first one.
389 class URLRequestTestDelayedCompletionJob
: public net::URLRequestTestJob
{
391 URLRequestTestDelayedCompletionJob(net::URLRequest
* request
,
392 net::NetworkDelegate
* network_delegate
)
393 : net::URLRequestTestJob(request
, network_delegate
) {}
394 URLRequestTestDelayedCompletionJob(net::URLRequest
* request
,
395 net::NetworkDelegate
* network_delegate
,
397 : net::URLRequestTestJob(request
, network_delegate
, auto_advance
) {}
398 URLRequestTestDelayedCompletionJob(net::URLRequest
* request
,
399 net::NetworkDelegate
* network_delegate
,
400 const std::string
& response_headers
,
401 const std::string
& response_data
,
403 : net::URLRequestTestJob(request
,
410 ~URLRequestTestDelayedCompletionJob() override
{}
413 bool NextReadAsync() override
{ return true; }
416 class URLRequestBigJob
: public net::URLRequestSimpleJob
{
418 URLRequestBigJob(net::URLRequest
* request
,
419 net::NetworkDelegate
* network_delegate
)
420 : net::URLRequestSimpleJob(request
, network_delegate
) {
423 int GetData(std::string
* mime_type
,
424 std::string
* charset
,
426 const net::CompletionCallback
& callback
) const override
{
427 *mime_type
= "text/plain";
432 if (!ParseURL(request_
->url(), &text
, &count
))
433 return net::ERR_INVALID_URL
;
435 data
->reserve(text
.size() * count
);
436 for (int i
= 0; i
< count
; ++i
)
443 ~URLRequestBigJob() override
{}
445 // big-job:substring,N
446 static bool ParseURL(const GURL
& url
, std::string
* text
, int* count
) {
447 std::vector
<std::string
> parts
;
448 base::SplitString(url
.path(), ',', &parts
);
450 if (parts
.size() != 2)
454 return base::StringToInt(parts
[1], count
);
458 class ResourceDispatcherHostTest
;
460 class TestURLRequestJobFactory
: public net::URLRequestJobFactory
{
462 explicit TestURLRequestJobFactory(ResourceDispatcherHostTest
* test_fixture
)
463 : test_fixture_(test_fixture
),
465 delay_complete_(false),
466 network_start_notification_(false),
467 url_request_jobs_created_count_(0) {
470 void HandleScheme(const std::string
& scheme
) {
471 supported_schemes_
.insert(scheme
);
474 int url_request_jobs_created_count() const {
475 return url_request_jobs_created_count_
;
478 void SetDelayedStartJobGeneration(bool delay_job_start
) {
479 delay_start_
= delay_job_start
;
482 void SetDelayedCompleteJobGeneration(bool delay_job_complete
) {
483 delay_complete_
= delay_job_complete
;
486 void SetNetworkStartNotificationJobGeneration(bool notification
) {
487 network_start_notification_
= notification
;
490 net::URLRequestJob
* MaybeCreateJobWithProtocolHandler(
491 const std::string
& scheme
,
492 net::URLRequest
* request
,
493 net::NetworkDelegate
* network_delegate
) const override
;
495 net::URLRequestJob
* MaybeInterceptRedirect(
496 net::URLRequest
* request
,
497 net::NetworkDelegate
* network_delegate
,
498 const GURL
& location
) const override
;
500 net::URLRequestJob
* MaybeInterceptResponse(
501 net::URLRequest
* request
,
502 net::NetworkDelegate
* network_delegate
) const override
;
504 bool IsHandledProtocol(const std::string
& scheme
) const override
{
505 return supported_schemes_
.count(scheme
) > 0;
508 bool IsHandledURL(const GURL
& url
) const override
{
509 return supported_schemes_
.count(url
.scheme()) > 0;
512 bool IsSafeRedirectTarget(const GURL
& location
) const override
{
517 ResourceDispatcherHostTest
* test_fixture_
;
519 bool delay_complete_
;
520 bool network_start_notification_
;
521 mutable int url_request_jobs_created_count_
;
522 std::set
<std::string
> supported_schemes_
;
524 DISALLOW_COPY_AND_ASSIGN(TestURLRequestJobFactory
);
527 // Associated with an URLRequest to determine if the URLRequest gets deleted.
528 class TestUserData
: public base::SupportsUserData::Data
{
530 explicit TestUserData(bool* was_deleted
)
531 : was_deleted_(was_deleted
) {
534 ~TestUserData() override
{ *was_deleted_
= true; }
540 class TransfersAllNavigationsContentBrowserClient
541 : public TestContentBrowserClient
{
543 bool ShouldSwapProcessesForRedirect(ResourceContext
* resource_context
,
544 const GURL
& current_url
,
545 const GURL
& new_url
) override
{
550 enum GenericResourceThrottleFlags
{
552 DEFER_STARTING_REQUEST
= 1 << 0,
553 DEFER_PROCESSING_RESPONSE
= 1 << 1,
554 CANCEL_BEFORE_START
= 1 << 2,
555 DEFER_NETWORK_START
= 1 << 3
558 // Throttle that tracks the current throttle blocking a request. Only one
559 // can throttle any request at a time.
560 class GenericResourceThrottle
: public ResourceThrottle
{
562 // The value is used to indicate that the throttle should not provide
563 // a error code when cancelling a request. net::OK is used, because this
564 // is not an error code.
565 static const int USE_DEFAULT_CANCEL_ERROR_CODE
= net::OK
;
567 GenericResourceThrottle(int flags
, int code
)
569 error_code_for_cancellation_(code
) {
572 ~GenericResourceThrottle() override
{
573 if (active_throttle_
== this)
574 active_throttle_
= NULL
;
577 // ResourceThrottle implementation:
578 void WillStartRequest(bool* defer
) override
{
579 ASSERT_EQ(NULL
, active_throttle_
);
580 if (flags_
& DEFER_STARTING_REQUEST
) {
581 active_throttle_
= this;
585 if (flags_
& CANCEL_BEFORE_START
) {
586 if (error_code_for_cancellation_
== USE_DEFAULT_CANCEL_ERROR_CODE
) {
587 controller()->Cancel();
589 controller()->CancelWithError(error_code_for_cancellation_
);
594 void WillProcessResponse(bool* defer
) override
{
595 ASSERT_EQ(NULL
, active_throttle_
);
596 if (flags_
& DEFER_PROCESSING_RESPONSE
) {
597 active_throttle_
= this;
602 void WillStartUsingNetwork(bool* defer
) override
{
603 ASSERT_EQ(NULL
, active_throttle_
);
605 if (flags_
& DEFER_NETWORK_START
) {
606 active_throttle_
= this;
611 const char* GetNameForLogging() const override
{
612 return "GenericResourceThrottle";
616 ASSERT_TRUE(this == active_throttle_
);
617 active_throttle_
= NULL
;
618 controller()->Resume();
621 static GenericResourceThrottle
* active_throttle() {
622 return active_throttle_
;
626 int flags_
; // bit-wise union of GenericResourceThrottleFlags.
627 int error_code_for_cancellation_
;
629 // The currently active throttle, if any.
630 static GenericResourceThrottle
* active_throttle_
;
633 GenericResourceThrottle
* GenericResourceThrottle::active_throttle_
= NULL
;
635 class TestResourceDispatcherHostDelegate
636 : public ResourceDispatcherHostDelegate
{
638 TestResourceDispatcherHostDelegate()
639 : create_two_throttles_(false),
641 error_code_for_cancellation_(
642 GenericResourceThrottle::USE_DEFAULT_CANCEL_ERROR_CODE
) {
645 void set_url_request_user_data(base::SupportsUserData::Data
* user_data
) {
646 user_data_
.reset(user_data
);
649 void set_flags(int value
) {
653 void set_error_code_for_cancellation(int code
) {
654 error_code_for_cancellation_
= code
;
657 void set_create_two_throttles(bool create_two_throttles
) {
658 create_two_throttles_
= create_two_throttles
;
661 // ResourceDispatcherHostDelegate implementation:
663 void RequestBeginning(net::URLRequest
* request
,
664 ResourceContext
* resource_context
,
665 AppCacheService
* appcache_service
,
666 ResourceType resource_type
,
667 ScopedVector
<ResourceThrottle
>* throttles
) override
{
669 const void* key
= user_data_
.get();
670 request
->SetUserData(key
, user_data_
.release());
673 if (flags_
!= NONE
) {
674 throttles
->push_back(new GenericResourceThrottle(
675 flags_
, error_code_for_cancellation_
));
676 if (create_two_throttles_
)
677 throttles
->push_back(new GenericResourceThrottle(
678 flags_
, error_code_for_cancellation_
));
683 bool create_two_throttles_
;
685 int error_code_for_cancellation_
;
686 scoped_ptr
<base::SupportsUserData::Data
> user_data_
;
689 // Waits for a ShareableFileReference to be released.
690 class ShareableFileReleaseWaiter
{
692 ShareableFileReleaseWaiter(const base::FilePath
& path
) {
693 scoped_refptr
<ShareableFileReference
> file
=
694 ShareableFileReference::Get(path
);
695 file
->AddFinalReleaseCallback(
696 base::Bind(&ShareableFileReleaseWaiter::Released
,
697 base::Unretained(this)));
705 void Released(const base::FilePath
& path
) {
711 DISALLOW_COPY_AND_ASSIGN(ShareableFileReleaseWaiter
);
714 class ResourceDispatcherHostTest
: public testing::Test
,
717 ResourceDispatcherHostTest()
718 : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP
),
720 send_data_received_acks_(false) {
721 browser_context_
.reset(new TestBrowserContext());
722 BrowserContext::EnsureResourceContextInitialized(browser_context_
.get());
723 base::RunLoop().RunUntilIdle();
724 filter_
= MakeForwardingFilter();
725 // TODO(cbentzel): Better way to get URLRequestContext?
726 net::URLRequestContext
* request_context
=
727 browser_context_
->GetResourceContext()->GetRequestContext();
728 job_factory_
.reset(new TestURLRequestJobFactory(this));
729 request_context
->set_job_factory(job_factory_
.get());
730 request_context
->set_network_delegate(&network_delegate_
);
733 // IPC::Sender implementation
734 bool Send(IPC::Message
* msg
) override
{
735 accum_
.AddMessage(*msg
);
737 if (send_data_received_acks_
&&
738 msg
->type() == ResourceMsg_DataReceived::ID
) {
739 GenerateDataReceivedACK(*msg
);
742 if (wait_for_request_complete_loop_
&&
743 msg
->type() == ResourceMsg_RequestComplete::ID
) {
744 wait_for_request_complete_loop_
->Quit();
747 // Do not release handles in it yet; the accumulator owns them now.
753 friend class TestURLRequestJobFactory
;
756 void SetUp() override
{
757 ChildProcessSecurityPolicyImpl::GetInstance()->Add(0);
758 HandleScheme("test");
761 void TearDown() override
{
762 EXPECT_TRUE(URLRequestTestDelayedStartJob::DelayedStartQueueEmpty());
763 URLRequestTestDelayedStartJob::ClearQueue();
765 for (std::set
<int>::iterator it
= child_ids_
.begin();
766 it
!= child_ids_
.end(); ++it
) {
767 host_
.CancelRequestsForProcess(*it
);
772 ChildProcessSecurityPolicyImpl::GetInstance()->Remove(0);
774 // Flush the message loop to make application verifiers happy.
775 if (ResourceDispatcherHostImpl::Get())
776 ResourceDispatcherHostImpl::Get()->CancelRequestsForContext(
777 browser_context_
->GetResourceContext());
779 browser_context_
.reset();
780 base::RunLoop().RunUntilIdle();
783 // Creates a new ForwardingFilter and registers it with |child_ids_| so as not
784 // to leak per-child state on test shutdown.
785 ForwardingFilter
* MakeForwardingFilter() {
786 ForwardingFilter
* filter
=
787 new ForwardingFilter(this, browser_context_
->GetResourceContext());
788 child_ids_
.insert(filter
->child_id());
792 // Creates a request using the current test object as the filter and
793 // SubResource as the resource type.
794 void MakeTestRequest(int render_view_id
,
798 // Generates a request using the given filter and resource type.
799 void MakeTestRequestWithResourceType(ResourceMessageFilter
* filter
,
805 void CancelRequest(int request_id
);
806 void RendererCancelRequest(int request_id
) {
807 ResourceMessageFilter
* old_filter
= SetFilter(filter_
.get());
808 host_
.OnCancelRequest(request_id
);
809 SetFilter(old_filter
);
812 void CompleteStartRequest(int request_id
);
813 void CompleteStartRequest(ResourceMessageFilter
* filter
, int request_id
);
815 net::TestNetworkDelegate
* network_delegate() { return &network_delegate_
; }
817 void EnsureSchemeIsAllowed(const std::string
& scheme
) {
818 ChildProcessSecurityPolicyImpl
* policy
=
819 ChildProcessSecurityPolicyImpl::GetInstance();
820 if (!policy
->IsWebSafeScheme(scheme
))
821 policy
->RegisterWebSafeScheme(scheme
);
824 // Sets a particular response for any request from now on. To switch back to
825 // the default bahavior, pass an empty |headers|. |headers| should be raw-
826 // formatted (NULLs instead of EOLs).
827 void SetResponse(const std::string
& headers
, const std::string
& data
) {
828 response_headers_
= net::HttpUtil::AssembleRawHeaders(headers
.data(),
830 response_data_
= data
;
832 void SetResponse(const std::string
& headers
) {
833 SetResponse(headers
, std::string());
836 void SendDataReceivedACKs(bool send_acks
) {
837 send_data_received_acks_
= send_acks
;
840 // Intercepts requests for the given protocol.
841 void HandleScheme(const std::string
& scheme
) {
842 job_factory_
->HandleScheme(scheme
);
843 EnsureSchemeIsAllowed(scheme
);
846 void GenerateDataReceivedACK(const IPC::Message
& msg
) {
847 EXPECT_EQ(ResourceMsg_DataReceived::ID
, msg
.type());
850 bool result
= PickleIterator(msg
).ReadInt(&request_id
);
852 scoped_ptr
<IPC::Message
> ack(
853 new ResourceHostMsg_DataReceived_ACK(request_id
));
855 base::MessageLoop::current()->PostTask(
857 base::Bind(&GenerateIPCMessage
, filter_
, base::Passed(&ack
)));
860 // Setting filters for testing renderer messages.
861 // Returns the previous filter.
862 ResourceMessageFilter
* SetFilter(ResourceMessageFilter
* new_filter
) {
863 ResourceMessageFilter
* old_filter
= host_
.filter_
;
864 host_
.filter_
= new_filter
;
868 void WaitForRequestComplete() {
869 DCHECK(!wait_for_request_complete_loop_
);
870 wait_for_request_complete_loop_
.reset(new base::RunLoop
);
871 wait_for_request_complete_loop_
->Run();
872 wait_for_request_complete_loop_
.reset();
875 content::TestBrowserThreadBundle thread_bundle_
;
876 scoped_ptr
<TestBrowserContext
> browser_context_
;
877 scoped_ptr
<TestURLRequestJobFactory
> job_factory_
;
878 scoped_refptr
<ForwardingFilter
> filter_
;
879 net::TestNetworkDelegate network_delegate_
;
880 ResourceDispatcherHostImpl host_
;
881 ResourceIPCAccumulator accum_
;
882 std::string response_headers_
;
883 std::string response_data_
;
885 net::URLRequest::ProtocolFactory
* old_factory_
;
886 bool send_data_received_acks_
;
887 std::set
<int> child_ids_
;
888 scoped_ptr
<base::RunLoop
> wait_for_request_complete_loop_
;
891 void ResourceDispatcherHostTest::MakeTestRequest(int render_view_id
,
894 MakeTestRequestWithResourceType(filter_
.get(), render_view_id
, request_id
,
895 url
, RESOURCE_TYPE_SUB_RESOURCE
);
898 void ResourceDispatcherHostTest::MakeTestRequestWithResourceType(
899 ResourceMessageFilter
* filter
,
904 ResourceHostMsg_Request request
=
905 CreateResourceRequest("GET", type
, url
);
906 ResourceHostMsg_RequestResource
msg(render_view_id
, request_id
, request
);
907 host_
.OnMessageReceived(msg
, filter
);
911 void ResourceDispatcherHostTest::CancelRequest(int request_id
) {
912 host_
.CancelRequest(filter_
->child_id(), request_id
);
915 void ResourceDispatcherHostTest::CompleteStartRequest(int request_id
) {
916 CompleteStartRequest(filter_
.get(), request_id
);
919 void ResourceDispatcherHostTest::CompleteStartRequest(
920 ResourceMessageFilter
* filter
,
922 GlobalRequestID
gid(filter
->child_id(), request_id
);
923 net::URLRequest
* req
= host_
.GetURLRequest(gid
);
926 URLRequestTestDelayedStartJob::CompleteStart(req
);
929 void CheckRequestCompleteErrorCode(const IPC::Message
& message
,
930 int expected_error_code
) {
931 // Verify the expected error code was received.
935 ASSERT_EQ(ResourceMsg_RequestComplete::ID
, message
.type());
937 PickleIterator
iter(message
);
938 ASSERT_TRUE(IPC::ReadParam(&message
, &iter
, &request_id
));
939 ASSERT_TRUE(IPC::ReadParam(&message
, &iter
, &error_code
));
940 ASSERT_EQ(expected_error_code
, error_code
);
943 testing::AssertionResult
ExtractDataOffsetAndLength(const IPC::Message
& message
,
946 PickleIterator
iter(message
);
948 if (!IPC::ReadParam(&message
, &iter
, &request_id
))
949 return testing::AssertionFailure() << "Could not read request_id";
950 if (!IPC::ReadParam(&message
, &iter
, data_offset
))
951 return testing::AssertionFailure() << "Could not read data_offset";
952 if (!IPC::ReadParam(&message
, &iter
, data_length
))
953 return testing::AssertionFailure() << "Could not read data_length";
954 return testing::AssertionSuccess();
957 void CheckSuccessfulRequestWithErrorCode(
958 const std::vector
<IPC::Message
>& messages
,
959 const std::string
& reference_data
,
960 int expected_error
) {
961 // A successful request will have received 4 messages:
962 // ReceivedResponse (indicates headers received)
963 // SetDataBuffer (contains shared memory handle)
964 // DataReceived (data offset and length into shared memory)
965 // RequestComplete (request is done)
967 // This function verifies that we received 4 messages and that they are
968 // appropriate. It allows for an error code other than net::OK if the request
969 // should successfully receive data and then abort, e.g., on cancel.
970 ASSERT_EQ(4U, messages
.size());
972 // The first messages should be received response
973 ASSERT_EQ(ResourceMsg_ReceivedResponse::ID
, messages
[0].type());
975 ASSERT_EQ(ResourceMsg_SetDataBuffer::ID
, messages
[1].type());
977 PickleIterator
iter(messages
[1]);
979 ASSERT_TRUE(IPC::ReadParam(&messages
[1], &iter
, &request_id
));
980 base::SharedMemoryHandle shm_handle
;
981 ASSERT_TRUE(IPC::ReadParam(&messages
[1], &iter
, &shm_handle
));
983 ASSERT_TRUE(IPC::ReadParam(&messages
[1], &iter
, &shm_size
));
985 // Followed by the data, currently we only do the data in one chunk, but
986 // should probably test multiple chunks later
987 ASSERT_EQ(ResourceMsg_DataReceived::ID
, messages
[2].type());
992 ExtractDataOffsetAndLength(messages
[2], &data_offset
, &data_length
));
994 ASSERT_EQ(reference_data
.size(), static_cast<size_t>(data_length
));
995 ASSERT_GE(shm_size
, data_length
);
997 base::SharedMemory
shared_mem(shm_handle
, true); // read only
998 shared_mem
.Map(data_length
);
999 const char* data
= static_cast<char*>(shared_mem
.memory()) + data_offset
;
1000 ASSERT_EQ(0, memcmp(reference_data
.c_str(), data
, data_length
));
1002 // The last message should be all data received.
1003 CheckRequestCompleteErrorCode(messages
[3], expected_error
);
1006 void CheckSuccessfulRequest(const std::vector
<IPC::Message
>& messages
,
1007 const std::string
& reference_data
) {
1008 CheckSuccessfulRequestWithErrorCode(messages
, reference_data
, net::OK
);
1011 void CheckSuccessfulRedirect(const std::vector
<IPC::Message
>& messages
,
1012 const std::string
& reference_data
) {
1013 ASSERT_EQ(5U, messages
.size());
1014 ASSERT_EQ(ResourceMsg_ReceivedRedirect::ID
, messages
[0].type());
1016 const std::vector
<IPC::Message
> second_req_msgs
=
1017 std::vector
<IPC::Message
>(messages
.begin() + 1, messages
.end());
1018 CheckSuccessfulRequest(second_req_msgs
, reference_data
);
1021 void CheckFailedRequest(const std::vector
<IPC::Message
>& messages
,
1022 const std::string
& reference_data
,
1023 int expected_error
) {
1024 ASSERT_LT(0U, messages
.size());
1025 ASSERT_GE(2U, messages
.size());
1026 size_t failure_index
= messages
.size() - 1;
1028 if (messages
.size() == 2) {
1029 EXPECT_EQ(ResourceMsg_ReceivedResponse::ID
, messages
[0].type());
1032 CheckRequestCompleteErrorCode(messages
[failure_index
], expected_error
);
1035 // Tests whether many messages get dispatched properly.
1036 TEST_F(ResourceDispatcherHostTest
, TestMany
) {
1037 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
1038 MakeTestRequest(0, 2, net::URLRequestTestJob::test_url_2());
1039 MakeTestRequest(0, 3, net::URLRequestTestJob::test_url_3());
1040 MakeTestRequestWithResourceType(filter_
.get(), 0, 4,
1041 net::URLRequestTestJob::test_url_4(),
1042 RESOURCE_TYPE_PREFETCH
); // detachable type
1043 MakeTestRequest(0, 5, net::URLRequestTestJob::test_url_redirect_to_url_2());
1045 // Finish the redirection
1046 ResourceHostMsg_FollowRedirect
redirect_msg(5);
1047 host_
.OnMessageReceived(redirect_msg
, filter_
.get());
1048 base::MessageLoop::current()->RunUntilIdle();
1050 // flush all the pending requests
1051 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1053 // sorts out all the messages we saw by request
1054 ResourceIPCAccumulator::ClassifiedMessages msgs
;
1055 accum_
.GetClassifiedMessages(&msgs
);
1057 // there are five requests, so we should have gotten them classified as such
1058 ASSERT_EQ(5U, msgs
.size());
1060 CheckSuccessfulRequest(msgs
[0], net::URLRequestTestJob::test_data_1());
1061 CheckSuccessfulRequest(msgs
[1], net::URLRequestTestJob::test_data_2());
1062 CheckSuccessfulRequest(msgs
[2], net::URLRequestTestJob::test_data_3());
1063 CheckSuccessfulRequest(msgs
[3], net::URLRequestTestJob::test_data_4());
1064 CheckSuccessfulRedirect(msgs
[4], net::URLRequestTestJob::test_data_2());
1067 // Tests whether messages get canceled properly. We issue four requests,
1068 // cancel two of them, and make sure that each sent the proper notifications.
1069 TEST_F(ResourceDispatcherHostTest
, Cancel
) {
1070 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
1071 MakeTestRequest(0, 2, net::URLRequestTestJob::test_url_2());
1072 MakeTestRequest(0, 3, net::URLRequestTestJob::test_url_3());
1074 MakeTestRequestWithResourceType(filter_
.get(), 0, 4,
1075 net::URLRequestTestJob::test_url_4(),
1076 RESOURCE_TYPE_PREFETCH
); // detachable type
1080 // Cancel request must come from the renderer for a detachable resource to
1082 RendererCancelRequest(4);
1084 // The handler should have been detached now.
1085 GlobalRequestID
global_request_id(filter_
->child_id(), 4);
1086 ResourceRequestInfoImpl
* info
= ResourceRequestInfoImpl::ForRequest(
1087 host_
.GetURLRequest(global_request_id
));
1088 ASSERT_TRUE(info
->detachable_handler()->is_detached());
1090 // flush all the pending requests
1091 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1092 base::MessageLoop::current()->RunUntilIdle();
1094 // Everything should be out now.
1095 EXPECT_EQ(0, host_
.pending_requests());
1097 ResourceIPCAccumulator::ClassifiedMessages msgs
;
1098 accum_
.GetClassifiedMessages(&msgs
);
1100 // there are four requests, so we should have gotten them classified as such
1101 ASSERT_EQ(4U, msgs
.size());
1103 CheckSuccessfulRequest(msgs
[0], net::URLRequestTestJob::test_data_1());
1104 CheckSuccessfulRequest(msgs
[2], net::URLRequestTestJob::test_data_3());
1106 // Check that request 2 and 4 got canceled, as far as the renderer is
1107 // concerned. Request 2 will have been deleted.
1108 ASSERT_EQ(1U, msgs
[1].size());
1109 ASSERT_EQ(ResourceMsg_ReceivedResponse::ID
, msgs
[1][0].type());
1111 ASSERT_EQ(2U, msgs
[3].size());
1112 ASSERT_EQ(ResourceMsg_ReceivedResponse::ID
, msgs
[3][0].type());
1113 CheckRequestCompleteErrorCode(msgs
[3][1], net::ERR_ABORTED
);
1115 // However, request 4 should have actually gone to completion. (Only request 2
1117 EXPECT_EQ(4, network_delegate()->completed_requests());
1118 EXPECT_EQ(1, network_delegate()->canceled_requests());
1119 EXPECT_EQ(0, network_delegate()->error_count());
1122 // Shows that detachable requests will timeout if the request takes too long to
1124 TEST_F(ResourceDispatcherHostTest
, DetachedResourceTimesOut
) {
1125 MakeTestRequestWithResourceType(filter_
.get(), 0, 1,
1126 net::URLRequestTestJob::test_url_2(),
1127 RESOURCE_TYPE_PREFETCH
); // detachable type
1128 GlobalRequestID
global_request_id(filter_
->child_id(), 1);
1129 ResourceRequestInfoImpl
* info
= ResourceRequestInfoImpl::ForRequest(
1130 host_
.GetURLRequest(global_request_id
));
1131 ASSERT_TRUE(info
->detachable_handler());
1132 info
->detachable_handler()->set_cancel_delay(
1133 base::TimeDelta::FromMilliseconds(200));
1134 base::MessageLoop::current()->RunUntilIdle();
1136 RendererCancelRequest(1);
1138 // From the renderer's perspective, the request was cancelled.
1139 ResourceIPCAccumulator::ClassifiedMessages msgs
;
1140 accum_
.GetClassifiedMessages(&msgs
);
1141 ASSERT_EQ(1U, msgs
.size());
1142 ASSERT_EQ(2U, msgs
[0].size());
1143 ASSERT_EQ(ResourceMsg_ReceivedResponse::ID
, msgs
[0][0].type());
1144 CheckRequestCompleteErrorCode(msgs
[0][1], net::ERR_ABORTED
);
1146 // But it continues detached.
1147 EXPECT_EQ(1, host_
.pending_requests());
1148 EXPECT_TRUE(info
->detachable_handler()->is_detached());
1150 // Wait until after the delay timer times out before we start processing any
1152 base::OneShotTimer
<base::MessageLoop
> timer
;
1153 timer
.Start(FROM_HERE
, base::TimeDelta::FromMilliseconds(210),
1154 base::MessageLoop::current(), &base::MessageLoop::QuitWhenIdle
);
1155 base::MessageLoop::current()->Run();
1157 // The prefetch should be cancelled by now.
1158 EXPECT_EQ(0, host_
.pending_requests());
1159 EXPECT_EQ(1, network_delegate()->completed_requests());
1160 EXPECT_EQ(1, network_delegate()->canceled_requests());
1161 EXPECT_EQ(0, network_delegate()->error_count());
1164 // If the filter has disappeared then detachable resources should continue to
1166 TEST_F(ResourceDispatcherHostTest
, DeletedFilterDetached
) {
1167 // test_url_1's data is available synchronously, so use 2 and 3.
1168 ResourceHostMsg_Request request_prefetch
= CreateResourceRequest(
1169 "GET", RESOURCE_TYPE_PREFETCH
, net::URLRequestTestJob::test_url_2());
1170 ResourceHostMsg_Request request_ping
= CreateResourceRequest(
1171 "GET", RESOURCE_TYPE_PING
, net::URLRequestTestJob::test_url_3());
1173 ResourceHostMsg_RequestResource
msg_prefetch(0, 1, request_prefetch
);
1174 host_
.OnMessageReceived(msg_prefetch
, filter_
.get());
1175 ResourceHostMsg_RequestResource
msg_ping(0, 2, request_ping
);
1176 host_
.OnMessageReceived(msg_ping
, filter_
.get());
1178 // Remove the filter before processing the requests by simulating channel
1180 ResourceRequestInfoImpl
* info_prefetch
= ResourceRequestInfoImpl::ForRequest(
1181 host_
.GetURLRequest(GlobalRequestID(filter_
->child_id(), 1)));
1182 ResourceRequestInfoImpl
* info_ping
= ResourceRequestInfoImpl::ForRequest(
1183 host_
.GetURLRequest(GlobalRequestID(filter_
->child_id(), 2)));
1184 DCHECK_EQ(filter_
.get(), info_prefetch
->filter());
1185 DCHECK_EQ(filter_
.get(), info_ping
->filter());
1186 filter_
->OnChannelClosing();
1187 info_prefetch
->filter_
.reset();
1188 info_ping
->filter_
.reset();
1190 // From the renderer's perspective, the requests were cancelled.
1191 ResourceIPCAccumulator::ClassifiedMessages msgs
;
1192 accum_
.GetClassifiedMessages(&msgs
);
1193 ASSERT_EQ(2U, msgs
.size());
1194 CheckRequestCompleteErrorCode(msgs
[0][0], net::ERR_ABORTED
);
1195 CheckRequestCompleteErrorCode(msgs
[1][0], net::ERR_ABORTED
);
1197 // But it continues detached.
1198 EXPECT_EQ(2, host_
.pending_requests());
1199 EXPECT_TRUE(info_prefetch
->detachable_handler()->is_detached());
1200 EXPECT_TRUE(info_ping
->detachable_handler()->is_detached());
1204 // Make sure the requests weren't canceled early.
1205 EXPECT_EQ(2, host_
.pending_requests());
1207 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1208 base::MessageLoop::current()->RunUntilIdle();
1210 EXPECT_EQ(0, host_
.pending_requests());
1211 EXPECT_EQ(2, network_delegate()->completed_requests());
1212 EXPECT_EQ(0, network_delegate()->canceled_requests());
1213 EXPECT_EQ(0, network_delegate()->error_count());
1216 // If the filter has disappeared (original process dies) then detachable
1217 // resources should continue to load, even when redirected.
1218 TEST_F(ResourceDispatcherHostTest
, DeletedFilterDetachedRedirect
) {
1219 ResourceHostMsg_Request request
= CreateResourceRequest(
1220 "GET", RESOURCE_TYPE_PREFETCH
,
1221 net::URLRequestTestJob::test_url_redirect_to_url_2());
1223 ResourceHostMsg_RequestResource
msg(0, 1, request
);
1224 host_
.OnMessageReceived(msg
, filter_
.get());
1226 // Remove the filter before processing the request by simulating channel
1228 GlobalRequestID
global_request_id(filter_
->child_id(), 1);
1229 ResourceRequestInfoImpl
* info
= ResourceRequestInfoImpl::ForRequest(
1230 host_
.GetURLRequest(global_request_id
));
1231 info
->filter_
->OnChannelClosing();
1232 info
->filter_
.reset();
1234 // From the renderer's perspective, the request was cancelled.
1235 ResourceIPCAccumulator::ClassifiedMessages msgs
;
1236 accum_
.GetClassifiedMessages(&msgs
);
1237 ASSERT_EQ(1U, msgs
.size());
1238 CheckRequestCompleteErrorCode(msgs
[0][0], net::ERR_ABORTED
);
1240 // But it continues detached.
1241 EXPECT_EQ(1, host_
.pending_requests());
1242 EXPECT_TRUE(info
->detachable_handler()->is_detached());
1244 // Verify no redirects before resetting the filter.
1245 net::URLRequest
* url_request
= host_
.GetURLRequest(global_request_id
);
1246 EXPECT_EQ(1u, url_request
->url_chain().size());
1249 // Verify that a redirect was followed.
1250 EXPECT_EQ(2u, url_request
->url_chain().size());
1252 // Make sure the request wasn't canceled early.
1253 EXPECT_EQ(1, host_
.pending_requests());
1255 // Finish up the request.
1256 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1257 base::MessageLoop::current()->RunUntilIdle();
1259 EXPECT_EQ(0, host_
.pending_requests());
1260 EXPECT_EQ(1, network_delegate()->completed_requests());
1261 EXPECT_EQ(0, network_delegate()->canceled_requests());
1262 EXPECT_EQ(0, network_delegate()->error_count());
1265 TEST_F(ResourceDispatcherHostTest
, CancelWhileStartIsDeferred
) {
1266 bool was_deleted
= false;
1268 // Arrange to have requests deferred before starting.
1269 TestResourceDispatcherHostDelegate delegate
;
1270 delegate
.set_flags(DEFER_STARTING_REQUEST
);
1271 delegate
.set_url_request_user_data(new TestUserData(&was_deleted
));
1272 host_
.SetDelegate(&delegate
);
1274 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
1275 // We cancel from the renderer because all non-renderer cancels delete
1276 // the request synchronously.
1277 RendererCancelRequest(1);
1279 // Our TestResourceThrottle should not have been deleted yet. This is to
1280 // ensure that destruction of the URLRequest happens asynchronously to
1281 // calling CancelRequest.
1282 EXPECT_FALSE(was_deleted
);
1284 base::MessageLoop::current()->RunUntilIdle();
1286 EXPECT_TRUE(was_deleted
);
1289 TEST_F(ResourceDispatcherHostTest
, DetachWhileStartIsDeferred
) {
1290 bool was_deleted
= false;
1292 // Arrange to have requests deferred before starting.
1293 TestResourceDispatcherHostDelegate delegate
;
1294 delegate
.set_flags(DEFER_STARTING_REQUEST
);
1295 delegate
.set_url_request_user_data(new TestUserData(&was_deleted
));
1296 host_
.SetDelegate(&delegate
);
1298 MakeTestRequestWithResourceType(filter_
.get(), 0, 1,
1299 net::URLRequestTestJob::test_url_1(),
1300 RESOURCE_TYPE_PREFETCH
); // detachable type
1301 // Cancel request must come from the renderer for a detachable resource to
1303 RendererCancelRequest(1);
1305 // Even after driving the event loop, the request has not been deleted.
1306 EXPECT_FALSE(was_deleted
);
1308 // However, it is still throttled because the defer happened above the
1309 // DetachableResourceHandler.
1310 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1311 base::MessageLoop::current()->RunUntilIdle();
1312 EXPECT_FALSE(was_deleted
);
1314 // Resume the request.
1315 GenericResourceThrottle
* throttle
=
1316 GenericResourceThrottle::active_throttle();
1317 ASSERT_TRUE(throttle
);
1320 // Now, the request completes.
1321 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1322 base::MessageLoop::current()->RunUntilIdle();
1323 EXPECT_TRUE(was_deleted
);
1324 EXPECT_EQ(1, network_delegate()->completed_requests());
1325 EXPECT_EQ(0, network_delegate()->canceled_requests());
1326 EXPECT_EQ(0, network_delegate()->error_count());
1329 // Tests if cancel is called in ResourceThrottle::WillStartRequest, then the
1330 // URLRequest will not be started.
1331 TEST_F(ResourceDispatcherHostTest
, CancelInResourceThrottleWillStartRequest
) {
1332 TestResourceDispatcherHostDelegate delegate
;
1333 delegate
.set_flags(CANCEL_BEFORE_START
);
1334 host_
.SetDelegate(&delegate
);
1336 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
1338 // flush all the pending requests
1339 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1340 base::MessageLoop::current()->RunUntilIdle();
1342 ResourceIPCAccumulator::ClassifiedMessages msgs
;
1343 accum_
.GetClassifiedMessages(&msgs
);
1345 // Check that request got canceled.
1346 ASSERT_EQ(1U, msgs
[0].size());
1347 CheckRequestCompleteErrorCode(msgs
[0][0], net::ERR_ABORTED
);
1349 // Make sure URLRequest is never started.
1350 EXPECT_EQ(0, job_factory_
->url_request_jobs_created_count());
1353 TEST_F(ResourceDispatcherHostTest
, PausedStartError
) {
1354 // Arrange to have requests deferred before processing response headers.
1355 TestResourceDispatcherHostDelegate delegate
;
1356 delegate
.set_flags(DEFER_PROCESSING_RESPONSE
);
1357 host_
.SetDelegate(&delegate
);
1359 job_factory_
->SetDelayedStartJobGeneration(true);
1360 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_error());
1361 CompleteStartRequest(1);
1363 // flush all the pending requests
1364 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1365 base::MessageLoop::current()->RunUntilIdle();
1367 EXPECT_EQ(0, host_
.pending_requests());
1370 // Test the WillStartUsingNetwork throttle.
1371 TEST_F(ResourceDispatcherHostTest
, ThrottleNetworkStart
) {
1372 // Arrange to have requests deferred before processing response headers.
1373 TestResourceDispatcherHostDelegate delegate
;
1374 delegate
.set_flags(DEFER_NETWORK_START
);
1375 host_
.SetDelegate(&delegate
);
1377 job_factory_
->SetNetworkStartNotificationJobGeneration(true);
1378 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_2());
1380 // Should have deferred for network start.
1381 GenericResourceThrottle
* first_throttle
=
1382 GenericResourceThrottle::active_throttle();
1383 ASSERT_TRUE(first_throttle
);
1384 EXPECT_EQ(0, network_delegate()->completed_requests());
1385 EXPECT_EQ(1, host_
.pending_requests());
1387 first_throttle
->Resume();
1389 // Flush all the pending requests.
1390 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1391 base::MessageLoop::current()->RunUntilIdle();
1393 EXPECT_EQ(1, network_delegate()->completed_requests());
1394 EXPECT_EQ(0, host_
.pending_requests());
1397 TEST_F(ResourceDispatcherHostTest
, ThrottleAndResumeTwice
) {
1398 // Arrange to have requests deferred before starting.
1399 TestResourceDispatcherHostDelegate delegate
;
1400 delegate
.set_flags(DEFER_STARTING_REQUEST
);
1401 delegate
.set_create_two_throttles(true);
1402 host_
.SetDelegate(&delegate
);
1404 // Make sure the first throttle blocked the request, and then resume.
1405 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
1406 GenericResourceThrottle
* first_throttle
=
1407 GenericResourceThrottle::active_throttle();
1408 ASSERT_TRUE(first_throttle
);
1409 first_throttle
->Resume();
1411 // Make sure the second throttle blocked the request, and then resume.
1412 ASSERT_TRUE(GenericResourceThrottle::active_throttle());
1413 ASSERT_NE(first_throttle
, GenericResourceThrottle::active_throttle());
1414 GenericResourceThrottle::active_throttle()->Resume();
1416 ASSERT_FALSE(GenericResourceThrottle::active_throttle());
1418 // The request is started asynchronously.
1419 base::MessageLoop::current()->RunUntilIdle();
1421 // Flush all the pending requests.
1422 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1424 EXPECT_EQ(0, host_
.pending_requests());
1426 // Make sure the request completed successfully.
1427 ResourceIPCAccumulator::ClassifiedMessages msgs
;
1428 accum_
.GetClassifiedMessages(&msgs
);
1429 ASSERT_EQ(1U, msgs
.size());
1430 CheckSuccessfulRequest(msgs
[0], net::URLRequestTestJob::test_data_1());
1434 // Tests that the delegate can cancel a request and provide a error code.
1435 TEST_F(ResourceDispatcherHostTest
, CancelInDelegate
) {
1436 TestResourceDispatcherHostDelegate delegate
;
1437 delegate
.set_flags(CANCEL_BEFORE_START
);
1438 delegate
.set_error_code_for_cancellation(net::ERR_ACCESS_DENIED
);
1439 host_
.SetDelegate(&delegate
);
1441 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
1442 // The request will get cancelled by the throttle.
1444 // flush all the pending requests
1445 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1446 base::MessageLoop::current()->RunUntilIdle();
1448 ResourceIPCAccumulator::ClassifiedMessages msgs
;
1449 accum_
.GetClassifiedMessages(&msgs
);
1451 // Check the cancellation
1452 ASSERT_EQ(1U, msgs
.size());
1453 ASSERT_EQ(1U, msgs
[0].size());
1455 CheckRequestCompleteErrorCode(msgs
[0][0], net::ERR_ACCESS_DENIED
);
1458 // Tests CancelRequestsForProcess
1459 TEST_F(ResourceDispatcherHostTest
, TestProcessCancel
) {
1460 scoped_refptr
<TestFilter
> test_filter
= new TestFilter(
1461 browser_context_
->GetResourceContext());
1462 child_ids_
.insert(test_filter
->child_id());
1464 // request 1 goes to the test delegate
1465 ResourceHostMsg_Request request
= CreateResourceRequest(
1466 "GET", RESOURCE_TYPE_SUB_RESOURCE
, net::URLRequestTestJob::test_url_1());
1468 MakeTestRequestWithResourceType(test_filter
.get(), 0, 1,
1469 net::URLRequestTestJob::test_url_1(),
1470 RESOURCE_TYPE_SUB_RESOURCE
);
1472 // request 2 goes to us
1473 MakeTestRequest(0, 2, net::URLRequestTestJob::test_url_2());
1475 // request 3 goes to the test delegate
1476 MakeTestRequestWithResourceType(test_filter
.get(), 0, 3,
1477 net::URLRequestTestJob::test_url_3(),
1478 RESOURCE_TYPE_SUB_RESOURCE
);
1480 // request 4 goes to us
1481 MakeTestRequestWithResourceType(filter_
.get(), 0, 4,
1482 net::URLRequestTestJob::test_url_4(),
1483 RESOURCE_TYPE_PREFETCH
); // detachable type
1486 // Make sure all requests have finished stage one. test_url_1 will have
1488 base::MessageLoop::current()->RunUntilIdle();
1491 // Now that the async IO path is in place, the IO always completes on the
1492 // initial call; so the requests have already completed. This basically
1493 // breaks the whole test.
1494 //EXPECT_EQ(3, host_.pending_requests());
1496 // Process test_url_2 and test_url_3 for one level so one callback is called.
1497 // We'll cancel test_url_4 (detachable) before processing it to verify that it
1498 // delays the cancel.
1499 for (int i
= 0; i
< 2; i
++)
1500 EXPECT_TRUE(net::URLRequestTestJob::ProcessOnePendingMessage());
1502 // Cancel the requests to the test process.
1503 host_
.CancelRequestsForProcess(filter_
->child_id());
1504 test_filter
->set_canceled(true);
1506 // The requests should all be cancelled, except request 4, which is detached.
1507 EXPECT_EQ(1, host_
.pending_requests());
1508 GlobalRequestID
global_request_id(filter_
->child_id(), 4);
1509 ResourceRequestInfoImpl
* info
= ResourceRequestInfoImpl::ForRequest(
1510 host_
.GetURLRequest(global_request_id
));
1511 ASSERT_TRUE(info
->detachable_handler()->is_detached());
1513 // Flush all the pending requests.
1514 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1516 EXPECT_EQ(0, host_
.pending_requests());
1518 // The test delegate should not have gotten any messages after being canceled.
1519 ASSERT_EQ(0, test_filter
->received_after_canceled());
1521 // There should be two results.
1522 ResourceIPCAccumulator::ClassifiedMessages msgs
;
1523 accum_
.GetClassifiedMessages(&msgs
);
1524 ASSERT_EQ(2U, msgs
.size());
1525 CheckSuccessfulRequest(msgs
[0], net::URLRequestTestJob::test_data_2());
1526 // The detachable request was cancelled by the renderer before it
1527 // finished. From the perspective of the renderer, it should have cancelled.
1528 ASSERT_EQ(2U, msgs
[1].size());
1529 ASSERT_EQ(ResourceMsg_ReceivedResponse::ID
, msgs
[1][0].type());
1530 CheckRequestCompleteErrorCode(msgs
[1][1], net::ERR_ABORTED
);
1531 // But it completed anyway. For the network stack, no requests were canceled.
1532 EXPECT_EQ(4, network_delegate()->completed_requests());
1533 EXPECT_EQ(0, network_delegate()->canceled_requests());
1534 EXPECT_EQ(0, network_delegate()->error_count());
1537 TEST_F(ResourceDispatcherHostTest
, TestProcessCancelDetachedTimesOut
) {
1538 MakeTestRequestWithResourceType(filter_
.get(), 0, 1,
1539 net::URLRequestTestJob::test_url_4(),
1540 RESOURCE_TYPE_PREFETCH
); // detachable type
1541 GlobalRequestID
global_request_id(filter_
->child_id(), 1);
1542 ResourceRequestInfoImpl
* info
= ResourceRequestInfoImpl::ForRequest(
1543 host_
.GetURLRequest(global_request_id
));
1544 ASSERT_TRUE(info
->detachable_handler());
1545 info
->detachable_handler()->set_cancel_delay(
1546 base::TimeDelta::FromMilliseconds(200));
1547 base::MessageLoop::current()->RunUntilIdle();
1549 // Cancel the requests to the test process.
1550 host_
.CancelRequestsForProcess(filter_
->child_id());
1551 EXPECT_EQ(1, host_
.pending_requests());
1553 // Wait until after the delay timer times out before we start processing any
1555 base::OneShotTimer
<base::MessageLoop
> timer
;
1556 timer
.Start(FROM_HERE
, base::TimeDelta::FromMilliseconds(210),
1557 base::MessageLoop::current(), &base::MessageLoop::QuitWhenIdle
);
1558 base::MessageLoop::current()->Run();
1560 // The prefetch should be cancelled by now.
1561 EXPECT_EQ(0, host_
.pending_requests());
1563 // In case any messages are still to be processed.
1564 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1565 base::MessageLoop::current()->RunUntilIdle();
1567 ResourceIPCAccumulator::ClassifiedMessages msgs
;
1568 accum_
.GetClassifiedMessages(&msgs
);
1570 ASSERT_EQ(1U, msgs
.size());
1572 // The request should have cancelled.
1573 ASSERT_EQ(2U, msgs
[0].size());
1574 ASSERT_EQ(ResourceMsg_ReceivedResponse::ID
, msgs
[0][0].type());
1575 CheckRequestCompleteErrorCode(msgs
[0][1], net::ERR_ABORTED
);
1576 // And not run to completion.
1577 EXPECT_EQ(1, network_delegate()->completed_requests());
1578 EXPECT_EQ(1, network_delegate()->canceled_requests());
1579 EXPECT_EQ(0, network_delegate()->error_count());
1582 // Tests blocking and resuming requests.
1583 TEST_F(ResourceDispatcherHostTest
, TestBlockingResumingRequests
) {
1584 host_
.BlockRequestsForRoute(filter_
->child_id(), 1);
1585 host_
.BlockRequestsForRoute(filter_
->child_id(), 2);
1586 host_
.BlockRequestsForRoute(filter_
->child_id(), 3);
1588 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
1589 MakeTestRequest(1, 2, net::URLRequestTestJob::test_url_2());
1590 MakeTestRequest(0, 3, net::URLRequestTestJob::test_url_3());
1591 MakeTestRequest(1, 4, net::URLRequestTestJob::test_url_1());
1592 MakeTestRequest(2, 5, net::URLRequestTestJob::test_url_2());
1593 MakeTestRequest(3, 6, net::URLRequestTestJob::test_url_3());
1595 // Flush all the pending requests
1596 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1598 // Sort out all the messages we saw by request
1599 ResourceIPCAccumulator::ClassifiedMessages msgs
;
1600 accum_
.GetClassifiedMessages(&msgs
);
1602 // All requests but the 2 for the RVH 0 should have been blocked.
1603 ASSERT_EQ(2U, msgs
.size());
1605 CheckSuccessfulRequest(msgs
[0], net::URLRequestTestJob::test_data_1());
1606 CheckSuccessfulRequest(msgs
[1], net::URLRequestTestJob::test_data_3());
1608 // Resume requests for RVH 1 and flush pending requests.
1609 host_
.ResumeBlockedRequestsForRoute(filter_
->child_id(), 1);
1611 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1614 accum_
.GetClassifiedMessages(&msgs
);
1615 ASSERT_EQ(2U, msgs
.size());
1616 CheckSuccessfulRequest(msgs
[0], net::URLRequestTestJob::test_data_2());
1617 CheckSuccessfulRequest(msgs
[1], net::URLRequestTestJob::test_data_1());
1619 // Test that new requests are not blocked for RVH 1.
1620 MakeTestRequest(1, 7, net::URLRequestTestJob::test_url_1());
1621 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1623 accum_
.GetClassifiedMessages(&msgs
);
1624 ASSERT_EQ(1U, msgs
.size());
1625 CheckSuccessfulRequest(msgs
[0], net::URLRequestTestJob::test_data_1());
1627 // Now resumes requests for all RVH (2 and 3).
1628 host_
.ResumeBlockedRequestsForRoute(filter_
->child_id(), 2);
1629 host_
.ResumeBlockedRequestsForRoute(filter_
->child_id(), 3);
1631 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1634 accum_
.GetClassifiedMessages(&msgs
);
1635 ASSERT_EQ(2U, msgs
.size());
1636 CheckSuccessfulRequest(msgs
[0], net::URLRequestTestJob::test_data_2());
1637 CheckSuccessfulRequest(msgs
[1], net::URLRequestTestJob::test_data_3());
1640 // Tests blocking and canceling requests.
1641 TEST_F(ResourceDispatcherHostTest
, TestBlockingCancelingRequests
) {
1642 host_
.BlockRequestsForRoute(filter_
->child_id(), 1);
1644 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
1645 MakeTestRequest(1, 2, net::URLRequestTestJob::test_url_2());
1646 MakeTestRequest(0, 3, net::URLRequestTestJob::test_url_3());
1647 MakeTestRequest(1, 4, net::URLRequestTestJob::test_url_1());
1648 // Blocked detachable resources should not delay cancellation.
1649 MakeTestRequestWithResourceType(filter_
.get(), 1, 5,
1650 net::URLRequestTestJob::test_url_4(),
1651 RESOURCE_TYPE_PREFETCH
); // detachable type
1653 // Flush all the pending requests.
1654 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1656 // Sort out all the messages we saw by request.
1657 ResourceIPCAccumulator::ClassifiedMessages msgs
;
1658 accum_
.GetClassifiedMessages(&msgs
);
1660 // The 2 requests for the RVH 0 should have been processed.
1661 ASSERT_EQ(2U, msgs
.size());
1663 CheckSuccessfulRequest(msgs
[0], net::URLRequestTestJob::test_data_1());
1664 CheckSuccessfulRequest(msgs
[1], net::URLRequestTestJob::test_data_3());
1666 // Cancel requests for RVH 1.
1667 host_
.CancelBlockedRequestsForRoute(filter_
->child_id(), 1);
1669 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1672 accum_
.GetClassifiedMessages(&msgs
);
1673 ASSERT_EQ(0U, msgs
.size());
1676 // Tests that blocked requests are canceled if their associated process dies.
1677 TEST_F(ResourceDispatcherHostTest
, TestBlockedRequestsProcessDies
) {
1678 // This second filter is used to emulate a second process.
1679 scoped_refptr
<ForwardingFilter
> second_filter
= MakeForwardingFilter();
1681 host_
.BlockRequestsForRoute(second_filter
->child_id(), 0);
1683 MakeTestRequestWithResourceType(filter_
.get(), 0, 1,
1684 net::URLRequestTestJob::test_url_1(),
1685 RESOURCE_TYPE_SUB_RESOURCE
);
1686 MakeTestRequestWithResourceType(second_filter
.get(), 0, 2,
1687 net::URLRequestTestJob::test_url_2(),
1688 RESOURCE_TYPE_SUB_RESOURCE
);
1689 MakeTestRequestWithResourceType(filter_
.get(), 0, 3,
1690 net::URLRequestTestJob::test_url_3(),
1691 RESOURCE_TYPE_SUB_RESOURCE
);
1692 MakeTestRequestWithResourceType(second_filter
.get(), 0, 4,
1693 net::URLRequestTestJob::test_url_1(),
1694 RESOURCE_TYPE_SUB_RESOURCE
);
1695 MakeTestRequestWithResourceType(second_filter
.get(), 0, 5,
1696 net::URLRequestTestJob::test_url_4(),
1697 RESOURCE_TYPE_PREFETCH
); // detachable type
1699 // Simulate process death.
1700 host_
.CancelRequestsForProcess(second_filter
->child_id());
1702 // Flush all the pending requests.
1703 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1705 // Sort out all the messages we saw by request.
1706 ResourceIPCAccumulator::ClassifiedMessages msgs
;
1707 accum_
.GetClassifiedMessages(&msgs
);
1709 // The 2 requests for the RVH 0 should have been processed. Note that
1710 // blocked detachable requests are canceled without delay.
1711 ASSERT_EQ(2U, msgs
.size());
1713 CheckSuccessfulRequest(msgs
[0], net::URLRequestTestJob::test_data_1());
1714 CheckSuccessfulRequest(msgs
[1], net::URLRequestTestJob::test_data_3());
1716 EXPECT_TRUE(host_
.blocked_loaders_map_
.empty());
1719 // Tests that blocked requests don't leak when the ResourceDispatcherHost goes
1720 // away. Note that we rely on Purify for finding the leaks if any.
1721 // If this test turns the Purify bot red, check the ResourceDispatcherHost
1722 // destructor to make sure the blocked requests are deleted.
1723 TEST_F(ResourceDispatcherHostTest
, TestBlockedRequestsDontLeak
) {
1724 // This second filter is used to emulate a second process.
1725 scoped_refptr
<ForwardingFilter
> second_filter
= MakeForwardingFilter();
1727 host_
.BlockRequestsForRoute(filter_
->child_id(), 1);
1728 host_
.BlockRequestsForRoute(filter_
->child_id(), 2);
1729 host_
.BlockRequestsForRoute(second_filter
->child_id(), 1);
1731 MakeTestRequestWithResourceType(filter_
.get(), 0, 1,
1732 net::URLRequestTestJob::test_url_1(),
1733 RESOURCE_TYPE_SUB_RESOURCE
);
1734 MakeTestRequestWithResourceType(filter_
.get(), 1, 2,
1735 net::URLRequestTestJob::test_url_2(),
1736 RESOURCE_TYPE_SUB_RESOURCE
);
1737 MakeTestRequestWithResourceType(filter_
.get(), 0, 3,
1738 net::URLRequestTestJob::test_url_3(),
1739 RESOURCE_TYPE_SUB_RESOURCE
);
1740 MakeTestRequestWithResourceType(second_filter
.get(), 1, 4,
1741 net::URLRequestTestJob::test_url_1(),
1742 RESOURCE_TYPE_SUB_RESOURCE
);
1743 MakeTestRequestWithResourceType(filter_
.get(), 2, 5,
1744 net::URLRequestTestJob::test_url_2(),
1745 RESOURCE_TYPE_SUB_RESOURCE
);
1746 MakeTestRequestWithResourceType(filter_
.get(), 2, 6,
1747 net::URLRequestTestJob::test_url_3(),
1748 RESOURCE_TYPE_SUB_RESOURCE
);
1749 MakeTestRequestWithResourceType(filter_
.get(), 0, 7,
1750 net::URLRequestTestJob::test_url_4(),
1751 RESOURCE_TYPE_PREFETCH
); // detachable type
1752 MakeTestRequestWithResourceType(second_filter
.get(), 1, 8,
1753 net::URLRequestTestJob::test_url_4(),
1754 RESOURCE_TYPE_PREFETCH
); // detachable type
1756 host_
.CancelRequestsForProcess(filter_
->child_id());
1757 host_
.CancelRequestsForProcess(second_filter
->child_id());
1759 // Flush all the pending requests.
1760 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1763 // Test the private helper method "CalculateApproximateMemoryCost()".
1764 TEST_F(ResourceDispatcherHostTest
, CalculateApproximateMemoryCost
) {
1765 net::URLRequestContext context
;
1766 scoped_ptr
<net::URLRequest
> req(context
.CreateRequest(
1767 GURL("http://www.google.com"), net::DEFAULT_PRIORITY
, NULL
, NULL
));
1770 ResourceDispatcherHostImpl::CalculateApproximateMemoryCost(req
.get()));
1772 // Add 9 bytes of referrer.
1773 req
->SetReferrer("123456789");
1776 ResourceDispatcherHostImpl::CalculateApproximateMemoryCost(req
.get()));
1778 // Add 33 bytes of upload content.
1779 std::string upload_content
;
1780 upload_content
.resize(33);
1781 std::fill(upload_content
.begin(), upload_content
.end(), 'x');
1782 scoped_ptr
<net::UploadElementReader
> reader(new net::UploadBytesElementReader(
1783 upload_content
.data(), upload_content
.size()));
1785 net::ElementsUploadDataStream::CreateWithReader(reader
.Pass(), 0));
1787 // Since the upload throttling is disabled, this has no effect on the cost.
1790 ResourceDispatcherHostImpl::CalculateApproximateMemoryCost(req
.get()));
1793 // Test that too much memory for outstanding requests for a particular
1794 // render_process_host_id causes requests to fail.
1795 TEST_F(ResourceDispatcherHostTest
, TooMuchOutstandingRequestsMemory
) {
1796 // Expected cost of each request as measured by
1797 // ResourceDispatcherHost::CalculateApproximateMemoryCost().
1798 int kMemoryCostOfTest2Req
=
1799 ResourceDispatcherHostImpl::kAvgBytesPerOutstandingRequest
+
1800 std::string("GET").size() +
1801 net::URLRequestTestJob::test_url_2().spec().size();
1803 // Tighten the bound on the ResourceDispatcherHost, to speed things up.
1804 int kMaxCostPerProcess
= 440000;
1805 host_
.set_max_outstanding_requests_cost_per_process(kMaxCostPerProcess
);
1807 // Determine how many instance of test_url_2() we can request before
1808 // throttling kicks in.
1809 size_t kMaxRequests
= kMaxCostPerProcess
/ kMemoryCostOfTest2Req
;
1811 // This second filter is used to emulate a second process.
1812 scoped_refptr
<ForwardingFilter
> second_filter
= MakeForwardingFilter();
1814 // Saturate the number of outstanding requests for our process.
1815 for (size_t i
= 0; i
< kMaxRequests
; ++i
) {
1816 MakeTestRequestWithResourceType(filter_
.get(), 0, i
+ 1,
1817 net::URLRequestTestJob::test_url_2(),
1818 RESOURCE_TYPE_SUB_RESOURCE
);
1821 // Issue two more requests for our process -- these should fail immediately.
1822 MakeTestRequestWithResourceType(filter_
.get(), 0, kMaxRequests
+ 1,
1823 net::URLRequestTestJob::test_url_2(),
1824 RESOURCE_TYPE_SUB_RESOURCE
);
1825 MakeTestRequestWithResourceType(filter_
.get(), 0, kMaxRequests
+ 2,
1826 net::URLRequestTestJob::test_url_2(),
1827 RESOURCE_TYPE_SUB_RESOURCE
);
1829 // Issue two requests for the second process -- these should succeed since
1830 // it is just process 0 that is saturated.
1831 MakeTestRequestWithResourceType(second_filter
.get(), 0, kMaxRequests
+ 3,
1832 net::URLRequestTestJob::test_url_2(),
1833 RESOURCE_TYPE_SUB_RESOURCE
);
1834 MakeTestRequestWithResourceType(second_filter
.get(), 0, kMaxRequests
+ 4,
1835 net::URLRequestTestJob::test_url_2(),
1836 RESOURCE_TYPE_SUB_RESOURCE
);
1838 // Flush all the pending requests.
1839 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1840 base::MessageLoop::current()->RunUntilIdle();
1842 // Sorts out all the messages we saw by request.
1843 ResourceIPCAccumulator::ClassifiedMessages msgs
;
1844 accum_
.GetClassifiedMessages(&msgs
);
1846 // We issued (kMaxRequests + 4) total requests.
1847 ASSERT_EQ(kMaxRequests
+ 4, msgs
.size());
1849 // Check that the first kMaxRequests succeeded.
1850 for (size_t i
= 0; i
< kMaxRequests
; ++i
)
1851 CheckSuccessfulRequest(msgs
[i
], net::URLRequestTestJob::test_data_2());
1853 // Check that the subsequent two requests (kMaxRequests + 1) and
1854 // (kMaxRequests + 2) were failed, since the per-process bound was reached.
1855 for (int i
= 0; i
< 2; ++i
) {
1856 // Should have sent a single RequestComplete message.
1857 int index
= kMaxRequests
+ i
;
1858 CheckFailedRequest(msgs
[index
], net::URLRequestTestJob::test_data_2(),
1859 net::ERR_INSUFFICIENT_RESOURCES
);
1862 // The final 2 requests should have succeeded.
1863 CheckSuccessfulRequest(msgs
[kMaxRequests
+ 2],
1864 net::URLRequestTestJob::test_data_2());
1865 CheckSuccessfulRequest(msgs
[kMaxRequests
+ 3],
1866 net::URLRequestTestJob::test_data_2());
1869 // Test that when too many requests are outstanding for a particular
1870 // render_process_host_id, any subsequent request from it fails. Also verify
1871 // that the global limit is honored.
1872 TEST_F(ResourceDispatcherHostTest
, TooManyOutstandingRequests
) {
1873 // Tighten the bound on the ResourceDispatcherHost, to speed things up.
1874 const size_t kMaxRequestsPerProcess
= 2;
1875 host_
.set_max_num_in_flight_requests_per_process(kMaxRequestsPerProcess
);
1876 const size_t kMaxRequests
= 3;
1877 host_
.set_max_num_in_flight_requests(kMaxRequests
);
1879 // Needed to emulate additional processes.
1880 scoped_refptr
<ForwardingFilter
> second_filter
= MakeForwardingFilter();
1881 scoped_refptr
<ForwardingFilter
> third_filter
= MakeForwardingFilter();
1883 // Saturate the number of outstanding requests for our process.
1884 for (size_t i
= 0; i
< kMaxRequestsPerProcess
; ++i
) {
1885 MakeTestRequestWithResourceType(filter_
.get(), 0, i
+ 1,
1886 net::URLRequestTestJob::test_url_2(),
1887 RESOURCE_TYPE_SUB_RESOURCE
);
1890 // Issue another request for our process -- this should fail immediately.
1891 MakeTestRequestWithResourceType(filter_
.get(), 0, kMaxRequestsPerProcess
+ 1,
1892 net::URLRequestTestJob::test_url_2(),
1893 RESOURCE_TYPE_SUB_RESOURCE
);
1895 // Issue a request for the second process -- this should succeed, because it
1896 // is just process 0 that is saturated.
1897 MakeTestRequestWithResourceType(
1898 second_filter
.get(), 0, kMaxRequestsPerProcess
+ 2,
1899 net::URLRequestTestJob::test_url_2(), RESOURCE_TYPE_SUB_RESOURCE
);
1901 // Issue a request for the third process -- this should fail, because the
1902 // global limit has been reached.
1903 MakeTestRequestWithResourceType(
1904 third_filter
.get(), 0, kMaxRequestsPerProcess
+ 3,
1905 net::URLRequestTestJob::test_url_2(), RESOURCE_TYPE_SUB_RESOURCE
);
1907 // Flush all the pending requests.
1908 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1909 base::MessageLoop::current()->RunUntilIdle();
1911 // Sorts out all the messages we saw by request.
1912 ResourceIPCAccumulator::ClassifiedMessages msgs
;
1913 accum_
.GetClassifiedMessages(&msgs
);
1915 // The processes issued the following requests:
1916 // #1 issued kMaxRequestsPerProcess that passed + 1 that failed
1917 // #2 issued 1 request that passed
1918 // #3 issued 1 request that failed
1919 ASSERT_EQ((kMaxRequestsPerProcess
+ 1) + 1 + 1, msgs
.size());
1921 for (size_t i
= 0; i
< kMaxRequestsPerProcess
; ++i
)
1922 CheckSuccessfulRequest(msgs
[i
], net::URLRequestTestJob::test_data_2());
1924 CheckFailedRequest(msgs
[kMaxRequestsPerProcess
+ 0],
1925 net::URLRequestTestJob::test_data_2(),
1926 net::ERR_INSUFFICIENT_RESOURCES
);
1927 CheckSuccessfulRequest(msgs
[kMaxRequestsPerProcess
+ 1],
1928 net::URLRequestTestJob::test_data_2());
1929 CheckFailedRequest(msgs
[kMaxRequestsPerProcess
+ 2],
1930 net::URLRequestTestJob::test_data_2(),
1931 net::ERR_INSUFFICIENT_RESOURCES
);
1934 // Tests that we sniff the mime type for a simple request.
1935 TEST_F(ResourceDispatcherHostTest
, MimeSniffed
) {
1936 std::string
raw_headers("HTTP/1.1 200 OK\n\n");
1937 std::string
response_data("<html><title>Test One</title></html>");
1938 SetResponse(raw_headers
, response_data
);
1940 HandleScheme("http");
1941 MakeTestRequest(0, 1, GURL("http:bla"));
1943 // Flush all pending requests.
1944 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1946 // Sorts out all the messages we saw by request.
1947 ResourceIPCAccumulator::ClassifiedMessages msgs
;
1948 accum_
.GetClassifiedMessages(&msgs
);
1949 ASSERT_EQ(1U, msgs
.size());
1951 ResourceResponseHead response_head
;
1952 GetResponseHead(msgs
[0], &response_head
);
1953 ASSERT_EQ("text/html", response_head
.mime_type
);
1956 // Tests that we don't sniff the mime type when the server provides one.
1957 TEST_F(ResourceDispatcherHostTest
, MimeNotSniffed
) {
1958 std::string
raw_headers("HTTP/1.1 200 OK\n"
1959 "Content-type: image/jpeg\n\n");
1960 std::string
response_data("<html><title>Test One</title></html>");
1961 SetResponse(raw_headers
, response_data
);
1963 HandleScheme("http");
1964 MakeTestRequest(0, 1, GURL("http:bla"));
1966 // Flush all pending requests.
1967 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1969 // Sorts out all the messages we saw by request.
1970 ResourceIPCAccumulator::ClassifiedMessages msgs
;
1971 accum_
.GetClassifiedMessages(&msgs
);
1972 ASSERT_EQ(1U, msgs
.size());
1974 ResourceResponseHead response_head
;
1975 GetResponseHead(msgs
[0], &response_head
);
1976 ASSERT_EQ("image/jpeg", response_head
.mime_type
);
1979 // Tests that we don't sniff the mime type when there is no message body.
1980 TEST_F(ResourceDispatcherHostTest
, MimeNotSniffed2
) {
1981 SetResponse("HTTP/1.1 304 Not Modified\n\n");
1983 HandleScheme("http");
1984 MakeTestRequest(0, 1, GURL("http:bla"));
1986 // Flush all pending requests.
1987 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1989 // Sorts out all the messages we saw by request.
1990 ResourceIPCAccumulator::ClassifiedMessages msgs
;
1991 accum_
.GetClassifiedMessages(&msgs
);
1992 ASSERT_EQ(1U, msgs
.size());
1994 ResourceResponseHead response_head
;
1995 GetResponseHead(msgs
[0], &response_head
);
1996 ASSERT_EQ("", response_head
.mime_type
);
1999 TEST_F(ResourceDispatcherHostTest
, MimeSniff204
) {
2000 SetResponse("HTTP/1.1 204 No Content\n\n");
2002 HandleScheme("http");
2003 MakeTestRequest(0, 1, GURL("http:bla"));
2005 // Flush all pending requests.
2006 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2008 // Sorts out all the messages we saw by request.
2009 ResourceIPCAccumulator::ClassifiedMessages msgs
;
2010 accum_
.GetClassifiedMessages(&msgs
);
2011 ASSERT_EQ(1U, msgs
.size());
2013 ResourceResponseHead response_head
;
2014 GetResponseHead(msgs
[0], &response_head
);
2015 ASSERT_EQ("text/plain", response_head
.mime_type
);
2018 TEST_F(ResourceDispatcherHostTest
, MimeSniffEmpty
) {
2019 SetResponse("HTTP/1.1 200 OK\n\n");
2021 HandleScheme("http");
2022 MakeTestRequest(0, 1, GURL("http:bla"));
2024 // Flush all pending requests.
2025 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2027 // Sorts out all the messages we saw by request.
2028 ResourceIPCAccumulator::ClassifiedMessages msgs
;
2029 accum_
.GetClassifiedMessages(&msgs
);
2030 ASSERT_EQ(1U, msgs
.size());
2032 ResourceResponseHead response_head
;
2033 GetResponseHead(msgs
[0], &response_head
);
2034 ASSERT_EQ("text/plain", response_head
.mime_type
);
2037 // Tests for crbug.com/31266 (Non-2xx + application/octet-stream).
2038 TEST_F(ResourceDispatcherHostTest
, ForbiddenDownload
) {
2039 std::string
raw_headers("HTTP/1.1 403 Forbidden\n"
2040 "Content-disposition: attachment; filename=blah\n"
2041 "Content-type: application/octet-stream\n\n");
2042 std::string
response_data("<html><title>Test One</title></html>");
2043 SetResponse(raw_headers
, response_data
);
2045 HandleScheme("http");
2047 // Only MAIN_FRAMEs can trigger a download.
2048 MakeTestRequestWithResourceType(filter_
.get(), 0, 1, GURL("http:bla"),
2049 RESOURCE_TYPE_MAIN_FRAME
);
2051 // Flush all pending requests.
2052 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2053 base::MessageLoop::current()->RunUntilIdle();
2055 // Sorts out all the messages we saw by request.
2056 ResourceIPCAccumulator::ClassifiedMessages msgs
;
2057 accum_
.GetClassifiedMessages(&msgs
);
2059 // We should have gotten one RequestComplete message.
2060 ASSERT_EQ(1U, msgs
.size());
2061 ASSERT_EQ(1U, msgs
[0].size());
2062 EXPECT_EQ(ResourceMsg_RequestComplete::ID
, msgs
[0][0].type());
2064 // The RequestComplete message should have had the error code of
2065 // ERR_INVALID_RESPONSE.
2066 CheckRequestCompleteErrorCode(msgs
[0][0], net::ERR_INVALID_RESPONSE
);
2069 // Test for http://crbug.com/76202 . We don't want to destroy a
2070 // download request prematurely when processing a cancellation from
2072 TEST_F(ResourceDispatcherHostTest
, IgnoreCancelForDownloads
) {
2073 EXPECT_EQ(0, host_
.pending_requests());
2075 int render_view_id
= 0;
2078 std::string
raw_headers("HTTP\n"
2079 "Content-disposition: attachment; filename=foo\n\n");
2080 std::string
response_data("01234567890123456789\x01foobar");
2082 // Get past sniffing metrics in the BufferedResourceHandler. Note that
2083 // if we don't get past the sniffing metrics, the result will be that
2084 // the BufferedResourceHandler won't have figured out that it's a download,
2085 // won't have constructed a DownloadResourceHandler, and and the request
2086 // will be successfully canceled below, failing the test.
2087 response_data
.resize(1025, ' ');
2089 SetResponse(raw_headers
, response_data
);
2090 job_factory_
->SetDelayedCompleteJobGeneration(true);
2091 HandleScheme("http");
2093 MakeTestRequestWithResourceType(filter_
.get(), render_view_id
, request_id
,
2094 GURL("http://example.com/blah"),
2095 RESOURCE_TYPE_MAIN_FRAME
);
2096 // Return some data so that the request is identified as a download
2097 // and the proper resource handlers are created.
2098 EXPECT_TRUE(net::URLRequestTestJob::ProcessOnePendingMessage());
2100 // And now simulate a cancellation coming from the renderer.
2101 ResourceHostMsg_CancelRequest
msg(request_id
);
2102 host_
.OnMessageReceived(msg
, filter_
.get());
2104 // Since the request had already started processing as a download,
2105 // the cancellation above should have been ignored and the request
2106 // should still be alive.
2107 EXPECT_EQ(1, host_
.pending_requests());
2109 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2112 TEST_F(ResourceDispatcherHostTest
, CancelRequestsForContext
) {
2113 EXPECT_EQ(0, host_
.pending_requests());
2115 int render_view_id
= 0;
2118 std::string
raw_headers("HTTP\n"
2119 "Content-disposition: attachment; filename=foo\n\n");
2120 std::string
response_data("01234567890123456789\x01foobar");
2121 // Get past sniffing metrics.
2122 response_data
.resize(1025, ' ');
2124 SetResponse(raw_headers
, response_data
);
2125 job_factory_
->SetDelayedCompleteJobGeneration(true);
2126 HandleScheme("http");
2128 MakeTestRequestWithResourceType(filter_
.get(), render_view_id
, request_id
,
2129 GURL("http://example.com/blah"),
2130 RESOURCE_TYPE_MAIN_FRAME
);
2131 // Return some data so that the request is identified as a download
2132 // and the proper resource handlers are created.
2133 EXPECT_TRUE(net::URLRequestTestJob::ProcessOnePendingMessage());
2135 // And now simulate a cancellation coming from the renderer.
2136 ResourceHostMsg_CancelRequest
msg(request_id
);
2137 host_
.OnMessageReceived(msg
, filter_
.get());
2139 // Since the request had already started processing as a download,
2140 // the cancellation above should have been ignored and the request
2141 // should still be alive.
2142 EXPECT_EQ(1, host_
.pending_requests());
2144 // Cancelling by other methods shouldn't work either.
2145 host_
.CancelRequestsForProcess(render_view_id
);
2146 EXPECT_EQ(1, host_
.pending_requests());
2148 // Cancelling by context should work.
2149 host_
.CancelRequestsForContext(filter_
->resource_context());
2150 EXPECT_EQ(0, host_
.pending_requests());
2153 TEST_F(ResourceDispatcherHostTest
, CancelRequestsForContextDetached
) {
2154 EXPECT_EQ(0, host_
.pending_requests());
2156 int render_view_id
= 0;
2159 MakeTestRequestWithResourceType(filter_
.get(), render_view_id
, request_id
,
2160 net::URLRequestTestJob::test_url_4(),
2161 RESOURCE_TYPE_PREFETCH
); // detachable type
2163 // Simulate a cancel coming from the renderer.
2164 RendererCancelRequest(request_id
);
2166 // Since the request had already started processing as detachable,
2167 // the cancellation above should have been ignored and the request
2168 // should have been detached.
2169 EXPECT_EQ(1, host_
.pending_requests());
2171 // Cancelling by other methods should also leave it detached.
2172 host_
.CancelRequestsForProcess(render_view_id
);
2173 EXPECT_EQ(1, host_
.pending_requests());
2175 // Cancelling by context should work.
2176 host_
.CancelRequestsForContext(filter_
->resource_context());
2177 EXPECT_EQ(0, host_
.pending_requests());
2180 // Test the cancelling of requests that are being transferred to a new renderer
2181 // due to a redirection.
2182 TEST_F(ResourceDispatcherHostTest
, CancelRequestsForContextTransferred
) {
2183 EXPECT_EQ(0, host_
.pending_requests());
2185 int render_view_id
= 0;
2188 std::string
raw_headers("HTTP/1.1 200 OK\n"
2189 "Content-Type: text/html; charset=utf-8\n\n");
2190 std::string
response_data("<html>foobar</html>");
2192 SetResponse(raw_headers
, response_data
);
2193 HandleScheme("http");
2195 MakeTestRequestWithResourceType(filter_
.get(), render_view_id
, request_id
,
2196 GURL("http://example.com/blah"),
2197 RESOURCE_TYPE_MAIN_FRAME
);
2200 GlobalRequestID
global_request_id(filter_
->child_id(), request_id
);
2201 host_
.MarkAsTransferredNavigation(global_request_id
);
2203 // And now simulate a cancellation coming from the renderer.
2204 ResourceHostMsg_CancelRequest
msg(request_id
);
2205 host_
.OnMessageReceived(msg
, filter_
.get());
2207 // Since the request is marked as being transferred,
2208 // the cancellation above should have been ignored and the request
2209 // should still be alive.
2210 EXPECT_EQ(1, host_
.pending_requests());
2212 // Cancelling by other methods shouldn't work either.
2213 host_
.CancelRequestsForProcess(render_view_id
);
2214 EXPECT_EQ(1, host_
.pending_requests());
2216 // Cancelling by context should work.
2217 host_
.CancelRequestsForContext(filter_
->resource_context());
2218 EXPECT_EQ(0, host_
.pending_requests());
2221 // Test transferred navigations with text/html, which doesn't trigger any
2222 // content sniffing.
2223 TEST_F(ResourceDispatcherHostTest
, TransferNavigationHtml
) {
2224 // This test expects the cross site request to be leaked, so it can transfer
2225 // the request directly.
2226 CrossSiteResourceHandler::SetLeakRequestsForTesting(true);
2228 EXPECT_EQ(0, host_
.pending_requests());
2230 int render_view_id
= 0;
2233 // Configure initial request.
2234 SetResponse("HTTP/1.1 302 Found\n"
2235 "Location: http://other.com/blech\n\n");
2237 HandleScheme("http");
2239 // Temporarily replace ContentBrowserClient with one that will trigger the
2240 // transfer navigation code paths.
2241 TransfersAllNavigationsContentBrowserClient new_client
;
2242 ContentBrowserClient
* old_client
= SetBrowserClientForTesting(&new_client
);
2244 MakeTestRequestWithResourceType(filter_
.get(), render_view_id
, request_id
,
2245 GURL("http://example.com/blah"),
2246 RESOURCE_TYPE_MAIN_FRAME
);
2248 // Now that we're blocked on the redirect, update the response and unblock by
2249 // telling the AsyncResourceHandler to follow the redirect.
2250 const std::string kResponseBody
= "hello world";
2251 SetResponse("HTTP/1.1 200 OK\n"
2252 "Content-Type: text/html\n\n",
2254 ResourceHostMsg_FollowRedirect
redirect_msg(request_id
);
2255 host_
.OnMessageReceived(redirect_msg
, filter_
.get());
2256 base::MessageLoop::current()->RunUntilIdle();
2258 // Flush all the pending requests to get the response through the
2259 // BufferedResourceHandler.
2260 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2262 // Restore, now that we've set up a transfer.
2263 SetBrowserClientForTesting(old_client
);
2265 // This second filter is used to emulate a second process.
2266 scoped_refptr
<ForwardingFilter
> second_filter
= MakeForwardingFilter();
2268 int new_render_view_id
= 1;
2269 int new_request_id
= 2;
2271 ResourceHostMsg_Request request
=
2272 CreateResourceRequest("GET", RESOURCE_TYPE_MAIN_FRAME
,
2273 GURL("http://other.com/blech"));
2274 request
.transferred_request_child_id
= filter_
->child_id();
2275 request
.transferred_request_request_id
= request_id
;
2277 ResourceHostMsg_RequestResource
transfer_request_msg(
2278 new_render_view_id
, new_request_id
, request
);
2279 host_
.OnMessageReceived(transfer_request_msg
, second_filter
.get());
2280 base::MessageLoop::current()->RunUntilIdle();
2282 // Check generated messages.
2283 ResourceIPCAccumulator::ClassifiedMessages msgs
;
2284 accum_
.GetClassifiedMessages(&msgs
);
2286 ASSERT_EQ(2U, msgs
.size());
2287 EXPECT_EQ(ResourceMsg_ReceivedRedirect::ID
, msgs
[0][0].type());
2288 CheckSuccessfulRequest(msgs
[1], kResponseBody
);
2291 // Test transferring two navigations with text/html, to ensure the resource
2292 // accounting works.
2293 TEST_F(ResourceDispatcherHostTest
, TransferTwoNavigationsHtml
) {
2294 // This test expects the cross site request to be leaked, so it can transfer
2295 // the request directly.
2296 CrossSiteResourceHandler::SetLeakRequestsForTesting(true);
2298 EXPECT_EQ(0, host_
.pending_requests());
2300 int render_view_id
= 0;
2303 // Configure initial request.
2304 const std::string kResponseBody
= "hello world";
2305 SetResponse("HTTP/1.1 200 OK\n"
2306 "Content-Type: text/html\n\n",
2309 HandleScheme("http");
2311 // Temporarily replace ContentBrowserClient with one that will trigger the
2312 // transfer navigation code paths.
2313 TransfersAllNavigationsContentBrowserClient new_client
;
2314 ContentBrowserClient
* old_client
= SetBrowserClientForTesting(&new_client
);
2316 // Make the first request.
2317 MakeTestRequestWithResourceType(filter_
.get(), render_view_id
, request_id
,
2318 GURL("http://example.com/blah"),
2319 RESOURCE_TYPE_MAIN_FRAME
);
2321 // Make a second request from the same process.
2322 int second_request_id
= 2;
2323 MakeTestRequestWithResourceType(filter_
.get(), render_view_id
,
2325 GURL("http://example.com/foo"),
2326 RESOURCE_TYPE_MAIN_FRAME
);
2328 // Flush all the pending requests to get the response through the
2329 // BufferedResourceHandler.
2330 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2332 // Restore, now that we've set up a transfer.
2333 SetBrowserClientForTesting(old_client
);
2335 // This second filter is used to emulate a second process.
2336 scoped_refptr
<ForwardingFilter
> second_filter
= MakeForwardingFilter();
2338 // Transfer the first request.
2339 int new_render_view_id
= 1;
2340 int new_request_id
= 5;
2341 ResourceHostMsg_Request request
=
2342 CreateResourceRequest("GET", RESOURCE_TYPE_MAIN_FRAME
,
2343 GURL("http://example.com/blah"));
2344 request
.transferred_request_child_id
= filter_
->child_id();
2345 request
.transferred_request_request_id
= request_id
;
2347 ResourceHostMsg_RequestResource
transfer_request_msg(
2348 new_render_view_id
, new_request_id
, request
);
2349 host_
.OnMessageReceived(transfer_request_msg
, second_filter
.get());
2350 base::MessageLoop::current()->RunUntilIdle();
2352 // Transfer the second request.
2353 int new_second_request_id
= 6;
2354 ResourceHostMsg_Request second_request
=
2355 CreateResourceRequest("GET", RESOURCE_TYPE_MAIN_FRAME
,
2356 GURL("http://example.com/foo"));
2357 request
.transferred_request_child_id
= filter_
->child_id();
2358 request
.transferred_request_request_id
= second_request_id
;
2360 ResourceHostMsg_RequestResource
second_transfer_request_msg(
2361 new_render_view_id
, new_second_request_id
, second_request
);
2362 host_
.OnMessageReceived(second_transfer_request_msg
, second_filter
.get());
2363 base::MessageLoop::current()->RunUntilIdle();
2365 // Check generated messages.
2366 ResourceIPCAccumulator::ClassifiedMessages msgs
;
2367 accum_
.GetClassifiedMessages(&msgs
);
2369 ASSERT_EQ(2U, msgs
.size());
2370 CheckSuccessfulRequest(msgs
[0], kResponseBody
);
2373 // Test transferred navigations with text/plain, which causes
2374 // BufferedResourceHandler to buffer the response to sniff the content
2375 // before the transfer occurs.
2376 TEST_F(ResourceDispatcherHostTest
, TransferNavigationText
) {
2377 // This test expects the cross site request to be leaked, so it can transfer
2378 // the request directly.
2379 CrossSiteResourceHandler::SetLeakRequestsForTesting(true);
2381 EXPECT_EQ(0, host_
.pending_requests());
2383 int render_view_id
= 0;
2386 // Configure initial request.
2387 SetResponse("HTTP/1.1 302 Found\n"
2388 "Location: http://other.com/blech\n\n");
2390 HandleScheme("http");
2392 // Temporarily replace ContentBrowserClient with one that will trigger the
2393 // transfer navigation code paths.
2394 TransfersAllNavigationsContentBrowserClient new_client
;
2395 ContentBrowserClient
* old_client
= SetBrowserClientForTesting(&new_client
);
2397 MakeTestRequestWithResourceType(filter_
.get(), render_view_id
, request_id
,
2398 GURL("http://example.com/blah"),
2399 RESOURCE_TYPE_MAIN_FRAME
);
2401 // Now that we're blocked on the redirect, update the response and unblock by
2402 // telling the AsyncResourceHandler to follow the redirect. Use a text/plain
2403 // MIME type, which causes BufferedResourceHandler to buffer it before the
2405 const std::string kResponseBody
= "hello world";
2406 SetResponse("HTTP/1.1 200 OK\n"
2407 "Content-Type: text/plain\n\n",
2409 ResourceHostMsg_FollowRedirect
redirect_msg(request_id
);
2410 host_
.OnMessageReceived(redirect_msg
, filter_
.get());
2411 base::MessageLoop::current()->RunUntilIdle();
2413 // Flush all the pending requests to get the response through the
2414 // BufferedResourceHandler.
2415 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2417 // Restore, now that we've set up a transfer.
2418 SetBrowserClientForTesting(old_client
);
2420 // This second filter is used to emulate a second process.
2421 scoped_refptr
<ForwardingFilter
> second_filter
= MakeForwardingFilter();
2423 int new_render_view_id
= 1;
2424 int new_request_id
= 2;
2426 ResourceHostMsg_Request request
=
2427 CreateResourceRequest("GET", RESOURCE_TYPE_MAIN_FRAME
,
2428 GURL("http://other.com/blech"));
2429 request
.transferred_request_child_id
= filter_
->child_id();
2430 request
.transferred_request_request_id
= request_id
;
2432 ResourceHostMsg_RequestResource
transfer_request_msg(
2433 new_render_view_id
, new_request_id
, request
);
2434 host_
.OnMessageReceived(transfer_request_msg
, second_filter
.get());
2435 base::MessageLoop::current()->RunUntilIdle();
2437 // Check generated messages.
2438 ResourceIPCAccumulator::ClassifiedMessages msgs
;
2439 accum_
.GetClassifiedMessages(&msgs
);
2441 ASSERT_EQ(2U, msgs
.size());
2442 EXPECT_EQ(ResourceMsg_ReceivedRedirect::ID
, msgs
[0][0].type());
2443 CheckSuccessfulRequest(msgs
[1], kResponseBody
);
2446 TEST_F(ResourceDispatcherHostTest
, TransferNavigationWithProcessCrash
) {
2447 // This test expects the cross site request to be leaked, so it can transfer
2448 // the request directly.
2449 CrossSiteResourceHandler::SetLeakRequestsForTesting(true);
2451 EXPECT_EQ(0, host_
.pending_requests());
2453 int render_view_id
= 0;
2455 int first_child_id
= -1;
2457 // Configure initial request.
2458 SetResponse("HTTP/1.1 302 Found\n"
2459 "Location: http://other.com/blech\n\n");
2460 const std::string kResponseBody
= "hello world";
2462 HandleScheme("http");
2464 // Temporarily replace ContentBrowserClient with one that will trigger the
2465 // transfer navigation code paths.
2466 TransfersAllNavigationsContentBrowserClient new_client
;
2467 ContentBrowserClient
* old_client
= SetBrowserClientForTesting(&new_client
);
2469 // Create a first filter that can be deleted before the second one starts.
2471 scoped_refptr
<ForwardingFilter
> first_filter
= MakeForwardingFilter();
2472 first_child_id
= first_filter
->child_id();
2474 ResourceHostMsg_Request first_request
=
2475 CreateResourceRequest("GET", RESOURCE_TYPE_MAIN_FRAME
,
2476 GURL("http://example.com/blah"));
2478 ResourceHostMsg_RequestResource
first_request_msg(
2479 render_view_id
, request_id
, first_request
);
2480 host_
.OnMessageReceived(first_request_msg
, first_filter
.get());
2481 base::MessageLoop::current()->RunUntilIdle();
2483 // Now that we're blocked on the redirect, update the response and unblock
2484 // by telling the AsyncResourceHandler to follow the redirect.
2485 SetResponse("HTTP/1.1 200 OK\n"
2486 "Content-Type: text/html\n\n",
2488 ResourceHostMsg_FollowRedirect
redirect_msg(request_id
);
2489 host_
.OnMessageReceived(redirect_msg
, first_filter
.get());
2490 base::MessageLoop::current()->RunUntilIdle();
2492 // Flush all the pending requests to get the response through the
2493 // BufferedResourceHandler.
2494 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2496 // The first filter is now deleted, as if the child process died.
2499 SetBrowserClientForTesting(old_client
);
2501 // Make sure we don't hold onto the ResourceMessageFilter after it is deleted.
2502 GlobalRequestID
first_global_request_id(first_child_id
, request_id
);
2504 // This second filter is used to emulate a second process.
2505 scoped_refptr
<ForwardingFilter
> second_filter
= MakeForwardingFilter();
2507 int new_render_view_id
= 1;
2508 int new_request_id
= 2;
2510 ResourceHostMsg_Request request
=
2511 CreateResourceRequest("GET", RESOURCE_TYPE_MAIN_FRAME
,
2512 GURL("http://other.com/blech"));
2513 request
.transferred_request_child_id
= first_child_id
;
2514 request
.transferred_request_request_id
= request_id
;
2517 child_ids_
.insert(second_filter
->child_id());
2518 ResourceHostMsg_RequestResource
transfer_request_msg(
2519 new_render_view_id
, new_request_id
, request
);
2520 host_
.OnMessageReceived(transfer_request_msg
, second_filter
.get());
2521 base::MessageLoop::current()->RunUntilIdle();
2523 // Check generated messages.
2524 ResourceIPCAccumulator::ClassifiedMessages msgs
;
2525 accum_
.GetClassifiedMessages(&msgs
);
2527 ASSERT_EQ(2U, msgs
.size());
2528 EXPECT_EQ(ResourceMsg_ReceivedRedirect::ID
, msgs
[0][0].type());
2529 CheckSuccessfulRequest(msgs
[1], kResponseBody
);
2532 TEST_F(ResourceDispatcherHostTest
, TransferNavigationWithTwoRedirects
) {
2533 // This test expects the cross site request to be leaked, so it can transfer
2534 // the request directly.
2535 CrossSiteResourceHandler::SetLeakRequestsForTesting(true);
2537 EXPECT_EQ(0, host_
.pending_requests());
2539 int render_view_id
= 0;
2542 // Configure initial request.
2543 SetResponse("HTTP/1.1 302 Found\n"
2544 "Location: http://other.com/blech\n\n");
2546 HandleScheme("http");
2548 // Temporarily replace ContentBrowserClient with one that will trigger the
2549 // transfer navigation code paths.
2550 TransfersAllNavigationsContentBrowserClient new_client
;
2551 ContentBrowserClient
* old_client
= SetBrowserClientForTesting(&new_client
);
2553 MakeTestRequestWithResourceType(filter_
.get(), render_view_id
, request_id
,
2554 GURL("http://example.com/blah"),
2555 RESOURCE_TYPE_MAIN_FRAME
);
2557 // Now that we're blocked on the redirect, simulate hitting another redirect.
2558 SetResponse("HTTP/1.1 302 Found\n"
2559 "Location: http://other.com/blerg\n\n");
2560 ResourceHostMsg_FollowRedirect
redirect_msg(request_id
);
2561 host_
.OnMessageReceived(redirect_msg
, filter_
.get());
2562 base::MessageLoop::current()->RunUntilIdle();
2564 // Now that we're blocked on the second redirect, update the response and
2565 // unblock by telling the AsyncResourceHandler to follow the redirect.
2566 // Again, use text/plain to force BufferedResourceHandler to buffer before
2568 const std::string kResponseBody
= "hello world";
2569 SetResponse("HTTP/1.1 200 OK\n"
2570 "Content-Type: text/plain\n\n",
2572 ResourceHostMsg_FollowRedirect
redirect_msg2(request_id
);
2573 host_
.OnMessageReceived(redirect_msg2
, filter_
.get());
2574 base::MessageLoop::current()->RunUntilIdle();
2576 // Flush all the pending requests to get the response through the
2577 // BufferedResourceHandler.
2578 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2581 SetBrowserClientForTesting(old_client
);
2583 // This second filter is used to emulate a second process.
2584 scoped_refptr
<ForwardingFilter
> second_filter
= MakeForwardingFilter();
2586 int new_render_view_id
= 1;
2587 int new_request_id
= 2;
2589 ResourceHostMsg_Request request
=
2590 CreateResourceRequest("GET", RESOURCE_TYPE_MAIN_FRAME
,
2591 GURL("http://other.com/blech"));
2592 request
.transferred_request_child_id
= filter_
->child_id();
2593 request
.transferred_request_request_id
= request_id
;
2596 child_ids_
.insert(second_filter
->child_id());
2597 ResourceHostMsg_RequestResource
transfer_request_msg(
2598 new_render_view_id
, new_request_id
, request
);
2599 host_
.OnMessageReceived(transfer_request_msg
, second_filter
.get());
2601 // Verify that we update the ResourceRequestInfo.
2602 GlobalRequestID
global_request_id(second_filter
->child_id(), new_request_id
);
2603 const ResourceRequestInfoImpl
* info
= ResourceRequestInfoImpl::ForRequest(
2604 host_
.GetURLRequest(global_request_id
));
2605 EXPECT_EQ(second_filter
->child_id(), info
->GetChildID());
2606 EXPECT_EQ(new_render_view_id
, info
->GetRouteID());
2607 EXPECT_EQ(new_request_id
, info
->GetRequestID());
2608 EXPECT_EQ(second_filter
.get(), info
->filter());
2610 // Let request complete.
2611 base::MessageLoop::current()->RunUntilIdle();
2613 // Check generated messages.
2614 ResourceIPCAccumulator::ClassifiedMessages msgs
;
2615 accum_
.GetClassifiedMessages(&msgs
);
2617 ASSERT_EQ(2U, msgs
.size());
2618 EXPECT_EQ(ResourceMsg_ReceivedRedirect::ID
, msgs
[0][0].type());
2619 CheckSuccessfulRequest(msgs
[1], kResponseBody
);
2622 TEST_F(ResourceDispatcherHostTest
, UnknownURLScheme
) {
2623 EXPECT_EQ(0, host_
.pending_requests());
2625 HandleScheme("http");
2627 MakeTestRequestWithResourceType(filter_
.get(), 0, 1, GURL("foo://bar"),
2628 RESOURCE_TYPE_MAIN_FRAME
);
2630 // Flush all pending requests.
2631 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2633 // Sort all the messages we saw by request.
2634 ResourceIPCAccumulator::ClassifiedMessages msgs
;
2635 accum_
.GetClassifiedMessages(&msgs
);
2637 // We should have gotten one RequestComplete message.
2638 ASSERT_EQ(1U, msgs
[0].size());
2639 EXPECT_EQ(ResourceMsg_RequestComplete::ID
, msgs
[0][0].type());
2641 // The RequestComplete message should have the error code of
2642 // ERR_UNKNOWN_URL_SCHEME.
2643 CheckRequestCompleteErrorCode(msgs
[0][0], net::ERR_UNKNOWN_URL_SCHEME
);
2646 TEST_F(ResourceDispatcherHostTest
, DataReceivedACKs
) {
2647 EXPECT_EQ(0, host_
.pending_requests());
2649 SendDataReceivedACKs(true);
2651 HandleScheme("big-job");
2652 MakeTestRequest(0, 1, GURL("big-job:0123456789,1000000"));
2654 // Sort all the messages we saw by request.
2655 ResourceIPCAccumulator::ClassifiedMessages msgs
;
2656 accum_
.GetClassifiedMessages(&msgs
);
2658 size_t size
= msgs
[0].size();
2660 EXPECT_EQ(ResourceMsg_ReceivedResponse::ID
, msgs
[0][0].type());
2661 EXPECT_EQ(ResourceMsg_SetDataBuffer::ID
, msgs
[0][1].type());
2662 for (size_t i
= 2; i
< size
- 1; ++i
)
2663 EXPECT_EQ(ResourceMsg_DataReceived::ID
, msgs
[0][i
].type());
2664 EXPECT_EQ(ResourceMsg_RequestComplete::ID
, msgs
[0][size
- 1].type());
2667 // Request a very large detachable resource and cancel part way. Some of the
2668 // data should have been sent to the renderer, but not all.
2669 TEST_F(ResourceDispatcherHostTest
, DataSentBeforeDetach
) {
2670 EXPECT_EQ(0, host_
.pending_requests());
2672 int render_view_id
= 0;
2675 std::string
raw_headers("HTTP\n"
2676 "Content-type: image/jpeg\n\n");
2677 std::string
response_data("01234567890123456789\x01foobar");
2679 // Create a response larger than kMaxAllocationSize (currently 32K). Note
2680 // that if this increase beyond 512K we'll need to make the response longer.
2681 const int kAllocSize
= 1024*512;
2682 response_data
.resize(kAllocSize
, ' ');
2684 SetResponse(raw_headers
, response_data
);
2685 job_factory_
->SetDelayedCompleteJobGeneration(true);
2686 HandleScheme("http");
2688 MakeTestRequestWithResourceType(filter_
.get(), render_view_id
, request_id
,
2689 GURL("http://example.com/blah"),
2690 RESOURCE_TYPE_PREFETCH
);
2692 // Get a bit of data before cancelling.
2693 EXPECT_TRUE(net::URLRequestTestJob::ProcessOnePendingMessage());
2695 // Simulate a cancellation coming from the renderer.
2696 ResourceHostMsg_CancelRequest
msg(request_id
);
2697 host_
.OnMessageReceived(msg
, filter_
.get());
2699 EXPECT_EQ(1, host_
.pending_requests());
2701 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2703 // Sort all the messages we saw by request.
2704 ResourceIPCAccumulator::ClassifiedMessages msgs
;
2705 accum_
.GetClassifiedMessages(&msgs
);
2707 EXPECT_EQ(4U, msgs
[0].size());
2709 // Figure out how many bytes were received by the renderer.
2713 ExtractDataOffsetAndLength(msgs
[0][2], &data_offset
, &data_length
));
2714 EXPECT_LT(0, data_length
);
2715 EXPECT_GT(kAllocSize
, data_length
);
2717 // Verify the data that was received before cancellation. The request should
2718 // have appeared to cancel, however.
2719 CheckSuccessfulRequestWithErrorCode(
2721 std::string(response_data
.begin(), response_data
.begin() + data_length
),
2725 TEST_F(ResourceDispatcherHostTest
, DelayedDataReceivedACKs
) {
2726 EXPECT_EQ(0, host_
.pending_requests());
2728 HandleScheme("big-job");
2729 MakeTestRequest(0, 1, GURL("big-job:0123456789,1000000"));
2731 // Sort all the messages we saw by request.
2732 ResourceIPCAccumulator::ClassifiedMessages msgs
;
2733 accum_
.GetClassifiedMessages(&msgs
);
2735 // We expect 1x ReceivedResponse, 1x SetDataBuffer, Nx ReceivedData messages.
2736 EXPECT_EQ(ResourceMsg_ReceivedResponse::ID
, msgs
[0][0].type());
2737 EXPECT_EQ(ResourceMsg_SetDataBuffer::ID
, msgs
[0][1].type());
2738 for (size_t i
= 2; i
< msgs
[0].size(); ++i
)
2739 EXPECT_EQ(ResourceMsg_DataReceived::ID
, msgs
[0][i
].type());
2741 // NOTE: If we fail the above checks then it means that we probably didn't
2742 // load a big enough response to trigger the delay mechanism we are trying to
2745 msgs
[0].erase(msgs
[0].begin());
2746 msgs
[0].erase(msgs
[0].begin());
2748 // ACK all DataReceived messages until we find a RequestComplete message.
2749 bool complete
= false;
2751 for (size_t i
= 0; i
< msgs
[0].size(); ++i
) {
2752 if (msgs
[0][i
].type() == ResourceMsg_RequestComplete::ID
) {
2757 EXPECT_EQ(ResourceMsg_DataReceived::ID
, msgs
[0][i
].type());
2759 ResourceHostMsg_DataReceived_ACK
msg(1);
2760 host_
.OnMessageReceived(msg
, filter_
.get());
2763 base::MessageLoop::current()->RunUntilIdle();
2766 accum_
.GetClassifiedMessages(&msgs
);
2770 // Flakyness of this test might indicate memory corruption issues with
2771 // for example the ResourceBuffer of AsyncResourceHandler.
2772 TEST_F(ResourceDispatcherHostTest
, DataReceivedUnexpectedACKs
) {
2773 EXPECT_EQ(0, host_
.pending_requests());
2775 HandleScheme("big-job");
2776 MakeTestRequest(0, 1, GURL("big-job:0123456789,1000000"));
2778 // Sort all the messages we saw by request.
2779 ResourceIPCAccumulator::ClassifiedMessages msgs
;
2780 accum_
.GetClassifiedMessages(&msgs
);
2782 // We expect 1x ReceivedResponse, 1x SetDataBuffer, Nx ReceivedData messages.
2783 EXPECT_EQ(ResourceMsg_ReceivedResponse::ID
, msgs
[0][0].type());
2784 EXPECT_EQ(ResourceMsg_SetDataBuffer::ID
, msgs
[0][1].type());
2785 for (size_t i
= 2; i
< msgs
[0].size(); ++i
)
2786 EXPECT_EQ(ResourceMsg_DataReceived::ID
, msgs
[0][i
].type());
2788 // NOTE: If we fail the above checks then it means that we probably didn't
2789 // load a big enough response to trigger the delay mechanism.
2791 // Send some unexpected ACKs.
2792 for (size_t i
= 0; i
< 128; ++i
) {
2793 ResourceHostMsg_DataReceived_ACK
msg(1);
2794 host_
.OnMessageReceived(msg
, filter_
.get());
2797 msgs
[0].erase(msgs
[0].begin());
2798 msgs
[0].erase(msgs
[0].begin());
2800 // ACK all DataReceived messages until we find a RequestComplete message.
2801 bool complete
= false;
2803 for (size_t i
= 0; i
< msgs
[0].size(); ++i
) {
2804 if (msgs
[0][i
].type() == ResourceMsg_RequestComplete::ID
) {
2809 EXPECT_EQ(ResourceMsg_DataReceived::ID
, msgs
[0][i
].type());
2811 ResourceHostMsg_DataReceived_ACK
msg(1);
2812 host_
.OnMessageReceived(msg
, filter_
.get());
2815 base::MessageLoop::current()->RunUntilIdle();
2818 accum_
.GetClassifiedMessages(&msgs
);
2822 // Tests the dispatcher host's temporary file management.
2823 TEST_F(ResourceDispatcherHostTest
, RegisterDownloadedTempFile
) {
2824 const int kRequestID
= 1;
2826 // Create a temporary file.
2827 base::FilePath file_path
;
2828 ASSERT_TRUE(base::CreateTemporaryFile(&file_path
));
2829 scoped_refptr
<ShareableFileReference
> deletable_file
=
2830 ShareableFileReference::GetOrCreate(
2832 ShareableFileReference::DELETE_ON_FINAL_RELEASE
,
2833 BrowserThread::GetMessageLoopProxyForThread(
2834 BrowserThread::FILE).get());
2837 EXPECT_FALSE(ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
2838 filter_
->child_id(), file_path
));
2840 // Register it for a resource request.
2841 host_
.RegisterDownloadedTempFile(filter_
->child_id(), kRequestID
, file_path
);
2843 // Should be readable now.
2844 EXPECT_TRUE(ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
2845 filter_
->child_id(), file_path
));
2847 // The child releases from the request.
2848 ResourceHostMsg_ReleaseDownloadedFile
release_msg(kRequestID
);
2849 host_
.OnMessageReceived(release_msg
, filter_
.get());
2851 // Still readable because there is another reference to the file. (The child
2852 // may take additional blob references.)
2853 EXPECT_TRUE(ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
2854 filter_
->child_id(), file_path
));
2856 // Release extra references and wait for the file to be deleted. (This relies
2857 // on the delete happening on the FILE thread which is mapped to main thread
2859 deletable_file
= NULL
;
2860 base::RunLoop().RunUntilIdle();
2862 // The file is no longer readable to the child and has been deleted.
2863 EXPECT_FALSE(ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
2864 filter_
->child_id(), file_path
));
2865 EXPECT_FALSE(base::PathExists(file_path
));
2868 // Tests that temporary files held on behalf of child processes are released
2869 // when the child process dies.
2870 TEST_F(ResourceDispatcherHostTest
, ReleaseTemporiesOnProcessExit
) {
2871 const int kRequestID
= 1;
2873 // Create a temporary file.
2874 base::FilePath file_path
;
2875 ASSERT_TRUE(base::CreateTemporaryFile(&file_path
));
2876 scoped_refptr
<ShareableFileReference
> deletable_file
=
2877 ShareableFileReference::GetOrCreate(
2879 ShareableFileReference::DELETE_ON_FINAL_RELEASE
,
2880 BrowserThread::GetMessageLoopProxyForThread(
2881 BrowserThread::FILE).get());
2883 // Register it for a resource request.
2884 host_
.RegisterDownloadedTempFile(filter_
->child_id(), kRequestID
, file_path
);
2885 deletable_file
= NULL
;
2887 // Should be readable now.
2888 EXPECT_TRUE(ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
2889 filter_
->child_id(), file_path
));
2891 // Let the process die.
2892 filter_
->OnChannelClosing();
2893 base::RunLoop().RunUntilIdle();
2895 // The file is no longer readable to the child and has been deleted.
2896 EXPECT_FALSE(ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
2897 filter_
->child_id(), file_path
));
2898 EXPECT_FALSE(base::PathExists(file_path
));
2901 TEST_F(ResourceDispatcherHostTest
, DownloadToFile
) {
2902 // Make a request which downloads to file.
2903 ResourceHostMsg_Request request
= CreateResourceRequest(
2904 "GET", RESOURCE_TYPE_SUB_RESOURCE
, net::URLRequestTestJob::test_url_1());
2905 request
.download_to_file
= true;
2906 ResourceHostMsg_RequestResource
request_msg(0, 1, request
);
2907 host_
.OnMessageReceived(request_msg
, filter_
.get());
2909 // Running the message loop until idle does not work because
2910 // RedirectToFileResourceHandler posts things to base::WorkerPool. Instead,
2911 // wait for the ResourceMsg_RequestComplete to go out. Then run the event loop
2912 // until idle so the loader is gone.
2913 WaitForRequestComplete();
2914 base::RunLoop().RunUntilIdle();
2915 EXPECT_EQ(0, host_
.pending_requests());
2917 ResourceIPCAccumulator::ClassifiedMessages msgs
;
2918 accum_
.GetClassifiedMessages(&msgs
);
2920 ASSERT_EQ(1U, msgs
.size());
2921 const std::vector
<IPC::Message
>& messages
= msgs
[0];
2923 // The request should contain the following messages:
2924 // ReceivedResponse (indicates headers received and filename)
2925 // DataDownloaded* (bytes downloaded and total length)
2926 // RequestComplete (request is done)
2929 ResourceResponseHead response_head
;
2930 GetResponseHead(messages
, &response_head
);
2931 ASSERT_FALSE(response_head
.download_file_path
.empty());
2934 size_t total_len
= 0;
2935 for (size_t i
= 1; i
< messages
.size() - 1; i
++) {
2936 ASSERT_EQ(ResourceMsg_DataDownloaded::ID
, messages
[i
].type());
2937 PickleIterator
iter(messages
[i
]);
2938 int request_id
, data_len
;
2939 ASSERT_TRUE(IPC::ReadParam(&messages
[i
], &iter
, &request_id
));
2940 ASSERT_TRUE(IPC::ReadParam(&messages
[i
], &iter
, &data_len
));
2941 total_len
+= data_len
;
2943 EXPECT_EQ(net::URLRequestTestJob::test_data_1().size(), total_len
);
2946 CheckRequestCompleteErrorCode(messages
.back(), net::OK
);
2948 // Verify that the data ended up in the temporary file.
2949 std::string contents
;
2950 ASSERT_TRUE(base::ReadFileToString(response_head
.download_file_path
,
2952 EXPECT_EQ(net::URLRequestTestJob::test_data_1(), contents
);
2954 // The file should be readable by the child.
2955 EXPECT_TRUE(ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
2956 filter_
->child_id(), response_head
.download_file_path
));
2958 // When the renderer releases the file, it should be deleted. Again,
2959 // RunUntilIdle doesn't work because base::WorkerPool is involved.
2960 ShareableFileReleaseWaiter
waiter(response_head
.download_file_path
);
2961 ResourceHostMsg_ReleaseDownloadedFile
release_msg(1);
2962 host_
.OnMessageReceived(release_msg
, filter_
.get());
2964 // The release callback runs before the delete is scheduled, so pump the
2965 // message loop for the delete itself. (This relies on the delete happening on
2966 // the FILE thread which is mapped to main thread in this test.)
2967 base::RunLoop().RunUntilIdle();
2969 EXPECT_FALSE(base::PathExists(response_head
.download_file_path
));
2970 EXPECT_FALSE(ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
2971 filter_
->child_id(), response_head
.download_file_path
));
2974 net::URLRequestJob
* TestURLRequestJobFactory::MaybeCreateJobWithProtocolHandler(
2975 const std::string
& scheme
,
2976 net::URLRequest
* request
,
2977 net::NetworkDelegate
* network_delegate
) const {
2978 url_request_jobs_created_count_
++;
2979 if (test_fixture_
->response_headers_
.empty()) {
2981 return new URLRequestTestDelayedStartJob(request
, network_delegate
);
2982 } else if (delay_complete_
) {
2983 return new URLRequestTestDelayedCompletionJob(request
,
2985 } else if (network_start_notification_
) {
2986 return new URLRequestTestDelayedNetworkJob(request
, network_delegate
);
2987 } else if (scheme
== "big-job") {
2988 return new URLRequestBigJob(request
, network_delegate
);
2990 return new net::URLRequestTestJob(request
, network_delegate
);
2994 return new URLRequestTestDelayedStartJob(
2995 request
, network_delegate
,
2996 test_fixture_
->response_headers_
, test_fixture_
->response_data_
,
2998 } else if (delay_complete_
) {
2999 return new URLRequestTestDelayedCompletionJob(
3000 request
, network_delegate
,
3001 test_fixture_
->response_headers_
, test_fixture_
->response_data_
,
3004 return new net::URLRequestTestJob(
3005 request
, network_delegate
,
3006 test_fixture_
->response_headers_
, test_fixture_
->response_data_
,
3012 net::URLRequestJob
* TestURLRequestJobFactory::MaybeInterceptRedirect(
3013 net::URLRequest
* request
,
3014 net::NetworkDelegate
* network_delegate
,
3015 const GURL
& location
) const {
3019 net::URLRequestJob
* TestURLRequestJobFactory::MaybeInterceptResponse(
3020 net::URLRequest
* request
,
3021 net::NetworkDelegate
* network_delegate
) const {
3025 } // namespace content