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