Roll src/third_party/WebKit d9c6159:8139f33 (svn 201974:201975)
[chromium-blink-merge.git] / content / browser / loader / resource_dispatcher_host_unittest.cc
blob59045599dece613d9722525bae6a2ecf1db6d29b
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/render_process_host.h"
35 #include "content/public/browser/resource_context.h"
36 #include "content/public/browser/resource_dispatcher_host_delegate.h"
37 #include "content/public/browser/resource_request_info.h"
38 #include "content/public/browser/resource_throttle.h"
39 #include "content/public/browser/web_contents.h"
40 #include "content/public/browser/web_contents_observer.h"
41 #include "content/public/common/child_process_host.h"
42 #include "content/public/common/content_switches.h"
43 #include "content/public/common/process_type.h"
44 #include "content/public/common/resource_response.h"
45 #include "content/public/test/test_browser_context.h"
46 #include "content/public/test/test_browser_thread_bundle.h"
47 #include "content/public/test/test_renderer_host.h"
48 #include "content/test/test_content_browser_client.h"
49 #include "net/base/elements_upload_data_stream.h"
50 #include "net/base/net_errors.h"
51 #include "net/base/request_priority.h"
52 #include "net/base/upload_bytes_element_reader.h"
53 #include "net/http/http_util.h"
54 #include "net/url_request/url_request.h"
55 #include "net/url_request/url_request_context.h"
56 #include "net/url_request/url_request_job.h"
57 #include "net/url_request/url_request_job_factory.h"
58 #include "net/url_request/url_request_simple_job.h"
59 #include "net/url_request/url_request_test_job.h"
60 #include "net/url_request/url_request_test_util.h"
61 #include "storage/browser/blob/shareable_file_reference.h"
62 #include "testing/gtest/include/gtest/gtest.h"
64 // TODO(eroman): Write unit tests for SafeBrowsing that exercise
65 // SafeBrowsingResourceHandler.
67 using storage::ShareableFileReference;
69 namespace content {
71 namespace {
73 // Returns the resource response header structure for this request.
74 void GetResponseHead(const std::vector<IPC::Message>& messages,
75 ResourceResponseHead* response_head) {
76 ASSERT_GE(messages.size(), 2U);
78 // The first messages should be received response.
79 ASSERT_EQ(ResourceMsg_ReceivedResponse::ID, messages[0].type());
81 base::PickleIterator iter(messages[0]);
82 int request_id;
83 ASSERT_TRUE(IPC::ReadParam(&messages[0], &iter, &request_id));
84 ASSERT_TRUE(IPC::ReadParam(&messages[0], &iter, response_head));
87 void GenerateIPCMessage(
88 scoped_refptr<ResourceMessageFilter> filter,
89 scoped_ptr<IPC::Message> message) {
90 ResourceDispatcherHostImpl::Get()->OnMessageReceived(
91 *message, filter.get());
94 // On Windows, ResourceMsg_SetDataBuffer supplies a HANDLE which is not
95 // automatically released.
97 // See ResourceDispatcher::ReleaseResourcesInDataMessage.
99 // TODO(davidben): It would be nice if the behavior for base::SharedMemoryHandle
100 // were more like it is in POSIX where the received fds are tracked in a
101 // ref-counted core that closes them if not extracted.
102 void ReleaseHandlesInMessage(const IPC::Message& message) {
103 if (message.type() == ResourceMsg_SetDataBuffer::ID) {
104 base::PickleIterator iter(message);
105 int request_id;
106 CHECK(iter.ReadInt(&request_id));
107 base::SharedMemoryHandle shm_handle;
108 if (IPC::ParamTraits<base::SharedMemoryHandle>::Read(&message,
109 &iter,
110 &shm_handle)) {
111 if (base::SharedMemory::IsHandleValid(shm_handle))
112 base::SharedMemory::CloseHandle(shm_handle);
117 } // namespace
119 static int RequestIDForMessage(const IPC::Message& msg) {
120 int request_id = -1;
121 switch (msg.type()) {
122 case ResourceMsg_UploadProgress::ID:
123 case ResourceMsg_ReceivedResponse::ID:
124 case ResourceMsg_ReceivedRedirect::ID:
125 case ResourceMsg_SetDataBuffer::ID:
126 case ResourceMsg_DataReceived::ID:
127 case ResourceMsg_DataDownloaded::ID:
128 case ResourceMsg_RequestComplete::ID: {
129 bool result = base::PickleIterator(msg).ReadInt(&request_id);
130 DCHECK(result);
131 break;
134 return request_id;
137 static ResourceHostMsg_Request CreateResourceRequest(const char* method,
138 ResourceType type,
139 const GURL& url) {
140 ResourceHostMsg_Request request;
141 request.method = std::string(method);
142 request.url = url;
143 request.first_party_for_cookies = url; // bypass third-party cookie blocking
144 request.referrer_policy = blink::WebReferrerPolicyDefault;
145 request.load_flags = 0;
146 request.origin_pid = 0;
147 request.resource_type = type;
148 request.request_context = 0;
149 request.appcache_host_id = kAppCacheNoHostId;
150 request.download_to_file = false;
151 request.should_reset_appcache = false;
152 request.is_main_frame = true;
153 request.parent_is_main_frame = false;
154 request.parent_render_frame_id = -1;
155 request.transition_type = ui::PAGE_TRANSITION_LINK;
156 request.allow_download = true;
157 return request;
160 // Spin up the message loop to kick off the request.
161 static void KickOffRequest() {
162 base::MessageLoop::current()->RunUntilIdle();
165 // We may want to move this to a shared space if it is useful for something else
166 class ResourceIPCAccumulator {
167 public:
168 ~ResourceIPCAccumulator() {
169 for (size_t i = 0; i < messages_.size(); i++) {
170 ReleaseHandlesInMessage(messages_[i]);
174 // On Windows, takes ownership of SharedMemoryHandles in |msg|.
175 void AddMessage(const IPC::Message& msg) {
176 messages_.push_back(msg);
179 // This groups the messages by their request ID. The groups will be in order
180 // that the first message for each request ID was received, and the messages
181 // within the groups will be in the order that they appeared.
182 // Note that this clears messages_. The caller takes ownership of any
183 // SharedMemoryHandles in messages placed into |msgs|.
184 typedef std::vector< std::vector<IPC::Message> > ClassifiedMessages;
185 void GetClassifiedMessages(ClassifiedMessages* msgs);
187 private:
188 std::vector<IPC::Message> messages_;
191 // This is very inefficient as a result of repeatedly extracting the ID, use
192 // only for tests!
193 void ResourceIPCAccumulator::GetClassifiedMessages(ClassifiedMessages* msgs) {
194 while (!messages_.empty()) {
195 // Ignore unknown message types as it is valid for code to generated other
196 // IPCs as side-effects that we are not testing here.
197 int cur_id = RequestIDForMessage(messages_[0]);
198 if (cur_id != -1) {
199 std::vector<IPC::Message> cur_requests;
200 cur_requests.push_back(messages_[0]);
201 // find all other messages with this ID
202 for (int i = 1; i < static_cast<int>(messages_.size()); i++) {
203 int id = RequestIDForMessage(messages_[i]);
204 if (id == cur_id) {
205 cur_requests.push_back(messages_[i]);
206 messages_.erase(messages_.begin() + i);
207 i--;
210 msgs->push_back(cur_requests);
212 messages_.erase(messages_.begin());
216 // This is used to create a filter matching a specified child id.
217 class TestFilterSpecifyingChild : public ResourceMessageFilter {
218 public:
219 explicit TestFilterSpecifyingChild(ResourceContext* resource_context,
220 int process_id)
221 : ResourceMessageFilter(
222 process_id,
223 PROCESS_TYPE_RENDERER,
224 NULL,
225 NULL,
226 NULL,
227 NULL,
228 NULL,
229 base::Bind(&TestFilterSpecifyingChild::GetContexts,
230 base::Unretained(this))),
231 resource_context_(resource_context),
232 canceled_(false),
233 received_after_canceled_(0) {
234 set_peer_process_for_testing(base::Process::Current());
237 void set_canceled(bool canceled) { canceled_ = canceled; }
238 int received_after_canceled() const { return received_after_canceled_; }
240 // ResourceMessageFilter override
241 bool Send(IPC::Message* msg) override {
242 // No messages should be received when the process has been canceled.
243 if (canceled_)
244 received_after_canceled_++;
245 ReleaseHandlesInMessage(*msg);
246 delete msg;
247 return true;
250 ResourceContext* resource_context() { return resource_context_; }
252 protected:
253 ~TestFilterSpecifyingChild() override {}
255 private:
256 void GetContexts(const ResourceHostMsg_Request& request,
257 ResourceContext** resource_context,
258 net::URLRequestContext** request_context) {
259 *resource_context = resource_context_;
260 *request_context = resource_context_->GetRequestContext();
263 ResourceContext* resource_context_;
264 bool canceled_;
265 int received_after_canceled_;
267 DISALLOW_COPY_AND_ASSIGN(TestFilterSpecifyingChild);
270 class TestFilter : public TestFilterSpecifyingChild {
271 public:
272 explicit TestFilter(ResourceContext* resource_context)
273 : TestFilterSpecifyingChild(
274 resource_context,
275 ChildProcessHostImpl::GenerateChildProcessUniqueId()) {
276 ChildProcessSecurityPolicyImpl::GetInstance()->Add(child_id());
279 protected:
280 ~TestFilter() override {
281 ChildProcessSecurityPolicyImpl::GetInstance()->Remove(child_id());
285 // This class forwards the incoming messages to the ResourceDispatcherHostTest.
286 // For the test, we want all the incoming messages to go to the same place,
287 // which is why this forwards.
288 class ForwardingFilter : public TestFilter {
289 public:
290 explicit ForwardingFilter(IPC::Sender* dest,
291 ResourceContext* resource_context)
292 : TestFilter(resource_context),
293 dest_(dest) {
296 // TestFilter override
297 bool Send(IPC::Message* msg) override { return dest_->Send(msg); }
299 private:
300 ~ForwardingFilter() override {}
302 IPC::Sender* dest_;
304 DISALLOW_COPY_AND_ASSIGN(ForwardingFilter);
307 // This class is a variation on URLRequestTestJob that will call
308 // URLRequest::WillStartUsingNetwork before starting.
309 class URLRequestTestDelayedNetworkJob : public net::URLRequestTestJob {
310 public:
311 URLRequestTestDelayedNetworkJob(net::URLRequest* request,
312 net::NetworkDelegate* network_delegate)
313 : net::URLRequestTestJob(request, network_delegate) {}
315 // Only start if not deferred for network start.
316 void Start() override {
317 bool defer = false;
318 NotifyBeforeNetworkStart(&defer);
319 if (defer)
320 return;
321 net::URLRequestTestJob::Start();
324 void ResumeNetworkStart() override { net::URLRequestTestJob::StartAsync(); }
326 private:
327 ~URLRequestTestDelayedNetworkJob() override {}
329 DISALLOW_COPY_AND_ASSIGN(URLRequestTestDelayedNetworkJob);
332 // This class is a variation on URLRequestTestJob in that it does
333 // not complete start upon entry, only when specifically told to.
334 class URLRequestTestDelayedStartJob : public net::URLRequestTestJob {
335 public:
336 URLRequestTestDelayedStartJob(net::URLRequest* request,
337 net::NetworkDelegate* network_delegate)
338 : net::URLRequestTestJob(request, network_delegate) {
339 Init();
341 URLRequestTestDelayedStartJob(net::URLRequest* request,
342 net::NetworkDelegate* network_delegate,
343 bool auto_advance)
344 : net::URLRequestTestJob(request, network_delegate, auto_advance) {
345 Init();
347 URLRequestTestDelayedStartJob(net::URLRequest* request,
348 net::NetworkDelegate* network_delegate,
349 const std::string& response_headers,
350 const std::string& response_data,
351 bool auto_advance)
352 : net::URLRequestTestJob(request,
353 network_delegate,
354 response_headers,
355 response_data,
356 auto_advance) {
357 Init();
360 // Do nothing until you're told to.
361 void Start() override {}
363 // Finish starting a URL request whose job is an instance of
364 // URLRequestTestDelayedStartJob. It is illegal to call this routine
365 // with a URLRequest that does not use URLRequestTestDelayedStartJob.
366 static void CompleteStart(net::URLRequest* request) {
367 for (URLRequestTestDelayedStartJob* job = list_head_;
368 job;
369 job = job->next_) {
370 if (job->request() == request) {
371 job->net::URLRequestTestJob::Start();
372 return;
375 NOTREACHED();
378 static bool DelayedStartQueueEmpty() {
379 return !list_head_;
382 static void ClearQueue() {
383 if (list_head_) {
384 LOG(ERROR)
385 << "Unreleased entries on URLRequestTestDelayedStartJob delay queue"
386 << "; may result in leaks.";
387 list_head_ = NULL;
391 protected:
392 ~URLRequestTestDelayedStartJob() override {
393 for (URLRequestTestDelayedStartJob** job = &list_head_; *job;
394 job = &(*job)->next_) {
395 if (*job == this) {
396 *job = (*job)->next_;
397 return;
400 NOTREACHED();
403 private:
404 void Init() {
405 next_ = list_head_;
406 list_head_ = this;
409 static URLRequestTestDelayedStartJob* list_head_;
410 URLRequestTestDelayedStartJob* next_;
413 URLRequestTestDelayedStartJob*
414 URLRequestTestDelayedStartJob::list_head_ = NULL;
416 // This class is a variation on URLRequestTestJob in that it
417 // returns IO_pending errors before every read, not just the first one.
418 class URLRequestTestDelayedCompletionJob : public net::URLRequestTestJob {
419 public:
420 URLRequestTestDelayedCompletionJob(net::URLRequest* request,
421 net::NetworkDelegate* network_delegate)
422 : net::URLRequestTestJob(request, network_delegate) {}
423 URLRequestTestDelayedCompletionJob(net::URLRequest* request,
424 net::NetworkDelegate* network_delegate,
425 bool auto_advance)
426 : net::URLRequestTestJob(request, network_delegate, auto_advance) {}
427 URLRequestTestDelayedCompletionJob(net::URLRequest* request,
428 net::NetworkDelegate* network_delegate,
429 const std::string& response_headers,
430 const std::string& response_data,
431 bool auto_advance)
432 : net::URLRequestTestJob(request,
433 network_delegate,
434 response_headers,
435 response_data,
436 auto_advance) {}
438 protected:
439 ~URLRequestTestDelayedCompletionJob() override {}
441 private:
442 bool NextReadAsync() override { return true; }
445 class URLRequestBigJob : public net::URLRequestSimpleJob {
446 public:
447 URLRequestBigJob(net::URLRequest* request,
448 net::NetworkDelegate* network_delegate)
449 : net::URLRequestSimpleJob(request, network_delegate) {
452 // URLRequestSimpleJob implementation:
453 int GetData(std::string* mime_type,
454 std::string* charset,
455 std::string* data,
456 const net::CompletionCallback& callback) const override {
457 *mime_type = "text/plain";
458 *charset = "UTF-8";
460 std::string text;
461 int count;
462 if (!ParseURL(request_->url(), &text, &count))
463 return net::ERR_INVALID_URL;
465 data->reserve(text.size() * count);
466 for (int i = 0; i < count; ++i)
467 data->append(text);
469 return net::OK;
472 base::TaskRunner* GetTaskRunner() const override {
473 return base::ThreadTaskRunnerHandle::Get().get();
476 private:
477 ~URLRequestBigJob() override {}
479 // big-job:substring,N
480 static bool ParseURL(const GURL& url, std::string* text, int* count) {
481 std::vector<std::string> parts = base::SplitString(
482 url.path(), ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
484 if (parts.size() != 2)
485 return false;
487 *text = parts[0];
488 return base::StringToInt(parts[1], count);
492 // URLRequestJob used to test GetLoadInfoForAllRoutes. The LoadState and
493 // UploadProgress values are set for the jobs at the time of creation, and
494 // the jobs will never actually do anything.
495 class URLRequestLoadInfoJob : public net::URLRequestJob {
496 public:
497 URLRequestLoadInfoJob(net::URLRequest* request,
498 net::NetworkDelegate* network_delegate,
499 const net::LoadState& load_state,
500 const net::UploadProgress& upload_progress)
501 : net::URLRequestJob(request, network_delegate),
502 load_state_(load_state),
503 upload_progress_(upload_progress) {}
505 // net::URLRequestJob implementation:
506 void Start() override {}
507 net::LoadState GetLoadState() const override { return load_state_; }
508 net::UploadProgress GetUploadProgress() const override {
509 return upload_progress_;
512 private:
513 ~URLRequestLoadInfoJob() override {}
515 // big-job:substring,N
516 static bool ParseURL(const GURL& url, std::string* text, int* count) {
517 std::vector<std::string> parts = base::SplitString(
518 url.path(), ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
520 if (parts.size() != 2)
521 return false;
523 *text = parts[0];
524 return base::StringToInt(parts[1], count);
527 const net::LoadState load_state_;
528 const net::UploadProgress upload_progress_;
531 class ResourceDispatcherHostTest;
533 class TestURLRequestJobFactory : public net::URLRequestJobFactory {
534 public:
535 explicit TestURLRequestJobFactory(ResourceDispatcherHostTest* test_fixture)
536 : test_fixture_(test_fixture),
537 delay_start_(false),
538 delay_complete_(false),
539 network_start_notification_(false),
540 url_request_jobs_created_count_(0) {
543 void HandleScheme(const std::string& scheme) {
544 supported_schemes_.insert(scheme);
547 int url_request_jobs_created_count() const {
548 return url_request_jobs_created_count_;
551 void SetDelayedStartJobGeneration(bool delay_job_start) {
552 delay_start_ = delay_job_start;
555 void SetDelayedCompleteJobGeneration(bool delay_job_complete) {
556 delay_complete_ = delay_job_complete;
559 void SetNetworkStartNotificationJobGeneration(bool notification) {
560 network_start_notification_ = notification;
563 net::URLRequestJob* MaybeCreateJobWithProtocolHandler(
564 const std::string& scheme,
565 net::URLRequest* request,
566 net::NetworkDelegate* network_delegate) const override;
568 net::URLRequestJob* MaybeInterceptRedirect(
569 net::URLRequest* request,
570 net::NetworkDelegate* network_delegate,
571 const GURL& location) const override;
573 net::URLRequestJob* MaybeInterceptResponse(
574 net::URLRequest* request,
575 net::NetworkDelegate* network_delegate) const override;
577 bool IsHandledProtocol(const std::string& scheme) const override {
578 return supported_schemes_.count(scheme) > 0;
581 bool IsHandledURL(const GURL& url) const override {
582 return supported_schemes_.count(url.scheme()) > 0;
585 bool IsSafeRedirectTarget(const GURL& location) const override {
586 return false;
589 private:
590 ResourceDispatcherHostTest* test_fixture_;
591 bool delay_start_;
592 bool delay_complete_;
593 bool network_start_notification_;
594 mutable int url_request_jobs_created_count_;
595 std::set<std::string> supported_schemes_;
597 DISALLOW_COPY_AND_ASSIGN(TestURLRequestJobFactory);
600 // Associated with an URLRequest to determine if the URLRequest gets deleted.
601 class TestUserData : public base::SupportsUserData::Data {
602 public:
603 explicit TestUserData(bool* was_deleted)
604 : was_deleted_(was_deleted) {
607 ~TestUserData() override { *was_deleted_ = true; }
609 private:
610 bool* was_deleted_;
613 class TransfersAllNavigationsContentBrowserClient
614 : public TestContentBrowserClient {
615 public:
616 bool ShouldSwapProcessesForRedirect(ResourceContext* resource_context,
617 const GURL& current_url,
618 const GURL& new_url) override {
619 return true;
623 enum GenericResourceThrottleFlags {
624 NONE = 0,
625 DEFER_STARTING_REQUEST = 1 << 0,
626 DEFER_PROCESSING_RESPONSE = 1 << 1,
627 CANCEL_BEFORE_START = 1 << 2,
628 DEFER_NETWORK_START = 1 << 3
631 // Throttle that tracks the current throttle blocking a request. Only one
632 // can throttle any request at a time.
633 class GenericResourceThrottle : public ResourceThrottle {
634 public:
635 // The value is used to indicate that the throttle should not provide
636 // a error code when cancelling a request. net::OK is used, because this
637 // is not an error code.
638 static const int USE_DEFAULT_CANCEL_ERROR_CODE = net::OK;
640 GenericResourceThrottle(int flags, int code)
641 : flags_(flags),
642 error_code_for_cancellation_(code) {
645 ~GenericResourceThrottle() override {
646 if (active_throttle_ == this)
647 active_throttle_ = NULL;
650 // ResourceThrottle implementation:
651 void WillStartRequest(bool* defer) override {
652 ASSERT_EQ(NULL, active_throttle_);
653 if (flags_ & DEFER_STARTING_REQUEST) {
654 active_throttle_ = this;
655 *defer = true;
658 if (flags_ & CANCEL_BEFORE_START) {
659 if (error_code_for_cancellation_ == USE_DEFAULT_CANCEL_ERROR_CODE) {
660 controller()->Cancel();
661 } else {
662 controller()->CancelWithError(error_code_for_cancellation_);
667 void WillProcessResponse(bool* defer) override {
668 ASSERT_EQ(NULL, active_throttle_);
669 if (flags_ & DEFER_PROCESSING_RESPONSE) {
670 active_throttle_ = this;
671 *defer = true;
675 void WillStartUsingNetwork(bool* defer) override {
676 ASSERT_EQ(NULL, active_throttle_);
678 if (flags_ & DEFER_NETWORK_START) {
679 active_throttle_ = this;
680 *defer = true;
684 const char* GetNameForLogging() const override {
685 return "GenericResourceThrottle";
688 void Resume() {
689 ASSERT_TRUE(this == active_throttle_);
690 active_throttle_ = NULL;
691 controller()->Resume();
694 static GenericResourceThrottle* active_throttle() {
695 return active_throttle_;
698 private:
699 int flags_; // bit-wise union of GenericResourceThrottleFlags.
700 int error_code_for_cancellation_;
702 // The currently active throttle, if any.
703 static GenericResourceThrottle* active_throttle_;
705 // static
706 GenericResourceThrottle* GenericResourceThrottle::active_throttle_ = NULL;
708 class TestResourceDispatcherHostDelegate
709 : public ResourceDispatcherHostDelegate {
710 public:
711 TestResourceDispatcherHostDelegate()
712 : create_two_throttles_(false),
713 flags_(NONE),
714 error_code_for_cancellation_(
715 GenericResourceThrottle::USE_DEFAULT_CANCEL_ERROR_CODE) {
718 void set_url_request_user_data(base::SupportsUserData::Data* user_data) {
719 user_data_.reset(user_data);
722 void set_flags(int value) {
723 flags_ = value;
726 void set_error_code_for_cancellation(int code) {
727 error_code_for_cancellation_ = code;
730 void set_create_two_throttles(bool create_two_throttles) {
731 create_two_throttles_ = create_two_throttles;
734 // ResourceDispatcherHostDelegate implementation:
736 void RequestBeginning(net::URLRequest* request,
737 ResourceContext* resource_context,
738 AppCacheService* appcache_service,
739 ResourceType resource_type,
740 ScopedVector<ResourceThrottle>* throttles) override {
741 if (user_data_) {
742 const void* key = user_data_.get();
743 request->SetUserData(key, user_data_.release());
746 if (flags_ != NONE) {
747 throttles->push_back(new GenericResourceThrottle(
748 flags_, error_code_for_cancellation_));
749 if (create_two_throttles_)
750 throttles->push_back(new GenericResourceThrottle(
751 flags_, error_code_for_cancellation_));
755 private:
756 bool create_two_throttles_;
757 int flags_;
758 int error_code_for_cancellation_;
759 scoped_ptr<base::SupportsUserData::Data> user_data_;
762 // Waits for a ShareableFileReference to be released.
763 class ShareableFileReleaseWaiter {
764 public:
765 ShareableFileReleaseWaiter(const base::FilePath& path) {
766 scoped_refptr<ShareableFileReference> file =
767 ShareableFileReference::Get(path);
768 file->AddFinalReleaseCallback(
769 base::Bind(&ShareableFileReleaseWaiter::Released,
770 base::Unretained(this)));
773 void Wait() {
774 loop_.Run();
777 private:
778 void Released(const base::FilePath& path) {
779 loop_.Quit();
782 base::RunLoop loop_;
784 DISALLOW_COPY_AND_ASSIGN(ShareableFileReleaseWaiter);
787 // For verifying notifications sent to the WebContents by the
788 // ResourceDispatcherHostImpl.
789 class TestWebContentsObserver : public WebContentsObserver {
790 public:
791 TestWebContentsObserver(WebContents* web_contents)
792 : WebContentsObserver(web_contents),
793 resource_request_redirect_count_(0),
794 resource_response_start_count_(0) {}
796 void DidGetRedirectForResourceRequest(
797 RenderFrameHost* render_frame_host,
798 const ResourceRedirectDetails& details) override {
799 ++resource_request_redirect_count_;
802 void DidGetResourceResponseStart(
803 const ResourceRequestDetails& details) override {
804 ++resource_response_start_count_;
807 int resource_response_start_count() { return resource_response_start_count_; }
809 int resource_request_redirect_count() {
810 return resource_request_redirect_count_;
813 private:
814 int resource_request_redirect_count_;
815 int resource_response_start_count_;
818 // Information used to create resource requests that use URLRequestLoadInfoJobs.
819 // The child_id is just that of ResourceDispatcherHostTest::filter_.
820 struct LoadInfoTestRequestInfo {
821 int route_id;
822 GURL url;
823 net::LoadState load_state;
824 net::UploadProgress upload_progress;
827 class ResourceDispatcherHostTest : public testing::Test,
828 public IPC::Sender {
829 public:
830 typedef ResourceDispatcherHostImpl::LoadInfo LoadInfo;
831 typedef ResourceDispatcherHostImpl::LoadInfoMap LoadInfoMap;
833 ResourceDispatcherHostTest()
834 : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP),
835 old_factory_(NULL),
836 send_data_received_acks_(false) {
837 browser_context_.reset(new TestBrowserContext());
838 BrowserContext::EnsureResourceContextInitialized(browser_context_.get());
839 base::RunLoop().RunUntilIdle();
840 filter_ = MakeForwardingFilter();
841 // TODO(cbentzel): Better way to get URLRequestContext?
842 net::URLRequestContext* request_context =
843 browser_context_->GetResourceContext()->GetRequestContext();
844 job_factory_.reset(new TestURLRequestJobFactory(this));
845 request_context->set_job_factory(job_factory_.get());
846 request_context->set_network_delegate(&network_delegate_);
849 // IPC::Sender implementation
850 bool Send(IPC::Message* msg) override {
851 accum_.AddMessage(*msg);
853 if (send_data_received_acks_ &&
854 msg->type() == ResourceMsg_DataReceived::ID) {
855 GenerateDataReceivedACK(*msg);
858 if (wait_for_request_complete_loop_ &&
859 msg->type() == ResourceMsg_RequestComplete::ID) {
860 wait_for_request_complete_loop_->Quit();
863 // Do not release handles in it yet; the accumulator owns them now.
864 delete msg;
865 return true;
868 scoped_ptr<LoadInfoMap> RunLoadInfoTest(LoadInfoTestRequestInfo* request_info,
869 size_t num_requests) {
870 for (size_t i = 0; i < num_requests; ++i) {
871 loader_test_request_info_.reset(
872 new LoadInfoTestRequestInfo(request_info[i]));
873 wait_for_request_create_loop_.reset(new base::RunLoop());
874 MakeTestRequest(request_info[i].route_id, i + 1, request_info[i].url);
875 wait_for_request_create_loop_->Run();
876 wait_for_request_create_loop_.reset();
878 return ResourceDispatcherHostImpl::Get()->GetLoadInfoForAllRoutes();
881 protected:
882 friend class TestURLRequestJobFactory;
884 // testing::Test
885 void SetUp() override {
886 ChildProcessSecurityPolicyImpl::GetInstance()->Add(0);
887 HandleScheme("test");
888 scoped_refptr<SiteInstance> site_instance =
889 SiteInstance::Create(browser_context_.get());
890 web_contents_.reset(
891 WebContents::Create(WebContents::CreateParams(browser_context_.get())));
892 web_contents_observer_.reset(
893 new TestWebContentsObserver(web_contents_.get()));
894 web_contents_filter_ = new TestFilterSpecifyingChild(
895 browser_context_->GetResourceContext(),
896 web_contents_->GetRenderProcessHost()->GetID());
897 child_ids_.insert(web_contents_->GetRenderProcessHost()->GetID());
900 void TearDown() override {
901 web_contents_observer_.reset();
902 web_contents_.reset();
904 EXPECT_TRUE(URLRequestTestDelayedStartJob::DelayedStartQueueEmpty());
905 URLRequestTestDelayedStartJob::ClearQueue();
907 for (std::set<int>::iterator it = child_ids_.begin();
908 it != child_ids_.end(); ++it) {
909 host_.CancelRequestsForProcess(*it);
912 host_.Shutdown();
914 ChildProcessSecurityPolicyImpl::GetInstance()->Remove(0);
916 // Flush the message loop to make application verifiers happy.
917 if (ResourceDispatcherHostImpl::Get())
918 ResourceDispatcherHostImpl::Get()->CancelRequestsForContext(
919 browser_context_->GetResourceContext());
921 browser_context_.reset();
922 base::RunLoop().RunUntilIdle();
925 // Creates a new ForwardingFilter and registers it with |child_ids_| so as not
926 // to leak per-child state on test shutdown.
927 ForwardingFilter* MakeForwardingFilter() {
928 ForwardingFilter* filter =
929 new ForwardingFilter(this, browser_context_->GetResourceContext());
930 child_ids_.insert(filter->child_id());
931 return filter;
934 // Creates a request using the current test object as the filter and
935 // SubResource as the resource type.
936 void MakeTestRequest(int render_view_id,
937 int request_id,
938 const GURL& url);
940 // Generates a request using the given filter and resource type.
941 void MakeTestRequestWithResourceType(ResourceMessageFilter* filter,
942 int render_view_id,
943 int request_id,
944 const GURL& url,
945 ResourceType type);
947 void MakeWebContentsAssociatedTestRequest(int request_id, const GURL& url);
949 // Generates a request with the given priority.
950 void MakeTestRequestWithPriority(int render_view_id,
951 int request_id,
952 net::RequestPriority priority);
954 void MakeWebContentsAssociatedDownloadRequest(int request_id,
955 const GURL& url);
957 void CancelRequest(int request_id);
958 void RendererCancelRequest(int request_id) {
959 ResourceMessageFilter* old_filter = SetFilter(filter_.get());
960 host_.OnCancelRequest(request_id);
961 SetFilter(old_filter);
964 void CompleteStartRequest(int request_id);
965 void CompleteStartRequest(ResourceMessageFilter* filter, int request_id);
967 net::TestNetworkDelegate* network_delegate() { return &network_delegate_; }
969 void EnsureSchemeIsAllowed(const std::string& scheme) {
970 ChildProcessSecurityPolicyImpl* policy =
971 ChildProcessSecurityPolicyImpl::GetInstance();
972 if (!policy->IsWebSafeScheme(scheme))
973 policy->RegisterWebSafeScheme(scheme);
976 // Sets a particular response for any request from now on. To switch back to
977 // the default bahavior, pass an empty |headers|. |headers| should be raw-
978 // formatted (NULLs instead of EOLs).
979 void SetResponse(const std::string& headers, const std::string& data) {
980 response_headers_ = net::HttpUtil::AssembleRawHeaders(headers.data(),
981 headers.size());
982 response_data_ = data;
984 void SetResponse(const std::string& headers) {
985 SetResponse(headers, std::string());
988 void SendDataReceivedACKs(bool send_acks) {
989 send_data_received_acks_ = send_acks;
992 // Intercepts requests for the given protocol.
993 void HandleScheme(const std::string& scheme) {
994 job_factory_->HandleScheme(scheme);
995 EnsureSchemeIsAllowed(scheme);
998 void GenerateDataReceivedACK(const IPC::Message& msg) {
999 EXPECT_EQ(ResourceMsg_DataReceived::ID, msg.type());
1001 int request_id = -1;
1002 bool result = base::PickleIterator(msg).ReadInt(&request_id);
1003 DCHECK(result);
1004 scoped_ptr<IPC::Message> ack(
1005 new ResourceHostMsg_DataReceived_ACK(request_id));
1007 base::ThreadTaskRunnerHandle::Get()->PostTask(
1008 FROM_HERE,
1009 base::Bind(&GenerateIPCMessage, filter_, base::Passed(&ack)));
1012 // Setting filters for testing renderer messages.
1013 // Returns the previous filter.
1014 ResourceMessageFilter* SetFilter(ResourceMessageFilter* new_filter) {
1015 ResourceMessageFilter* old_filter = host_.filter_;
1016 host_.filter_ = new_filter;
1017 return old_filter;
1020 void WaitForRequestComplete() {
1021 DCHECK(!wait_for_request_complete_loop_);
1022 wait_for_request_complete_loop_.reset(new base::RunLoop);
1023 wait_for_request_complete_loop_->Run();
1024 wait_for_request_complete_loop_.reset();
1027 scoped_ptr<LoadInfoTestRequestInfo> loader_test_request_info_;
1028 scoped_ptr<base::RunLoop> wait_for_request_create_loop_;
1030 content::TestBrowserThreadBundle thread_bundle_;
1031 scoped_ptr<TestBrowserContext> browser_context_;
1032 scoped_ptr<TestURLRequestJobFactory> job_factory_;
1033 scoped_ptr<WebContents> web_contents_;
1034 scoped_ptr<TestWebContentsObserver> web_contents_observer_;
1035 scoped_refptr<ForwardingFilter> filter_;
1036 scoped_refptr<TestFilterSpecifyingChild> web_contents_filter_;
1037 net::TestNetworkDelegate network_delegate_;
1038 ResourceDispatcherHostImpl host_;
1039 ResourceIPCAccumulator accum_;
1040 std::string response_headers_;
1041 std::string response_data_;
1042 std::string scheme_;
1043 net::URLRequest::ProtocolFactory* old_factory_;
1044 bool send_data_received_acks_;
1045 std::set<int> child_ids_;
1046 scoped_ptr<base::RunLoop> wait_for_request_complete_loop_;
1047 RenderViewHostTestEnabler render_view_host_test_enabler_;
1050 void ResourceDispatcherHostTest::MakeTestRequest(int render_view_id,
1051 int request_id,
1052 const GURL& url) {
1053 MakeTestRequestWithResourceType(filter_.get(), render_view_id, request_id,
1054 url, RESOURCE_TYPE_SUB_RESOURCE);
1057 void ResourceDispatcherHostTest::MakeTestRequestWithResourceType(
1058 ResourceMessageFilter* filter,
1059 int render_view_id,
1060 int request_id,
1061 const GURL& url,
1062 ResourceType type) {
1063 ResourceHostMsg_Request request =
1064 CreateResourceRequest("GET", type, url);
1065 ResourceHostMsg_RequestResource msg(render_view_id, request_id, request);
1066 host_.OnMessageReceived(msg, filter);
1067 KickOffRequest();
1070 void ResourceDispatcherHostTest::MakeWebContentsAssociatedTestRequest(
1071 int request_id,
1072 const GURL& url) {
1073 ResourceHostMsg_Request request =
1074 CreateResourceRequest("GET", RESOURCE_TYPE_SUB_RESOURCE, url);
1075 request.origin_pid = web_contents_->GetRenderProcessHost()->GetID();
1076 request.render_frame_id = web_contents_->GetMainFrame()->GetRoutingID();
1077 ResourceHostMsg_RequestResource msg(web_contents_->GetRoutingID(), request_id,
1078 request);
1079 host_.OnMessageReceived(msg, web_contents_filter_.get());
1080 KickOffRequest();
1083 void ResourceDispatcherHostTest::MakeTestRequestWithPriority(
1084 int render_view_id,
1085 int request_id,
1086 net::RequestPriority priority) {
1087 ResourceHostMsg_Request request = CreateResourceRequest(
1088 "GET", RESOURCE_TYPE_SUB_RESOURCE, GURL("http://example.com/priority"));
1089 request.priority = priority;
1090 ResourceHostMsg_RequestResource msg(render_view_id, request_id, request);
1091 host_.OnMessageReceived(msg, filter_.get());
1094 void ResourceDispatcherHostTest::MakeWebContentsAssociatedDownloadRequest(
1095 int request_id,
1096 const GURL& url) {
1097 scoped_ptr<DownloadSaveInfo> save_info(new DownloadSaveInfo());
1098 save_info->prompt_for_save_location = false;
1099 net::URLRequestContext* request_context =
1100 browser_context_->GetResourceContext()->GetRequestContext();
1101 scoped_ptr<net::URLRequest> request(
1102 request_context->CreateRequest(url, net::DEFAULT_PRIORITY, NULL));
1103 host_.BeginDownload(
1104 request.Pass(),
1105 Referrer(),
1106 false, // is_content_initiated
1107 browser_context_->GetResourceContext(),
1108 web_contents_->GetRenderProcessHost()->GetID(),
1109 web_contents_->GetRoutingID(),
1110 web_contents_->GetMainFrame()->GetRoutingID(),
1111 false,
1112 false,
1113 save_info.Pass(),
1114 DownloadItem::kInvalidId,
1115 ResourceDispatcherHostImpl::DownloadStartedCallback());
1118 void ResourceDispatcherHostTest::CancelRequest(int request_id) {
1119 host_.CancelRequest(filter_->child_id(), request_id);
1122 void ResourceDispatcherHostTest::CompleteStartRequest(int request_id) {
1123 CompleteStartRequest(filter_.get(), request_id);
1126 void ResourceDispatcherHostTest::CompleteStartRequest(
1127 ResourceMessageFilter* filter,
1128 int request_id) {
1129 GlobalRequestID gid(filter->child_id(), request_id);
1130 net::URLRequest* req = host_.GetURLRequest(gid);
1131 EXPECT_TRUE(req);
1132 if (req)
1133 URLRequestTestDelayedStartJob::CompleteStart(req);
1136 void CheckRequestCompleteErrorCode(const IPC::Message& message,
1137 int expected_error_code) {
1138 // Verify the expected error code was received.
1139 int request_id;
1140 int error_code;
1142 ASSERT_EQ(ResourceMsg_RequestComplete::ID, message.type());
1144 base::PickleIterator iter(message);
1145 ASSERT_TRUE(IPC::ReadParam(&message, &iter, &request_id));
1146 ASSERT_TRUE(IPC::ReadParam(&message, &iter, &error_code));
1147 ASSERT_EQ(expected_error_code, error_code);
1150 testing::AssertionResult ExtractDataOffsetAndLength(const IPC::Message& message,
1151 int* data_offset,
1152 int* data_length) {
1153 base::PickleIterator iter(message);
1154 int request_id;
1155 if (!IPC::ReadParam(&message, &iter, &request_id))
1156 return testing::AssertionFailure() << "Could not read request_id";
1157 if (!IPC::ReadParam(&message, &iter, data_offset))
1158 return testing::AssertionFailure() << "Could not read data_offset";
1159 if (!IPC::ReadParam(&message, &iter, data_length))
1160 return testing::AssertionFailure() << "Could not read data_length";
1161 return testing::AssertionSuccess();
1164 void CheckSuccessfulRequestWithErrorCode(
1165 const std::vector<IPC::Message>& messages,
1166 const std::string& reference_data,
1167 int expected_error) {
1168 // A successful request will have received 4 messages:
1169 // ReceivedResponse (indicates headers received)
1170 // SetDataBuffer (contains shared memory handle)
1171 // DataReceived (data offset and length into shared memory)
1172 // RequestComplete (request is done)
1174 // This function verifies that we received 4 messages and that they are
1175 // appropriate. It allows for an error code other than net::OK if the request
1176 // should successfully receive data and then abort, e.g., on cancel.
1177 ASSERT_EQ(4U, messages.size());
1179 // The first messages should be received response
1180 ASSERT_EQ(ResourceMsg_ReceivedResponse::ID, messages[0].type());
1182 ASSERT_EQ(ResourceMsg_SetDataBuffer::ID, messages[1].type());
1184 base::PickleIterator iter(messages[1]);
1185 int request_id;
1186 ASSERT_TRUE(IPC::ReadParam(&messages[1], &iter, &request_id));
1187 base::SharedMemoryHandle shm_handle;
1188 ASSERT_TRUE(IPC::ReadParam(&messages[1], &iter, &shm_handle));
1189 int shm_size;
1190 ASSERT_TRUE(IPC::ReadParam(&messages[1], &iter, &shm_size));
1192 // Followed by the data, currently we only do the data in one chunk, but
1193 // should probably test multiple chunks later
1194 ASSERT_EQ(ResourceMsg_DataReceived::ID, messages[2].type());
1196 int data_offset;
1197 int data_length;
1198 ASSERT_TRUE(
1199 ExtractDataOffsetAndLength(messages[2], &data_offset, &data_length));
1201 ASSERT_EQ(reference_data.size(), static_cast<size_t>(data_length));
1202 ASSERT_GE(shm_size, data_length);
1204 base::SharedMemory shared_mem(shm_handle, true); // read only
1205 shared_mem.Map(data_length);
1206 const char* data = static_cast<char*>(shared_mem.memory()) + data_offset;
1207 ASSERT_EQ(0, memcmp(reference_data.c_str(), data, data_length));
1209 // The last message should be all data received.
1210 CheckRequestCompleteErrorCode(messages[3], expected_error);
1213 void CheckSuccessfulRequest(const std::vector<IPC::Message>& messages,
1214 const std::string& reference_data) {
1215 CheckSuccessfulRequestWithErrorCode(messages, reference_data, net::OK);
1218 void CheckSuccessfulRedirect(const std::vector<IPC::Message>& messages,
1219 const std::string& reference_data) {
1220 ASSERT_EQ(5U, messages.size());
1221 ASSERT_EQ(ResourceMsg_ReceivedRedirect::ID, messages[0].type());
1223 const std::vector<IPC::Message> second_req_msgs =
1224 std::vector<IPC::Message>(messages.begin() + 1, messages.end());
1225 CheckSuccessfulRequest(second_req_msgs, reference_data);
1228 void CheckFailedRequest(const std::vector<IPC::Message>& messages,
1229 const std::string& reference_data,
1230 int expected_error) {
1231 ASSERT_LT(0U, messages.size());
1232 ASSERT_GE(2U, messages.size());
1233 size_t failure_index = messages.size() - 1;
1235 if (messages.size() == 2) {
1236 EXPECT_EQ(ResourceMsg_ReceivedResponse::ID, messages[0].type());
1239 CheckRequestCompleteErrorCode(messages[failure_index], expected_error);
1242 // Tests whether many messages get dispatched properly.
1243 TEST_F(ResourceDispatcherHostTest, TestMany) {
1244 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
1245 MakeTestRequest(0, 2, net::URLRequestTestJob::test_url_2());
1246 MakeTestRequest(0, 3, net::URLRequestTestJob::test_url_3());
1247 MakeTestRequestWithResourceType(filter_.get(), 0, 4,
1248 net::URLRequestTestJob::test_url_4(),
1249 RESOURCE_TYPE_PREFETCH); // detachable type
1250 MakeTestRequest(0, 5, net::URLRequestTestJob::test_url_redirect_to_url_2());
1252 // Finish the redirection
1253 ResourceHostMsg_FollowRedirect redirect_msg(5);
1254 host_.OnMessageReceived(redirect_msg, filter_.get());
1255 base::MessageLoop::current()->RunUntilIdle();
1257 // flush all the pending requests
1258 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1260 // sorts out all the messages we saw by request
1261 ResourceIPCAccumulator::ClassifiedMessages msgs;
1262 accum_.GetClassifiedMessages(&msgs);
1264 // there are five requests, so we should have gotten them classified as such
1265 ASSERT_EQ(5U, msgs.size());
1267 CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_1());
1268 CheckSuccessfulRequest(msgs[1], net::URLRequestTestJob::test_data_2());
1269 CheckSuccessfulRequest(msgs[2], net::URLRequestTestJob::test_data_3());
1270 CheckSuccessfulRequest(msgs[3], net::URLRequestTestJob::test_data_4());
1271 CheckSuccessfulRedirect(msgs[4], net::URLRequestTestJob::test_data_2());
1274 // Tests whether messages get canceled properly. We issue four requests,
1275 // cancel two of them, and make sure that each sent the proper notifications.
1276 TEST_F(ResourceDispatcherHostTest, Cancel) {
1277 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
1278 MakeTestRequest(0, 2, net::URLRequestTestJob::test_url_2());
1279 MakeTestRequest(0, 3, net::URLRequestTestJob::test_url_3());
1281 MakeTestRequestWithResourceType(filter_.get(), 0, 4,
1282 net::URLRequestTestJob::test_url_4(),
1283 RESOURCE_TYPE_PREFETCH); // detachable type
1285 CancelRequest(2);
1287 // Cancel request must come from the renderer for a detachable resource to
1288 // delay.
1289 RendererCancelRequest(4);
1291 // The handler should have been detached now.
1292 GlobalRequestID global_request_id(filter_->child_id(), 4);
1293 ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest(
1294 host_.GetURLRequest(global_request_id));
1295 ASSERT_TRUE(info->detachable_handler()->is_detached());
1297 // flush all the pending requests
1298 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1299 base::MessageLoop::current()->RunUntilIdle();
1301 // Everything should be out now.
1302 EXPECT_EQ(0, host_.pending_requests());
1304 ResourceIPCAccumulator::ClassifiedMessages msgs;
1305 accum_.GetClassifiedMessages(&msgs);
1307 // there are four requests, so we should have gotten them classified as such
1308 ASSERT_EQ(4U, msgs.size());
1310 CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_1());
1311 CheckSuccessfulRequest(msgs[2], net::URLRequestTestJob::test_data_3());
1313 // Check that request 2 and 4 got canceled, as far as the renderer is
1314 // concerned. Request 2 will have been deleted.
1315 ASSERT_EQ(1U, msgs[1].size());
1316 ASSERT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[1][0].type());
1318 ASSERT_EQ(2U, msgs[3].size());
1319 ASSERT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[3][0].type());
1320 CheckRequestCompleteErrorCode(msgs[3][1], net::ERR_ABORTED);
1322 // However, request 4 should have actually gone to completion. (Only request 2
1323 // was canceled.)
1324 EXPECT_EQ(4, network_delegate()->completed_requests());
1325 EXPECT_EQ(1, network_delegate()->canceled_requests());
1326 EXPECT_EQ(0, network_delegate()->error_count());
1329 // Shows that detachable requests will timeout if the request takes too long to
1330 // complete.
1331 TEST_F(ResourceDispatcherHostTest, DetachedResourceTimesOut) {
1332 MakeTestRequestWithResourceType(filter_.get(), 0, 1,
1333 net::URLRequestTestJob::test_url_2(),
1334 RESOURCE_TYPE_PREFETCH); // detachable type
1335 GlobalRequestID global_request_id(filter_->child_id(), 1);
1336 ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest(
1337 host_.GetURLRequest(global_request_id));
1338 ASSERT_TRUE(info->detachable_handler());
1339 info->detachable_handler()->set_cancel_delay(
1340 base::TimeDelta::FromMilliseconds(200));
1341 base::MessageLoop::current()->RunUntilIdle();
1343 RendererCancelRequest(1);
1345 // From the renderer's perspective, the request was cancelled.
1346 ResourceIPCAccumulator::ClassifiedMessages msgs;
1347 accum_.GetClassifiedMessages(&msgs);
1348 ASSERT_EQ(1U, msgs.size());
1349 ASSERT_EQ(2U, msgs[0].size());
1350 ASSERT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[0][0].type());
1351 CheckRequestCompleteErrorCode(msgs[0][1], net::ERR_ABORTED);
1353 // But it continues detached.
1354 EXPECT_EQ(1, host_.pending_requests());
1355 EXPECT_TRUE(info->detachable_handler()->is_detached());
1357 // Wait until after the delay timer times out before we start processing any
1358 // messages.
1359 base::OneShotTimer<base::MessageLoop> timer;
1360 timer.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(210),
1361 base::MessageLoop::current(), &base::MessageLoop::QuitWhenIdle);
1362 base::MessageLoop::current()->Run();
1364 // The prefetch should be cancelled by now.
1365 EXPECT_EQ(0, host_.pending_requests());
1366 EXPECT_EQ(1, network_delegate()->completed_requests());
1367 EXPECT_EQ(1, network_delegate()->canceled_requests());
1368 EXPECT_EQ(0, network_delegate()->error_count());
1371 // If the filter has disappeared then detachable resources should continue to
1372 // load.
1373 TEST_F(ResourceDispatcherHostTest, DeletedFilterDetached) {
1374 // test_url_1's data is available synchronously, so use 2 and 3.
1375 ResourceHostMsg_Request request_prefetch = CreateResourceRequest(
1376 "GET", RESOURCE_TYPE_PREFETCH, net::URLRequestTestJob::test_url_2());
1377 ResourceHostMsg_Request request_ping = CreateResourceRequest(
1378 "GET", RESOURCE_TYPE_PING, net::URLRequestTestJob::test_url_3());
1380 ResourceHostMsg_RequestResource msg_prefetch(0, 1, request_prefetch);
1381 host_.OnMessageReceived(msg_prefetch, filter_.get());
1382 ResourceHostMsg_RequestResource msg_ping(0, 2, request_ping);
1383 host_.OnMessageReceived(msg_ping, filter_.get());
1385 // Remove the filter before processing the requests by simulating channel
1386 // closure.
1387 ResourceRequestInfoImpl* info_prefetch = ResourceRequestInfoImpl::ForRequest(
1388 host_.GetURLRequest(GlobalRequestID(filter_->child_id(), 1)));
1389 ResourceRequestInfoImpl* info_ping = ResourceRequestInfoImpl::ForRequest(
1390 host_.GetURLRequest(GlobalRequestID(filter_->child_id(), 2)));
1391 DCHECK_EQ(filter_.get(), info_prefetch->filter());
1392 DCHECK_EQ(filter_.get(), info_ping->filter());
1393 filter_->OnChannelClosing();
1394 info_prefetch->filter_.reset();
1395 info_ping->filter_.reset();
1397 // From the renderer's perspective, the requests were cancelled.
1398 ResourceIPCAccumulator::ClassifiedMessages msgs;
1399 accum_.GetClassifiedMessages(&msgs);
1400 ASSERT_EQ(2U, msgs.size());
1401 CheckRequestCompleteErrorCode(msgs[0][0], net::ERR_ABORTED);
1402 CheckRequestCompleteErrorCode(msgs[1][0], net::ERR_ABORTED);
1404 // But it continues detached.
1405 EXPECT_EQ(2, host_.pending_requests());
1406 EXPECT_TRUE(info_prefetch->detachable_handler()->is_detached());
1407 EXPECT_TRUE(info_ping->detachable_handler()->is_detached());
1409 KickOffRequest();
1411 // Make sure the requests weren't canceled early.
1412 EXPECT_EQ(2, host_.pending_requests());
1414 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1415 base::MessageLoop::current()->RunUntilIdle();
1417 EXPECT_EQ(0, host_.pending_requests());
1418 EXPECT_EQ(2, network_delegate()->completed_requests());
1419 EXPECT_EQ(0, network_delegate()->canceled_requests());
1420 EXPECT_EQ(0, network_delegate()->error_count());
1423 // If the filter has disappeared (original process dies) then detachable
1424 // resources should continue to load, even when redirected.
1425 TEST_F(ResourceDispatcherHostTest, DeletedFilterDetachedRedirect) {
1426 ResourceHostMsg_Request request = CreateResourceRequest(
1427 "GET", RESOURCE_TYPE_PREFETCH,
1428 net::URLRequestTestJob::test_url_redirect_to_url_2());
1430 ResourceHostMsg_RequestResource msg(0, 1, request);
1431 host_.OnMessageReceived(msg, filter_.get());
1433 // Remove the filter before processing the request by simulating channel
1434 // closure.
1435 GlobalRequestID global_request_id(filter_->child_id(), 1);
1436 ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest(
1437 host_.GetURLRequest(global_request_id));
1438 info->filter_->OnChannelClosing();
1439 info->filter_.reset();
1441 // From the renderer's perspective, the request was cancelled.
1442 ResourceIPCAccumulator::ClassifiedMessages msgs;
1443 accum_.GetClassifiedMessages(&msgs);
1444 ASSERT_EQ(1U, msgs.size());
1445 CheckRequestCompleteErrorCode(msgs[0][0], net::ERR_ABORTED);
1447 // But it continues detached.
1448 EXPECT_EQ(1, host_.pending_requests());
1449 EXPECT_TRUE(info->detachable_handler()->is_detached());
1451 // Verify no redirects before resetting the filter.
1452 net::URLRequest* url_request = host_.GetURLRequest(global_request_id);
1453 EXPECT_EQ(1u, url_request->url_chain().size());
1454 KickOffRequest();
1456 // Verify that a redirect was followed.
1457 EXPECT_EQ(2u, url_request->url_chain().size());
1459 // Make sure the request wasn't canceled early.
1460 EXPECT_EQ(1, host_.pending_requests());
1462 // Finish up the request.
1463 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1464 base::MessageLoop::current()->RunUntilIdle();
1466 EXPECT_EQ(0, host_.pending_requests());
1467 EXPECT_EQ(1, network_delegate()->completed_requests());
1468 EXPECT_EQ(0, network_delegate()->canceled_requests());
1469 EXPECT_EQ(0, network_delegate()->error_count());
1472 TEST_F(ResourceDispatcherHostTest, CancelWhileStartIsDeferred) {
1473 bool was_deleted = false;
1475 // Arrange to have requests deferred before starting.
1476 TestResourceDispatcherHostDelegate delegate;
1477 delegate.set_flags(DEFER_STARTING_REQUEST);
1478 delegate.set_url_request_user_data(new TestUserData(&was_deleted));
1479 host_.SetDelegate(&delegate);
1481 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
1482 // We cancel from the renderer because all non-renderer cancels delete
1483 // the request synchronously.
1484 RendererCancelRequest(1);
1486 // Our TestResourceThrottle should not have been deleted yet. This is to
1487 // ensure that destruction of the URLRequest happens asynchronously to
1488 // calling CancelRequest.
1489 EXPECT_FALSE(was_deleted);
1491 base::MessageLoop::current()->RunUntilIdle();
1493 EXPECT_TRUE(was_deleted);
1496 TEST_F(ResourceDispatcherHostTest, DetachWhileStartIsDeferred) {
1497 bool was_deleted = false;
1499 // Arrange to have requests deferred before starting.
1500 TestResourceDispatcherHostDelegate delegate;
1501 delegate.set_flags(DEFER_STARTING_REQUEST);
1502 delegate.set_url_request_user_data(new TestUserData(&was_deleted));
1503 host_.SetDelegate(&delegate);
1505 MakeTestRequestWithResourceType(filter_.get(), 0, 1,
1506 net::URLRequestTestJob::test_url_1(),
1507 RESOURCE_TYPE_PREFETCH); // detachable type
1508 // Cancel request must come from the renderer for a detachable resource to
1509 // detach.
1510 RendererCancelRequest(1);
1512 // Even after driving the event loop, the request has not been deleted.
1513 EXPECT_FALSE(was_deleted);
1515 // However, it is still throttled because the defer happened above the
1516 // DetachableResourceHandler.
1517 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1518 base::MessageLoop::current()->RunUntilIdle();
1519 EXPECT_FALSE(was_deleted);
1521 // Resume the request.
1522 GenericResourceThrottle* throttle =
1523 GenericResourceThrottle::active_throttle();
1524 ASSERT_TRUE(throttle);
1525 throttle->Resume();
1527 // Now, the request completes.
1528 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1529 base::MessageLoop::current()->RunUntilIdle();
1530 EXPECT_TRUE(was_deleted);
1531 EXPECT_EQ(1, network_delegate()->completed_requests());
1532 EXPECT_EQ(0, network_delegate()->canceled_requests());
1533 EXPECT_EQ(0, network_delegate()->error_count());
1536 // Tests if cancel is called in ResourceThrottle::WillStartRequest, then the
1537 // URLRequest will not be started.
1538 TEST_F(ResourceDispatcherHostTest, CancelInResourceThrottleWillStartRequest) {
1539 TestResourceDispatcherHostDelegate delegate;
1540 delegate.set_flags(CANCEL_BEFORE_START);
1541 host_.SetDelegate(&delegate);
1543 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
1545 // flush all the pending requests
1546 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1547 base::MessageLoop::current()->RunUntilIdle();
1549 ResourceIPCAccumulator::ClassifiedMessages msgs;
1550 accum_.GetClassifiedMessages(&msgs);
1552 // Check that request got canceled.
1553 ASSERT_EQ(1U, msgs[0].size());
1554 CheckRequestCompleteErrorCode(msgs[0][0], net::ERR_ABORTED);
1556 // Make sure URLRequest is never started.
1557 EXPECT_EQ(0, job_factory_->url_request_jobs_created_count());
1560 TEST_F(ResourceDispatcherHostTest, PausedStartError) {
1561 // Arrange to have requests deferred before processing response headers.
1562 TestResourceDispatcherHostDelegate delegate;
1563 delegate.set_flags(DEFER_PROCESSING_RESPONSE);
1564 host_.SetDelegate(&delegate);
1566 job_factory_->SetDelayedStartJobGeneration(true);
1567 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_error());
1568 CompleteStartRequest(1);
1570 // flush all the pending requests
1571 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1572 base::MessageLoop::current()->RunUntilIdle();
1574 EXPECT_EQ(0, host_.pending_requests());
1577 // Test the WillStartUsingNetwork throttle.
1578 TEST_F(ResourceDispatcherHostTest, ThrottleNetworkStart) {
1579 // Arrange to have requests deferred before processing response headers.
1580 TestResourceDispatcherHostDelegate delegate;
1581 delegate.set_flags(DEFER_NETWORK_START);
1582 host_.SetDelegate(&delegate);
1584 job_factory_->SetNetworkStartNotificationJobGeneration(true);
1585 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_2());
1587 // Should have deferred for network start.
1588 GenericResourceThrottle* first_throttle =
1589 GenericResourceThrottle::active_throttle();
1590 ASSERT_TRUE(first_throttle);
1591 EXPECT_EQ(0, network_delegate()->completed_requests());
1592 EXPECT_EQ(1, host_.pending_requests());
1594 first_throttle->Resume();
1596 // Flush all the pending requests.
1597 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1598 base::MessageLoop::current()->RunUntilIdle();
1600 EXPECT_EQ(1, network_delegate()->completed_requests());
1601 EXPECT_EQ(0, host_.pending_requests());
1604 TEST_F(ResourceDispatcherHostTest, ThrottleAndResumeTwice) {
1605 // Arrange to have requests deferred before starting.
1606 TestResourceDispatcherHostDelegate delegate;
1607 delegate.set_flags(DEFER_STARTING_REQUEST);
1608 delegate.set_create_two_throttles(true);
1609 host_.SetDelegate(&delegate);
1611 // Make sure the first throttle blocked the request, and then resume.
1612 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
1613 GenericResourceThrottle* first_throttle =
1614 GenericResourceThrottle::active_throttle();
1615 ASSERT_TRUE(first_throttle);
1616 first_throttle->Resume();
1618 // Make sure the second throttle blocked the request, and then resume.
1619 ASSERT_TRUE(GenericResourceThrottle::active_throttle());
1620 ASSERT_NE(first_throttle, GenericResourceThrottle::active_throttle());
1621 GenericResourceThrottle::active_throttle()->Resume();
1623 ASSERT_FALSE(GenericResourceThrottle::active_throttle());
1625 // The request is started asynchronously.
1626 base::MessageLoop::current()->RunUntilIdle();
1628 // Flush all the pending requests.
1629 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1631 EXPECT_EQ(0, host_.pending_requests());
1633 // Make sure the request completed successfully.
1634 ResourceIPCAccumulator::ClassifiedMessages msgs;
1635 accum_.GetClassifiedMessages(&msgs);
1636 ASSERT_EQ(1U, msgs.size());
1637 CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_1());
1641 // Tests that the delegate can cancel a request and provide a error code.
1642 TEST_F(ResourceDispatcherHostTest, CancelInDelegate) {
1643 TestResourceDispatcherHostDelegate delegate;
1644 delegate.set_flags(CANCEL_BEFORE_START);
1645 delegate.set_error_code_for_cancellation(net::ERR_ACCESS_DENIED);
1646 host_.SetDelegate(&delegate);
1648 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
1649 // The request will get cancelled by the throttle.
1651 // flush all the pending requests
1652 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1653 base::MessageLoop::current()->RunUntilIdle();
1655 ResourceIPCAccumulator::ClassifiedMessages msgs;
1656 accum_.GetClassifiedMessages(&msgs);
1658 // Check the cancellation
1659 ASSERT_EQ(1U, msgs.size());
1660 ASSERT_EQ(1U, msgs[0].size());
1662 CheckRequestCompleteErrorCode(msgs[0][0], net::ERR_ACCESS_DENIED);
1665 // Tests CancelRequestsForProcess
1666 TEST_F(ResourceDispatcherHostTest, TestProcessCancel) {
1667 scoped_refptr<TestFilter> test_filter = new TestFilter(
1668 browser_context_->GetResourceContext());
1669 child_ids_.insert(test_filter->child_id());
1671 // request 1 goes to the test delegate
1672 ResourceHostMsg_Request request = CreateResourceRequest(
1673 "GET", RESOURCE_TYPE_SUB_RESOURCE, net::URLRequestTestJob::test_url_1());
1675 MakeTestRequestWithResourceType(test_filter.get(), 0, 1,
1676 net::URLRequestTestJob::test_url_1(),
1677 RESOURCE_TYPE_SUB_RESOURCE);
1679 // request 2 goes to us
1680 MakeTestRequest(0, 2, net::URLRequestTestJob::test_url_2());
1682 // request 3 goes to the test delegate
1683 MakeTestRequestWithResourceType(test_filter.get(), 0, 3,
1684 net::URLRequestTestJob::test_url_3(),
1685 RESOURCE_TYPE_SUB_RESOURCE);
1687 // request 4 goes to us
1688 MakeTestRequestWithResourceType(filter_.get(), 0, 4,
1689 net::URLRequestTestJob::test_url_4(),
1690 RESOURCE_TYPE_PREFETCH); // detachable type
1693 // Make sure all requests have finished stage one. test_url_1 will have
1694 // finished.
1695 base::MessageLoop::current()->RunUntilIdle();
1697 // TODO(mbelshe):
1698 // Now that the async IO path is in place, the IO always completes on the
1699 // initial call; so the requests have already completed. This basically
1700 // breaks the whole test.
1701 //EXPECT_EQ(3, host_.pending_requests());
1703 // Process test_url_2 and test_url_3 for one level so one callback is called.
1704 // We'll cancel test_url_4 (detachable) before processing it to verify that it
1705 // delays the cancel.
1706 for (int i = 0; i < 2; i++)
1707 EXPECT_TRUE(net::URLRequestTestJob::ProcessOnePendingMessage());
1709 // Cancel the requests to the test process.
1710 host_.CancelRequestsForProcess(filter_->child_id());
1711 test_filter->set_canceled(true);
1713 // The requests should all be cancelled, except request 4, which is detached.
1714 EXPECT_EQ(1, host_.pending_requests());
1715 GlobalRequestID global_request_id(filter_->child_id(), 4);
1716 ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest(
1717 host_.GetURLRequest(global_request_id));
1718 ASSERT_TRUE(info->detachable_handler()->is_detached());
1720 // Flush all the pending requests.
1721 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1723 EXPECT_EQ(0, host_.pending_requests());
1725 // The test delegate should not have gotten any messages after being canceled.
1726 ASSERT_EQ(0, test_filter->received_after_canceled());
1728 // There should be two results.
1729 ResourceIPCAccumulator::ClassifiedMessages msgs;
1730 accum_.GetClassifiedMessages(&msgs);
1731 ASSERT_EQ(2U, msgs.size());
1732 CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_2());
1733 // The detachable request was cancelled by the renderer before it
1734 // finished. From the perspective of the renderer, it should have cancelled.
1735 ASSERT_EQ(2U, msgs[1].size());
1736 ASSERT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[1][0].type());
1737 CheckRequestCompleteErrorCode(msgs[1][1], net::ERR_ABORTED);
1738 // But it completed anyway. For the network stack, no requests were canceled.
1739 EXPECT_EQ(4, network_delegate()->completed_requests());
1740 EXPECT_EQ(0, network_delegate()->canceled_requests());
1741 EXPECT_EQ(0, network_delegate()->error_count());
1744 TEST_F(ResourceDispatcherHostTest, TestProcessCancelDetachedTimesOut) {
1745 MakeTestRequestWithResourceType(filter_.get(), 0, 1,
1746 net::URLRequestTestJob::test_url_4(),
1747 RESOURCE_TYPE_PREFETCH); // detachable type
1748 GlobalRequestID global_request_id(filter_->child_id(), 1);
1749 ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest(
1750 host_.GetURLRequest(global_request_id));
1751 ASSERT_TRUE(info->detachable_handler());
1752 info->detachable_handler()->set_cancel_delay(
1753 base::TimeDelta::FromMilliseconds(200));
1754 base::MessageLoop::current()->RunUntilIdle();
1756 // Cancel the requests to the test process.
1757 host_.CancelRequestsForProcess(filter_->child_id());
1758 EXPECT_EQ(1, host_.pending_requests());
1760 // Wait until after the delay timer times out before we start processing any
1761 // messages.
1762 base::OneShotTimer<base::MessageLoop> timer;
1763 timer.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(210),
1764 base::MessageLoop::current(), &base::MessageLoop::QuitWhenIdle);
1765 base::MessageLoop::current()->Run();
1767 // The prefetch should be cancelled by now.
1768 EXPECT_EQ(0, host_.pending_requests());
1770 // In case any messages are still to be processed.
1771 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1772 base::MessageLoop::current()->RunUntilIdle();
1774 ResourceIPCAccumulator::ClassifiedMessages msgs;
1775 accum_.GetClassifiedMessages(&msgs);
1777 ASSERT_EQ(1U, msgs.size());
1779 // The request should have cancelled.
1780 ASSERT_EQ(2U, msgs[0].size());
1781 ASSERT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[0][0].type());
1782 CheckRequestCompleteErrorCode(msgs[0][1], net::ERR_ABORTED);
1783 // And not run to completion.
1784 EXPECT_EQ(1, network_delegate()->completed_requests());
1785 EXPECT_EQ(1, network_delegate()->canceled_requests());
1786 EXPECT_EQ(0, network_delegate()->error_count());
1789 // Tests blocking and resuming requests.
1790 TEST_F(ResourceDispatcherHostTest, TestBlockingResumingRequests) {
1791 host_.BlockRequestsForRoute(filter_->child_id(), 1);
1792 host_.BlockRequestsForRoute(filter_->child_id(), 2);
1793 host_.BlockRequestsForRoute(filter_->child_id(), 3);
1795 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
1796 MakeTestRequest(1, 2, net::URLRequestTestJob::test_url_2());
1797 MakeTestRequest(0, 3, net::URLRequestTestJob::test_url_3());
1798 MakeTestRequest(1, 4, net::URLRequestTestJob::test_url_1());
1799 MakeTestRequest(2, 5, net::URLRequestTestJob::test_url_2());
1800 MakeTestRequest(3, 6, net::URLRequestTestJob::test_url_3());
1802 // Flush all the pending requests
1803 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1805 // Sort out all the messages we saw by request
1806 ResourceIPCAccumulator::ClassifiedMessages msgs;
1807 accum_.GetClassifiedMessages(&msgs);
1809 // All requests but the 2 for the RVH 0 should have been blocked.
1810 ASSERT_EQ(2U, msgs.size());
1812 CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_1());
1813 CheckSuccessfulRequest(msgs[1], net::URLRequestTestJob::test_data_3());
1815 // Resume requests for RVH 1 and flush pending requests.
1816 host_.ResumeBlockedRequestsForRoute(filter_->child_id(), 1);
1817 KickOffRequest();
1818 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1820 msgs.clear();
1821 accum_.GetClassifiedMessages(&msgs);
1822 ASSERT_EQ(2U, msgs.size());
1823 CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_2());
1824 CheckSuccessfulRequest(msgs[1], net::URLRequestTestJob::test_data_1());
1826 // Test that new requests are not blocked for RVH 1.
1827 MakeTestRequest(1, 7, net::URLRequestTestJob::test_url_1());
1828 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1829 msgs.clear();
1830 accum_.GetClassifiedMessages(&msgs);
1831 ASSERT_EQ(1U, msgs.size());
1832 CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_1());
1834 // Now resumes requests for all RVH (2 and 3).
1835 host_.ResumeBlockedRequestsForRoute(filter_->child_id(), 2);
1836 host_.ResumeBlockedRequestsForRoute(filter_->child_id(), 3);
1837 KickOffRequest();
1838 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1840 msgs.clear();
1841 accum_.GetClassifiedMessages(&msgs);
1842 ASSERT_EQ(2U, msgs.size());
1843 CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_2());
1844 CheckSuccessfulRequest(msgs[1], net::URLRequestTestJob::test_data_3());
1847 // Tests blocking and canceling requests.
1848 TEST_F(ResourceDispatcherHostTest, TestBlockingCancelingRequests) {
1849 host_.BlockRequestsForRoute(filter_->child_id(), 1);
1851 MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
1852 MakeTestRequest(1, 2, net::URLRequestTestJob::test_url_2());
1853 MakeTestRequest(0, 3, net::URLRequestTestJob::test_url_3());
1854 MakeTestRequest(1, 4, net::URLRequestTestJob::test_url_1());
1855 // Blocked detachable resources should not delay cancellation.
1856 MakeTestRequestWithResourceType(filter_.get(), 1, 5,
1857 net::URLRequestTestJob::test_url_4(),
1858 RESOURCE_TYPE_PREFETCH); // detachable type
1860 // Flush all the pending requests.
1861 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1863 // Sort out all the messages we saw by request.
1864 ResourceIPCAccumulator::ClassifiedMessages msgs;
1865 accum_.GetClassifiedMessages(&msgs);
1867 // The 2 requests for the RVH 0 should have been processed.
1868 ASSERT_EQ(2U, msgs.size());
1870 CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_1());
1871 CheckSuccessfulRequest(msgs[1], net::URLRequestTestJob::test_data_3());
1873 // Cancel requests for RVH 1.
1874 host_.CancelBlockedRequestsForRoute(filter_->child_id(), 1);
1875 KickOffRequest();
1876 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1878 msgs.clear();
1879 accum_.GetClassifiedMessages(&msgs);
1880 ASSERT_EQ(0U, msgs.size());
1883 // Tests that blocked requests are canceled if their associated process dies.
1884 TEST_F(ResourceDispatcherHostTest, TestBlockedRequestsProcessDies) {
1885 // This second filter is used to emulate a second process.
1886 scoped_refptr<ForwardingFilter> second_filter = MakeForwardingFilter();
1888 host_.BlockRequestsForRoute(second_filter->child_id(), 0);
1890 MakeTestRequestWithResourceType(filter_.get(), 0, 1,
1891 net::URLRequestTestJob::test_url_1(),
1892 RESOURCE_TYPE_SUB_RESOURCE);
1893 MakeTestRequestWithResourceType(second_filter.get(), 0, 2,
1894 net::URLRequestTestJob::test_url_2(),
1895 RESOURCE_TYPE_SUB_RESOURCE);
1896 MakeTestRequestWithResourceType(filter_.get(), 0, 3,
1897 net::URLRequestTestJob::test_url_3(),
1898 RESOURCE_TYPE_SUB_RESOURCE);
1899 MakeTestRequestWithResourceType(second_filter.get(), 0, 4,
1900 net::URLRequestTestJob::test_url_1(),
1901 RESOURCE_TYPE_SUB_RESOURCE);
1902 MakeTestRequestWithResourceType(second_filter.get(), 0, 5,
1903 net::URLRequestTestJob::test_url_4(),
1904 RESOURCE_TYPE_PREFETCH); // detachable type
1906 // Simulate process death.
1907 host_.CancelRequestsForProcess(second_filter->child_id());
1909 // Flush all the pending requests.
1910 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1912 // Sort out all the messages we saw by request.
1913 ResourceIPCAccumulator::ClassifiedMessages msgs;
1914 accum_.GetClassifiedMessages(&msgs);
1916 // The 2 requests for the RVH 0 should have been processed. Note that
1917 // blocked detachable requests are canceled without delay.
1918 ASSERT_EQ(2U, msgs.size());
1920 CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_1());
1921 CheckSuccessfulRequest(msgs[1], net::URLRequestTestJob::test_data_3());
1923 EXPECT_TRUE(host_.blocked_loaders_map_.empty());
1926 // Tests that blocked requests don't leak when the ResourceDispatcherHost goes
1927 // away. Note that we rely on Purify for finding the leaks if any.
1928 // If this test turns the Purify bot red, check the ResourceDispatcherHost
1929 // destructor to make sure the blocked requests are deleted.
1930 TEST_F(ResourceDispatcherHostTest, TestBlockedRequestsDontLeak) {
1931 // This second filter is used to emulate a second process.
1932 scoped_refptr<ForwardingFilter> second_filter = MakeForwardingFilter();
1934 host_.BlockRequestsForRoute(filter_->child_id(), 1);
1935 host_.BlockRequestsForRoute(filter_->child_id(), 2);
1936 host_.BlockRequestsForRoute(second_filter->child_id(), 1);
1938 MakeTestRequestWithResourceType(filter_.get(), 0, 1,
1939 net::URLRequestTestJob::test_url_1(),
1940 RESOURCE_TYPE_SUB_RESOURCE);
1941 MakeTestRequestWithResourceType(filter_.get(), 1, 2,
1942 net::URLRequestTestJob::test_url_2(),
1943 RESOURCE_TYPE_SUB_RESOURCE);
1944 MakeTestRequestWithResourceType(filter_.get(), 0, 3,
1945 net::URLRequestTestJob::test_url_3(),
1946 RESOURCE_TYPE_SUB_RESOURCE);
1947 MakeTestRequestWithResourceType(second_filter.get(), 1, 4,
1948 net::URLRequestTestJob::test_url_1(),
1949 RESOURCE_TYPE_SUB_RESOURCE);
1950 MakeTestRequestWithResourceType(filter_.get(), 2, 5,
1951 net::URLRequestTestJob::test_url_2(),
1952 RESOURCE_TYPE_SUB_RESOURCE);
1953 MakeTestRequestWithResourceType(filter_.get(), 2, 6,
1954 net::URLRequestTestJob::test_url_3(),
1955 RESOURCE_TYPE_SUB_RESOURCE);
1956 MakeTestRequestWithResourceType(filter_.get(), 0, 7,
1957 net::URLRequestTestJob::test_url_4(),
1958 RESOURCE_TYPE_PREFETCH); // detachable type
1959 MakeTestRequestWithResourceType(second_filter.get(), 1, 8,
1960 net::URLRequestTestJob::test_url_4(),
1961 RESOURCE_TYPE_PREFETCH); // detachable type
1963 host_.CancelRequestsForProcess(filter_->child_id());
1964 host_.CancelRequestsForProcess(second_filter->child_id());
1966 // Flush all the pending requests.
1967 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1970 // Test the private helper method "CalculateApproximateMemoryCost()".
1971 TEST_F(ResourceDispatcherHostTest, CalculateApproximateMemoryCost) {
1972 net::URLRequestContext context;
1973 scoped_ptr<net::URLRequest> req(context.CreateRequest(
1974 GURL("http://www.google.com"), net::DEFAULT_PRIORITY, NULL));
1975 EXPECT_EQ(
1976 4427,
1977 ResourceDispatcherHostImpl::CalculateApproximateMemoryCost(req.get()));
1979 // Add 9 bytes of referrer.
1980 req->SetReferrer("123456789");
1981 EXPECT_EQ(
1982 4436,
1983 ResourceDispatcherHostImpl::CalculateApproximateMemoryCost(req.get()));
1985 // Add 33 bytes of upload content.
1986 std::string upload_content;
1987 upload_content.resize(33);
1988 std::fill(upload_content.begin(), upload_content.end(), 'x');
1989 scoped_ptr<net::UploadElementReader> reader(new net::UploadBytesElementReader(
1990 upload_content.data(), upload_content.size()));
1991 req->set_upload(
1992 net::ElementsUploadDataStream::CreateWithReader(reader.Pass(), 0));
1994 // Since the upload throttling is disabled, this has no effect on the cost.
1995 EXPECT_EQ(
1996 4436,
1997 ResourceDispatcherHostImpl::CalculateApproximateMemoryCost(req.get()));
2000 // Test that too much memory for outstanding requests for a particular
2001 // render_process_host_id causes requests to fail.
2002 TEST_F(ResourceDispatcherHostTest, TooMuchOutstandingRequestsMemory) {
2003 // Expected cost of each request as measured by
2004 // ResourceDispatcherHost::CalculateApproximateMemoryCost().
2005 int kMemoryCostOfTest2Req =
2006 ResourceDispatcherHostImpl::kAvgBytesPerOutstandingRequest +
2007 std::string("GET").size() +
2008 net::URLRequestTestJob::test_url_2().spec().size();
2010 // Tighten the bound on the ResourceDispatcherHost, to speed things up.
2011 int kMaxCostPerProcess = 440000;
2012 host_.set_max_outstanding_requests_cost_per_process(kMaxCostPerProcess);
2014 // Determine how many instance of test_url_2() we can request before
2015 // throttling kicks in.
2016 size_t kMaxRequests = kMaxCostPerProcess / kMemoryCostOfTest2Req;
2018 // This second filter is used to emulate a second process.
2019 scoped_refptr<ForwardingFilter> second_filter = MakeForwardingFilter();
2021 // Saturate the number of outstanding requests for our process.
2022 for (size_t i = 0; i < kMaxRequests; ++i) {
2023 MakeTestRequestWithResourceType(filter_.get(), 0, i + 1,
2024 net::URLRequestTestJob::test_url_2(),
2025 RESOURCE_TYPE_SUB_RESOURCE);
2028 // Issue two more requests for our process -- these should fail immediately.
2029 MakeTestRequestWithResourceType(filter_.get(), 0, kMaxRequests + 1,
2030 net::URLRequestTestJob::test_url_2(),
2031 RESOURCE_TYPE_SUB_RESOURCE);
2032 MakeTestRequestWithResourceType(filter_.get(), 0, kMaxRequests + 2,
2033 net::URLRequestTestJob::test_url_2(),
2034 RESOURCE_TYPE_SUB_RESOURCE);
2036 // Issue two requests for the second process -- these should succeed since
2037 // it is just process 0 that is saturated.
2038 MakeTestRequestWithResourceType(second_filter.get(), 0, kMaxRequests + 3,
2039 net::URLRequestTestJob::test_url_2(),
2040 RESOURCE_TYPE_SUB_RESOURCE);
2041 MakeTestRequestWithResourceType(second_filter.get(), 0, kMaxRequests + 4,
2042 net::URLRequestTestJob::test_url_2(),
2043 RESOURCE_TYPE_SUB_RESOURCE);
2045 // Flush all the pending requests.
2046 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2047 base::MessageLoop::current()->RunUntilIdle();
2049 // Sorts out all the messages we saw by request.
2050 ResourceIPCAccumulator::ClassifiedMessages msgs;
2051 accum_.GetClassifiedMessages(&msgs);
2053 // We issued (kMaxRequests + 4) total requests.
2054 ASSERT_EQ(kMaxRequests + 4, msgs.size());
2056 // Check that the first kMaxRequests succeeded.
2057 for (size_t i = 0; i < kMaxRequests; ++i)
2058 CheckSuccessfulRequest(msgs[i], net::URLRequestTestJob::test_data_2());
2060 // Check that the subsequent two requests (kMaxRequests + 1) and
2061 // (kMaxRequests + 2) were failed, since the per-process bound was reached.
2062 for (int i = 0; i < 2; ++i) {
2063 // Should have sent a single RequestComplete message.
2064 int index = kMaxRequests + i;
2065 CheckFailedRequest(msgs[index], net::URLRequestTestJob::test_data_2(),
2066 net::ERR_INSUFFICIENT_RESOURCES);
2069 // The final 2 requests should have succeeded.
2070 CheckSuccessfulRequest(msgs[kMaxRequests + 2],
2071 net::URLRequestTestJob::test_data_2());
2072 CheckSuccessfulRequest(msgs[kMaxRequests + 3],
2073 net::URLRequestTestJob::test_data_2());
2076 // Test that when too many requests are outstanding for a particular
2077 // render_process_host_id, any subsequent request from it fails. Also verify
2078 // that the global limit is honored.
2079 TEST_F(ResourceDispatcherHostTest, TooManyOutstandingRequests) {
2080 // Tighten the bound on the ResourceDispatcherHost, to speed things up.
2081 const size_t kMaxRequestsPerProcess = 2;
2082 host_.set_max_num_in_flight_requests_per_process(kMaxRequestsPerProcess);
2083 const size_t kMaxRequests = 3;
2084 host_.set_max_num_in_flight_requests(kMaxRequests);
2086 // Needed to emulate additional processes.
2087 scoped_refptr<ForwardingFilter> second_filter = MakeForwardingFilter();
2088 scoped_refptr<ForwardingFilter> third_filter = MakeForwardingFilter();
2090 // Saturate the number of outstanding requests for our process.
2091 for (size_t i = 0; i < kMaxRequestsPerProcess; ++i) {
2092 MakeTestRequestWithResourceType(filter_.get(), 0, i + 1,
2093 net::URLRequestTestJob::test_url_2(),
2094 RESOURCE_TYPE_SUB_RESOURCE);
2097 // Issue another request for our process -- this should fail immediately.
2098 MakeTestRequestWithResourceType(filter_.get(), 0, kMaxRequestsPerProcess + 1,
2099 net::URLRequestTestJob::test_url_2(),
2100 RESOURCE_TYPE_SUB_RESOURCE);
2102 // Issue a request for the second process -- this should succeed, because it
2103 // is just process 0 that is saturated.
2104 MakeTestRequestWithResourceType(
2105 second_filter.get(), 0, kMaxRequestsPerProcess + 2,
2106 net::URLRequestTestJob::test_url_2(), RESOURCE_TYPE_SUB_RESOURCE);
2108 // Issue a request for the third process -- this should fail, because the
2109 // global limit has been reached.
2110 MakeTestRequestWithResourceType(
2111 third_filter.get(), 0, kMaxRequestsPerProcess + 3,
2112 net::URLRequestTestJob::test_url_2(), RESOURCE_TYPE_SUB_RESOURCE);
2114 // Flush all the pending requests.
2115 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2116 base::MessageLoop::current()->RunUntilIdle();
2118 // Sorts out all the messages we saw by request.
2119 ResourceIPCAccumulator::ClassifiedMessages msgs;
2120 accum_.GetClassifiedMessages(&msgs);
2122 // The processes issued the following requests:
2123 // #1 issued kMaxRequestsPerProcess that passed + 1 that failed
2124 // #2 issued 1 request that passed
2125 // #3 issued 1 request that failed
2126 ASSERT_EQ((kMaxRequestsPerProcess + 1) + 1 + 1, msgs.size());
2128 for (size_t i = 0; i < kMaxRequestsPerProcess; ++i)
2129 CheckSuccessfulRequest(msgs[i], net::URLRequestTestJob::test_data_2());
2131 CheckFailedRequest(msgs[kMaxRequestsPerProcess + 0],
2132 net::URLRequestTestJob::test_data_2(),
2133 net::ERR_INSUFFICIENT_RESOURCES);
2134 CheckSuccessfulRequest(msgs[kMaxRequestsPerProcess + 1],
2135 net::URLRequestTestJob::test_data_2());
2136 CheckFailedRequest(msgs[kMaxRequestsPerProcess + 2],
2137 net::URLRequestTestJob::test_data_2(),
2138 net::ERR_INSUFFICIENT_RESOURCES);
2141 // Tests that we sniff the mime type for a simple request.
2142 TEST_F(ResourceDispatcherHostTest, MimeSniffed) {
2143 std::string raw_headers("HTTP/1.1 200 OK\n\n");
2144 std::string response_data("<html><title>Test One</title></html>");
2145 SetResponse(raw_headers, response_data);
2147 HandleScheme("http");
2148 MakeTestRequest(0, 1, GURL("http:bla"));
2150 // Flush all pending requests.
2151 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2153 // Sorts out all the messages we saw by request.
2154 ResourceIPCAccumulator::ClassifiedMessages msgs;
2155 accum_.GetClassifiedMessages(&msgs);
2156 ASSERT_EQ(1U, msgs.size());
2158 ResourceResponseHead response_head;
2159 GetResponseHead(msgs[0], &response_head);
2160 ASSERT_EQ("text/html", response_head.mime_type);
2163 // Tests that we don't sniff the mime type when the server provides one.
2164 TEST_F(ResourceDispatcherHostTest, MimeNotSniffed) {
2165 std::string raw_headers("HTTP/1.1 200 OK\n"
2166 "Content-type: image/jpeg\n\n");
2167 std::string response_data("<html><title>Test One</title></html>");
2168 SetResponse(raw_headers, response_data);
2170 HandleScheme("http");
2171 MakeTestRequest(0, 1, GURL("http:bla"));
2173 // Flush all pending requests.
2174 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2176 // Sorts out all the messages we saw by request.
2177 ResourceIPCAccumulator::ClassifiedMessages msgs;
2178 accum_.GetClassifiedMessages(&msgs);
2179 ASSERT_EQ(1U, msgs.size());
2181 ResourceResponseHead response_head;
2182 GetResponseHead(msgs[0], &response_head);
2183 ASSERT_EQ("image/jpeg", response_head.mime_type);
2186 // Tests that we don't sniff the mime type when there is no message body.
2187 TEST_F(ResourceDispatcherHostTest, MimeNotSniffed2) {
2188 SetResponse("HTTP/1.1 304 Not Modified\n\n");
2190 HandleScheme("http");
2191 MakeTestRequest(0, 1, GURL("http:bla"));
2193 // Flush all pending requests.
2194 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2196 // Sorts out all the messages we saw by request.
2197 ResourceIPCAccumulator::ClassifiedMessages msgs;
2198 accum_.GetClassifiedMessages(&msgs);
2199 ASSERT_EQ(1U, msgs.size());
2201 ResourceResponseHead response_head;
2202 GetResponseHead(msgs[0], &response_head);
2203 ASSERT_EQ("", response_head.mime_type);
2206 TEST_F(ResourceDispatcherHostTest, MimeSniff204) {
2207 SetResponse("HTTP/1.1 204 No Content\n\n");
2209 HandleScheme("http");
2210 MakeTestRequest(0, 1, GURL("http:bla"));
2212 // Flush all pending requests.
2213 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2215 // Sorts out all the messages we saw by request.
2216 ResourceIPCAccumulator::ClassifiedMessages msgs;
2217 accum_.GetClassifiedMessages(&msgs);
2218 ASSERT_EQ(1U, msgs.size());
2220 ResourceResponseHead response_head;
2221 GetResponseHead(msgs[0], &response_head);
2222 ASSERT_EQ("text/plain", response_head.mime_type);
2225 TEST_F(ResourceDispatcherHostTest, MimeSniffEmpty) {
2226 SetResponse("HTTP/1.1 200 OK\n\n");
2228 HandleScheme("http");
2229 MakeTestRequest(0, 1, GURL("http:bla"));
2231 // Flush all pending requests.
2232 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2234 // Sorts out all the messages we saw by request.
2235 ResourceIPCAccumulator::ClassifiedMessages msgs;
2236 accum_.GetClassifiedMessages(&msgs);
2237 ASSERT_EQ(1U, msgs.size());
2239 ResourceResponseHead response_head;
2240 GetResponseHead(msgs[0], &response_head);
2241 ASSERT_EQ("text/plain", response_head.mime_type);
2244 // Tests for crbug.com/31266 (Non-2xx + application/octet-stream).
2245 TEST_F(ResourceDispatcherHostTest, ForbiddenDownload) {
2246 std::string raw_headers("HTTP/1.1 403 Forbidden\n"
2247 "Content-disposition: attachment; filename=blah\n"
2248 "Content-type: application/octet-stream\n\n");
2249 std::string response_data("<html><title>Test One</title></html>");
2250 SetResponse(raw_headers, response_data);
2252 HandleScheme("http");
2254 // Only MAIN_FRAMEs can trigger a download.
2255 MakeTestRequestWithResourceType(filter_.get(), 0, 1, GURL("http:bla"),
2256 RESOURCE_TYPE_MAIN_FRAME);
2258 // Flush all pending requests.
2259 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2260 base::MessageLoop::current()->RunUntilIdle();
2262 // Sorts out all the messages we saw by request.
2263 ResourceIPCAccumulator::ClassifiedMessages msgs;
2264 accum_.GetClassifiedMessages(&msgs);
2266 // We should have gotten one RequestComplete message.
2267 ASSERT_EQ(1U, msgs.size());
2268 ASSERT_EQ(1U, msgs[0].size());
2269 EXPECT_EQ(ResourceMsg_RequestComplete::ID, msgs[0][0].type());
2271 // The RequestComplete message should have had the error code of
2272 // ERR_INVALID_RESPONSE.
2273 CheckRequestCompleteErrorCode(msgs[0][0], net::ERR_INVALID_RESPONSE);
2276 // Test for http://crbug.com/76202 . We don't want to destroy a
2277 // download request prematurely when processing a cancellation from
2278 // the renderer.
2279 TEST_F(ResourceDispatcherHostTest, IgnoreCancelForDownloads) {
2280 EXPECT_EQ(0, host_.pending_requests());
2282 int render_view_id = 0;
2283 int request_id = 1;
2285 std::string raw_headers("HTTP\n"
2286 "Content-disposition: attachment; filename=foo\n\n");
2287 std::string response_data("01234567890123456789\x01foobar");
2289 // Get past sniffing metrics in the MimeTypeResourceHandler. Note that
2290 // if we don't get past the sniffing metrics, the result will be that
2291 // the MimeTypeResourceHandler won't have figured out that it's a download,
2292 // won't have constructed a DownloadResourceHandler, and and the request will
2293 // be successfully canceled below, failing the test.
2294 response_data.resize(1025, ' ');
2296 SetResponse(raw_headers, response_data);
2297 job_factory_->SetDelayedCompleteJobGeneration(true);
2298 HandleScheme("http");
2300 MakeTestRequestWithResourceType(filter_.get(), render_view_id, request_id,
2301 GURL("http://example.com/blah"),
2302 RESOURCE_TYPE_MAIN_FRAME);
2303 // Return some data so that the request is identified as a download
2304 // and the proper resource handlers are created.
2305 EXPECT_TRUE(net::URLRequestTestJob::ProcessOnePendingMessage());
2307 // And now simulate a cancellation coming from the renderer.
2308 ResourceHostMsg_CancelRequest msg(request_id);
2309 host_.OnMessageReceived(msg, filter_.get());
2311 // Since the request had already started processing as a download,
2312 // the cancellation above should have been ignored and the request
2313 // should still be alive.
2314 EXPECT_EQ(1, host_.pending_requests());
2316 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2319 TEST_F(ResourceDispatcherHostTest, CancelRequestsForContext) {
2320 EXPECT_EQ(0, host_.pending_requests());
2322 int render_view_id = 0;
2323 int request_id = 1;
2325 std::string raw_headers("HTTP\n"
2326 "Content-disposition: attachment; filename=foo\n\n");
2327 std::string response_data("01234567890123456789\x01foobar");
2328 // Get past sniffing metrics.
2329 response_data.resize(1025, ' ');
2331 SetResponse(raw_headers, response_data);
2332 job_factory_->SetDelayedCompleteJobGeneration(true);
2333 HandleScheme("http");
2335 MakeTestRequestWithResourceType(filter_.get(), render_view_id, request_id,
2336 GURL("http://example.com/blah"),
2337 RESOURCE_TYPE_MAIN_FRAME);
2338 // Return some data so that the request is identified as a download
2339 // and the proper resource handlers are created.
2340 EXPECT_TRUE(net::URLRequestTestJob::ProcessOnePendingMessage());
2342 // And now simulate a cancellation coming from the renderer.
2343 ResourceHostMsg_CancelRequest msg(request_id);
2344 host_.OnMessageReceived(msg, filter_.get());
2346 // Since the request had already started processing as a download,
2347 // the cancellation above should have been ignored and the request
2348 // should still be alive.
2349 EXPECT_EQ(1, host_.pending_requests());
2351 // Cancelling by other methods shouldn't work either.
2352 host_.CancelRequestsForProcess(render_view_id);
2353 EXPECT_EQ(1, host_.pending_requests());
2355 // Cancelling by context should work.
2356 host_.CancelRequestsForContext(filter_->resource_context());
2357 EXPECT_EQ(0, host_.pending_requests());
2360 TEST_F(ResourceDispatcherHostTest, CancelRequestsForContextDetached) {
2361 EXPECT_EQ(0, host_.pending_requests());
2363 int render_view_id = 0;
2364 int request_id = 1;
2366 MakeTestRequestWithResourceType(filter_.get(), render_view_id, request_id,
2367 net::URLRequestTestJob::test_url_4(),
2368 RESOURCE_TYPE_PREFETCH); // detachable type
2370 // Simulate a cancel coming from the renderer.
2371 RendererCancelRequest(request_id);
2373 // Since the request had already started processing as detachable,
2374 // the cancellation above should have been ignored and the request
2375 // should have been detached.
2376 EXPECT_EQ(1, host_.pending_requests());
2378 // Cancelling by other methods should also leave it detached.
2379 host_.CancelRequestsForProcess(render_view_id);
2380 EXPECT_EQ(1, host_.pending_requests());
2382 // Cancelling by context should work.
2383 host_.CancelRequestsForContext(filter_->resource_context());
2384 EXPECT_EQ(0, host_.pending_requests());
2387 // Test the cancelling of requests that are being transferred to a new renderer
2388 // due to a redirection.
2389 TEST_F(ResourceDispatcherHostTest, CancelRequestsForContextTransferred) {
2390 EXPECT_EQ(0, host_.pending_requests());
2392 int render_view_id = 0;
2393 int request_id = 1;
2395 std::string raw_headers("HTTP/1.1 200 OK\n"
2396 "Content-Type: text/html; charset=utf-8\n\n");
2397 std::string response_data("<html>foobar</html>");
2399 SetResponse(raw_headers, response_data);
2400 HandleScheme("http");
2402 MakeTestRequestWithResourceType(filter_.get(), render_view_id, request_id,
2403 GURL("http://example.com/blah"),
2404 RESOURCE_TYPE_MAIN_FRAME);
2407 GlobalRequestID global_request_id(filter_->child_id(), request_id);
2408 host_.MarkAsTransferredNavigation(global_request_id);
2410 // And now simulate a cancellation coming from the renderer.
2411 ResourceHostMsg_CancelRequest msg(request_id);
2412 host_.OnMessageReceived(msg, filter_.get());
2414 // Since the request is marked as being transferred,
2415 // the cancellation above should have been ignored and the request
2416 // should still be alive.
2417 EXPECT_EQ(1, host_.pending_requests());
2419 // Cancelling by other methods shouldn't work either.
2420 host_.CancelRequestsForProcess(render_view_id);
2421 EXPECT_EQ(1, host_.pending_requests());
2423 // Cancelling by context should work.
2424 host_.CancelRequestsForContext(filter_->resource_context());
2425 EXPECT_EQ(0, host_.pending_requests());
2428 // Test transferred navigations with text/html, which doesn't trigger any
2429 // content sniffing.
2430 TEST_F(ResourceDispatcherHostTest, TransferNavigationHtml) {
2431 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
2432 switches::kEnableBrowserSideNavigation)) {
2433 SUCCEED() << "Test is not applicable with browser side navigation enabled";
2434 return;
2436 // This test expects the cross site request to be leaked, so it can transfer
2437 // the request directly.
2438 CrossSiteResourceHandler::SetLeakRequestsForTesting(true);
2440 EXPECT_EQ(0, host_.pending_requests());
2442 int render_view_id = 0;
2443 int request_id = 1;
2445 // Configure initial request.
2446 SetResponse("HTTP/1.1 302 Found\n"
2447 "Location: http://other.com/blech\n\n");
2449 HandleScheme("http");
2451 // Temporarily replace ContentBrowserClient with one that will trigger the
2452 // transfer navigation code paths.
2453 TransfersAllNavigationsContentBrowserClient new_client;
2454 ContentBrowserClient* old_client = SetBrowserClientForTesting(&new_client);
2456 MakeTestRequestWithResourceType(filter_.get(), render_view_id, request_id,
2457 GURL("http://example.com/blah"),
2458 RESOURCE_TYPE_MAIN_FRAME);
2460 // Now that we're blocked on the redirect, update the response and unblock by
2461 // telling the AsyncResourceHandler to follow the redirect.
2462 const std::string kResponseBody = "hello world";
2463 SetResponse("HTTP/1.1 200 OK\n"
2464 "Content-Type: text/html\n\n",
2465 kResponseBody);
2466 ResourceHostMsg_FollowRedirect redirect_msg(request_id);
2467 host_.OnMessageReceived(redirect_msg, filter_.get());
2468 base::MessageLoop::current()->RunUntilIdle();
2470 // Flush all the pending requests to get the response through the
2471 // MimeTypeResourceHandler.
2472 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2474 // Restore, now that we've set up a transfer.
2475 SetBrowserClientForTesting(old_client);
2477 // This second filter is used to emulate a second process.
2478 scoped_refptr<ForwardingFilter> second_filter = MakeForwardingFilter();
2480 int new_render_view_id = 1;
2481 int new_request_id = 2;
2483 ResourceHostMsg_Request request =
2484 CreateResourceRequest("GET", RESOURCE_TYPE_MAIN_FRAME,
2485 GURL("http://other.com/blech"));
2486 request.transferred_request_child_id = filter_->child_id();
2487 request.transferred_request_request_id = request_id;
2489 ResourceHostMsg_RequestResource transfer_request_msg(
2490 new_render_view_id, new_request_id, request);
2491 host_.OnMessageReceived(transfer_request_msg, second_filter.get());
2492 base::MessageLoop::current()->RunUntilIdle();
2494 // Check generated messages.
2495 ResourceIPCAccumulator::ClassifiedMessages msgs;
2496 accum_.GetClassifiedMessages(&msgs);
2498 ASSERT_EQ(2U, msgs.size());
2499 EXPECT_EQ(ResourceMsg_ReceivedRedirect::ID, msgs[0][0].type());
2500 CheckSuccessfulRequest(msgs[1], kResponseBody);
2503 // Test transferring two navigations with text/html, to ensure the resource
2504 // accounting works.
2505 TEST_F(ResourceDispatcherHostTest, TransferTwoNavigationsHtml) {
2506 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
2507 switches::kEnableBrowserSideNavigation)) {
2508 SUCCEED() << "Test is not applicable with browser side navigation enabled";
2509 return;
2511 // This test expects the cross site request to be leaked, so it can transfer
2512 // the request directly.
2513 CrossSiteResourceHandler::SetLeakRequestsForTesting(true);
2515 EXPECT_EQ(0, host_.pending_requests());
2517 int render_view_id = 0;
2518 int request_id = 1;
2520 // Configure initial request.
2521 const std::string kResponseBody = "hello world";
2522 SetResponse("HTTP/1.1 200 OK\n"
2523 "Content-Type: text/html\n\n",
2524 kResponseBody);
2526 HandleScheme("http");
2528 // Temporarily replace ContentBrowserClient with one that will trigger the
2529 // transfer navigation code paths.
2530 TransfersAllNavigationsContentBrowserClient new_client;
2531 ContentBrowserClient* old_client = SetBrowserClientForTesting(&new_client);
2533 // Make the first request.
2534 MakeTestRequestWithResourceType(filter_.get(), render_view_id, request_id,
2535 GURL("http://example.com/blah"),
2536 RESOURCE_TYPE_MAIN_FRAME);
2538 // Make a second request from the same process.
2539 int second_request_id = 2;
2540 MakeTestRequestWithResourceType(filter_.get(), render_view_id,
2541 second_request_id,
2542 GURL("http://example.com/foo"),
2543 RESOURCE_TYPE_MAIN_FRAME);
2545 // Flush all the pending requests to get the response through the
2546 // MimeTypeResourceHandler.
2547 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2549 // Restore, now that we've set up a transfer.
2550 SetBrowserClientForTesting(old_client);
2552 // This second filter is used to emulate a second process.
2553 scoped_refptr<ForwardingFilter> second_filter = MakeForwardingFilter();
2555 // Transfer the first request.
2556 int new_render_view_id = 1;
2557 int new_request_id = 5;
2558 ResourceHostMsg_Request request =
2559 CreateResourceRequest("GET", RESOURCE_TYPE_MAIN_FRAME,
2560 GURL("http://example.com/blah"));
2561 request.transferred_request_child_id = filter_->child_id();
2562 request.transferred_request_request_id = request_id;
2564 ResourceHostMsg_RequestResource transfer_request_msg(
2565 new_render_view_id, new_request_id, request);
2566 host_.OnMessageReceived(transfer_request_msg, second_filter.get());
2567 base::MessageLoop::current()->RunUntilIdle();
2569 // Transfer the second request.
2570 int new_second_request_id = 6;
2571 ResourceHostMsg_Request second_request =
2572 CreateResourceRequest("GET", RESOURCE_TYPE_MAIN_FRAME,
2573 GURL("http://example.com/foo"));
2574 request.transferred_request_child_id = filter_->child_id();
2575 request.transferred_request_request_id = second_request_id;
2577 ResourceHostMsg_RequestResource second_transfer_request_msg(
2578 new_render_view_id, new_second_request_id, second_request);
2579 host_.OnMessageReceived(second_transfer_request_msg, second_filter.get());
2580 base::MessageLoop::current()->RunUntilIdle();
2582 // Check generated messages.
2583 ResourceIPCAccumulator::ClassifiedMessages msgs;
2584 accum_.GetClassifiedMessages(&msgs);
2586 ASSERT_EQ(2U, msgs.size());
2587 CheckSuccessfulRequest(msgs[0], kResponseBody);
2590 // Test transferred navigations with text/plain, which causes
2591 // MimeTypeResourceHandler to buffer the response to sniff the content before
2592 // the transfer occurs.
2593 TEST_F(ResourceDispatcherHostTest, TransferNavigationText) {
2594 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
2595 switches::kEnableBrowserSideNavigation)) {
2596 SUCCEED() << "Test is not applicable with browser side navigation enabled";
2597 return;
2599 // This test expects the cross site request to be leaked, so it can transfer
2600 // the request directly.
2601 CrossSiteResourceHandler::SetLeakRequestsForTesting(true);
2603 EXPECT_EQ(0, host_.pending_requests());
2605 int render_view_id = 0;
2606 int request_id = 1;
2608 // Configure initial request.
2609 SetResponse("HTTP/1.1 302 Found\n"
2610 "Location: http://other.com/blech\n\n");
2612 HandleScheme("http");
2614 // Temporarily replace ContentBrowserClient with one that will trigger the
2615 // transfer navigation code paths.
2616 TransfersAllNavigationsContentBrowserClient new_client;
2617 ContentBrowserClient* old_client = SetBrowserClientForTesting(&new_client);
2619 MakeTestRequestWithResourceType(filter_.get(), render_view_id, request_id,
2620 GURL("http://example.com/blah"),
2621 RESOURCE_TYPE_MAIN_FRAME);
2623 // Now that we're blocked on the redirect, update the response and unblock by
2624 // telling the AsyncResourceHandler to follow the redirect. Use a text/plain
2625 // MIME type, which causes MimeTypeResourceHandler to buffer it before the
2626 // transfer occurs.
2627 const std::string kResponseBody = "hello world";
2628 SetResponse("HTTP/1.1 200 OK\n"
2629 "Content-Type: text/plain\n\n",
2630 kResponseBody);
2631 ResourceHostMsg_FollowRedirect redirect_msg(request_id);
2632 host_.OnMessageReceived(redirect_msg, filter_.get());
2633 base::MessageLoop::current()->RunUntilIdle();
2635 // Flush all the pending requests to get the response through the
2636 // MimeTypeResourceHandler.
2637 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2639 // Restore, now that we've set up a transfer.
2640 SetBrowserClientForTesting(old_client);
2642 // This second filter is used to emulate a second process.
2643 scoped_refptr<ForwardingFilter> second_filter = MakeForwardingFilter();
2645 int new_render_view_id = 1;
2646 int new_request_id = 2;
2648 ResourceHostMsg_Request request =
2649 CreateResourceRequest("GET", RESOURCE_TYPE_MAIN_FRAME,
2650 GURL("http://other.com/blech"));
2651 request.transferred_request_child_id = filter_->child_id();
2652 request.transferred_request_request_id = request_id;
2654 ResourceHostMsg_RequestResource transfer_request_msg(
2655 new_render_view_id, new_request_id, request);
2656 host_.OnMessageReceived(transfer_request_msg, second_filter.get());
2657 base::MessageLoop::current()->RunUntilIdle();
2659 // Check generated messages.
2660 ResourceIPCAccumulator::ClassifiedMessages msgs;
2661 accum_.GetClassifiedMessages(&msgs);
2663 ASSERT_EQ(2U, msgs.size());
2664 EXPECT_EQ(ResourceMsg_ReceivedRedirect::ID, msgs[0][0].type());
2665 CheckSuccessfulRequest(msgs[1], kResponseBody);
2668 TEST_F(ResourceDispatcherHostTest, TransferNavigationWithProcessCrash) {
2669 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
2670 switches::kEnableBrowserSideNavigation)) {
2671 SUCCEED() << "Test is not applicable with browser side navigation enabled";
2672 return;
2674 // This test expects the cross site request to be leaked, so it can transfer
2675 // the request directly.
2676 CrossSiteResourceHandler::SetLeakRequestsForTesting(true);
2678 EXPECT_EQ(0, host_.pending_requests());
2680 int render_view_id = 0;
2681 int request_id = 1;
2682 int first_child_id = -1;
2684 // Configure initial request.
2685 SetResponse("HTTP/1.1 302 Found\n"
2686 "Location: http://other.com/blech\n\n");
2687 const std::string kResponseBody = "hello world";
2689 HandleScheme("http");
2691 // Temporarily replace ContentBrowserClient with one that will trigger the
2692 // transfer navigation code paths.
2693 TransfersAllNavigationsContentBrowserClient new_client;
2694 ContentBrowserClient* old_client = SetBrowserClientForTesting(&new_client);
2696 // Create a first filter that can be deleted before the second one starts.
2698 scoped_refptr<ForwardingFilter> first_filter = MakeForwardingFilter();
2699 first_child_id = first_filter->child_id();
2701 ResourceHostMsg_Request first_request =
2702 CreateResourceRequest("GET", RESOURCE_TYPE_MAIN_FRAME,
2703 GURL("http://example.com/blah"));
2705 ResourceHostMsg_RequestResource first_request_msg(
2706 render_view_id, request_id, first_request);
2707 host_.OnMessageReceived(first_request_msg, first_filter.get());
2708 base::MessageLoop::current()->RunUntilIdle();
2710 // Now that we're blocked on the redirect, update the response and unblock
2711 // by telling the AsyncResourceHandler to follow the redirect.
2712 SetResponse("HTTP/1.1 200 OK\n"
2713 "Content-Type: text/html\n\n",
2714 kResponseBody);
2715 ResourceHostMsg_FollowRedirect redirect_msg(request_id);
2716 host_.OnMessageReceived(redirect_msg, first_filter.get());
2717 base::MessageLoop::current()->RunUntilIdle();
2719 // Flush all the pending requests to get the response through the
2720 // MimeTypeResourceHandler.
2721 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2723 // The first filter is now deleted, as if the child process died.
2725 // Restore.
2726 SetBrowserClientForTesting(old_client);
2728 // Make sure we don't hold onto the ResourceMessageFilter after it is deleted.
2729 GlobalRequestID first_global_request_id(first_child_id, request_id);
2731 // This second filter is used to emulate a second process.
2732 scoped_refptr<ForwardingFilter> second_filter = MakeForwardingFilter();
2734 int new_render_view_id = 1;
2735 int new_request_id = 2;
2737 ResourceHostMsg_Request request =
2738 CreateResourceRequest("GET", RESOURCE_TYPE_MAIN_FRAME,
2739 GURL("http://other.com/blech"));
2740 request.transferred_request_child_id = first_child_id;
2741 request.transferred_request_request_id = request_id;
2743 // For cleanup.
2744 child_ids_.insert(second_filter->child_id());
2745 ResourceHostMsg_RequestResource transfer_request_msg(
2746 new_render_view_id, new_request_id, request);
2747 host_.OnMessageReceived(transfer_request_msg, second_filter.get());
2748 base::MessageLoop::current()->RunUntilIdle();
2750 // Check generated messages.
2751 ResourceIPCAccumulator::ClassifiedMessages msgs;
2752 accum_.GetClassifiedMessages(&msgs);
2754 ASSERT_EQ(2U, msgs.size());
2755 EXPECT_EQ(ResourceMsg_ReceivedRedirect::ID, msgs[0][0].type());
2756 CheckSuccessfulRequest(msgs[1], kResponseBody);
2759 TEST_F(ResourceDispatcherHostTest, TransferNavigationWithTwoRedirects) {
2760 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
2761 switches::kEnableBrowserSideNavigation)) {
2762 SUCCEED() << "Test is not applicable with browser side navigation enabled";
2763 return;
2765 // This test expects the cross site request to be leaked, so it can transfer
2766 // the request directly.
2767 CrossSiteResourceHandler::SetLeakRequestsForTesting(true);
2769 EXPECT_EQ(0, host_.pending_requests());
2771 int render_view_id = 0;
2772 int request_id = 1;
2774 // Configure initial request.
2775 SetResponse("HTTP/1.1 302 Found\n"
2776 "Location: http://other.com/blech\n\n");
2778 HandleScheme("http");
2780 // Temporarily replace ContentBrowserClient with one that will trigger the
2781 // transfer navigation code paths.
2782 TransfersAllNavigationsContentBrowserClient new_client;
2783 ContentBrowserClient* old_client = SetBrowserClientForTesting(&new_client);
2785 MakeTestRequestWithResourceType(filter_.get(), render_view_id, request_id,
2786 GURL("http://example.com/blah"),
2787 RESOURCE_TYPE_MAIN_FRAME);
2789 // Now that we're blocked on the redirect, simulate hitting another redirect.
2790 SetResponse("HTTP/1.1 302 Found\n"
2791 "Location: http://other.com/blerg\n\n");
2792 ResourceHostMsg_FollowRedirect redirect_msg(request_id);
2793 host_.OnMessageReceived(redirect_msg, filter_.get());
2794 base::MessageLoop::current()->RunUntilIdle();
2796 // Now that we're blocked on the second redirect, update the response and
2797 // unblock by telling the AsyncResourceHandler to follow the redirect.
2798 // Again, use text/plain to force MimeTypeResourceHandler to buffer before
2799 // the transfer.
2800 const std::string kResponseBody = "hello world";
2801 SetResponse("HTTP/1.1 200 OK\n"
2802 "Content-Type: text/plain\n\n",
2803 kResponseBody);
2804 ResourceHostMsg_FollowRedirect redirect_msg2(request_id);
2805 host_.OnMessageReceived(redirect_msg2, filter_.get());
2806 base::MessageLoop::current()->RunUntilIdle();
2808 // Flush all the pending requests to get the response through the
2809 // MimeTypeResourceHandler.
2810 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2812 // Restore.
2813 SetBrowserClientForTesting(old_client);
2815 // This second filter is used to emulate a second process.
2816 scoped_refptr<ForwardingFilter> second_filter = MakeForwardingFilter();
2818 int new_render_view_id = 1;
2819 int new_request_id = 2;
2821 ResourceHostMsg_Request request =
2822 CreateResourceRequest("GET", RESOURCE_TYPE_MAIN_FRAME,
2823 GURL("http://other.com/blech"));
2824 request.transferred_request_child_id = filter_->child_id();
2825 request.transferred_request_request_id = request_id;
2827 // For cleanup.
2828 child_ids_.insert(second_filter->child_id());
2829 ResourceHostMsg_RequestResource transfer_request_msg(
2830 new_render_view_id, new_request_id, request);
2831 host_.OnMessageReceived(transfer_request_msg, second_filter.get());
2833 // Verify that we update the ResourceRequestInfo.
2834 GlobalRequestID global_request_id(second_filter->child_id(), new_request_id);
2835 const ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest(
2836 host_.GetURLRequest(global_request_id));
2837 EXPECT_EQ(second_filter->child_id(), info->GetChildID());
2838 EXPECT_EQ(new_render_view_id, info->GetRouteID());
2839 EXPECT_EQ(new_request_id, info->GetRequestID());
2840 EXPECT_EQ(second_filter.get(), info->filter());
2842 // Let request complete.
2843 base::MessageLoop::current()->RunUntilIdle();
2845 // Check generated messages.
2846 ResourceIPCAccumulator::ClassifiedMessages msgs;
2847 accum_.GetClassifiedMessages(&msgs);
2849 ASSERT_EQ(2U, msgs.size());
2850 EXPECT_EQ(ResourceMsg_ReceivedRedirect::ID, msgs[0][0].type());
2851 CheckSuccessfulRequest(msgs[1], kResponseBody);
2854 TEST_F(ResourceDispatcherHostTest, UnknownURLScheme) {
2855 EXPECT_EQ(0, host_.pending_requests());
2857 HandleScheme("http");
2859 MakeTestRequestWithResourceType(filter_.get(), 0, 1, GURL("foo://bar"),
2860 RESOURCE_TYPE_MAIN_FRAME);
2862 // Flush all pending requests.
2863 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2865 // Sort all the messages we saw by request.
2866 ResourceIPCAccumulator::ClassifiedMessages msgs;
2867 accum_.GetClassifiedMessages(&msgs);
2869 // We should have gotten one RequestComplete message.
2870 ASSERT_EQ(1U, msgs[0].size());
2871 EXPECT_EQ(ResourceMsg_RequestComplete::ID, msgs[0][0].type());
2873 // The RequestComplete message should have the error code of
2874 // ERR_UNKNOWN_URL_SCHEME.
2875 CheckRequestCompleteErrorCode(msgs[0][0], net::ERR_UNKNOWN_URL_SCHEME);
2878 TEST_F(ResourceDispatcherHostTest, DataReceivedACKs) {
2879 EXPECT_EQ(0, host_.pending_requests());
2881 SendDataReceivedACKs(true);
2883 HandleScheme("big-job");
2884 MakeTestRequest(0, 1, GURL("big-job:0123456789,1000000"));
2886 base::RunLoop().RunUntilIdle();
2888 // Sort all the messages we saw by request.
2889 ResourceIPCAccumulator::ClassifiedMessages msgs;
2890 accum_.GetClassifiedMessages(&msgs);
2892 size_t size = msgs[0].size();
2894 EXPECT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[0][0].type());
2895 EXPECT_EQ(ResourceMsg_SetDataBuffer::ID, msgs[0][1].type());
2896 for (size_t i = 2; i < size - 1; ++i)
2897 EXPECT_EQ(ResourceMsg_DataReceived::ID, msgs[0][i].type());
2898 EXPECT_EQ(ResourceMsg_RequestComplete::ID, msgs[0][size - 1].type());
2901 // Request a very large detachable resource and cancel part way. Some of the
2902 // data should have been sent to the renderer, but not all.
2903 TEST_F(ResourceDispatcherHostTest, DataSentBeforeDetach) {
2904 EXPECT_EQ(0, host_.pending_requests());
2906 int render_view_id = 0;
2907 int request_id = 1;
2909 std::string raw_headers("HTTP\n"
2910 "Content-type: image/jpeg\n\n");
2911 std::string response_data("01234567890123456789\x01foobar");
2913 // Create a response larger than kMaxAllocationSize (currently 32K). Note
2914 // that if this increase beyond 512K we'll need to make the response longer.
2915 const int kAllocSize = 1024*512;
2916 response_data.resize(kAllocSize, ' ');
2918 SetResponse(raw_headers, response_data);
2919 job_factory_->SetDelayedCompleteJobGeneration(true);
2920 HandleScheme("http");
2922 MakeTestRequestWithResourceType(filter_.get(), render_view_id, request_id,
2923 GURL("http://example.com/blah"),
2924 RESOURCE_TYPE_PREFETCH);
2926 // Get a bit of data before cancelling.
2927 EXPECT_TRUE(net::URLRequestTestJob::ProcessOnePendingMessage());
2929 // Simulate a cancellation coming from the renderer.
2930 ResourceHostMsg_CancelRequest msg(request_id);
2931 host_.OnMessageReceived(msg, filter_.get());
2933 EXPECT_EQ(1, host_.pending_requests());
2935 while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2937 // Sort all the messages we saw by request.
2938 ResourceIPCAccumulator::ClassifiedMessages msgs;
2939 accum_.GetClassifiedMessages(&msgs);
2941 EXPECT_EQ(4U, msgs[0].size());
2943 // Figure out how many bytes were received by the renderer.
2944 int data_offset;
2945 int data_length;
2946 ASSERT_TRUE(
2947 ExtractDataOffsetAndLength(msgs[0][2], &data_offset, &data_length));
2948 EXPECT_LT(0, data_length);
2949 EXPECT_GT(kAllocSize, data_length);
2951 // Verify the data that was received before cancellation. The request should
2952 // have appeared to cancel, however.
2953 CheckSuccessfulRequestWithErrorCode(
2954 msgs[0],
2955 std::string(response_data.begin(), response_data.begin() + data_length),
2956 net::ERR_ABORTED);
2959 TEST_F(ResourceDispatcherHostTest, DelayedDataReceivedACKs) {
2960 EXPECT_EQ(0, host_.pending_requests());
2962 HandleScheme("big-job");
2963 MakeTestRequest(0, 1, GURL("big-job:0123456789,1000000"));
2965 base::RunLoop().RunUntilIdle();
2967 // Sort all the messages we saw by request.
2968 ResourceIPCAccumulator::ClassifiedMessages msgs;
2969 accum_.GetClassifiedMessages(&msgs);
2971 // We expect 1x ReceivedResponse, 1x SetDataBuffer, Nx ReceivedData messages.
2972 EXPECT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[0][0].type());
2973 EXPECT_EQ(ResourceMsg_SetDataBuffer::ID, msgs[0][1].type());
2974 for (size_t i = 2; i < msgs[0].size(); ++i)
2975 EXPECT_EQ(ResourceMsg_DataReceived::ID, msgs[0][i].type());
2977 // NOTE: If we fail the above checks then it means that we probably didn't
2978 // load a big enough response to trigger the delay mechanism we are trying to
2979 // test!
2981 msgs[0].erase(msgs[0].begin());
2982 msgs[0].erase(msgs[0].begin());
2984 // ACK all DataReceived messages until we find a RequestComplete message.
2985 bool complete = false;
2986 while (!complete) {
2987 for (size_t i = 0; i < msgs[0].size(); ++i) {
2988 if (msgs[0][i].type() == ResourceMsg_RequestComplete::ID) {
2989 complete = true;
2990 break;
2993 EXPECT_EQ(ResourceMsg_DataReceived::ID, msgs[0][i].type());
2995 ResourceHostMsg_DataReceived_ACK msg(1);
2996 host_.OnMessageReceived(msg, filter_.get());
2999 base::MessageLoop::current()->RunUntilIdle();
3001 msgs.clear();
3002 accum_.GetClassifiedMessages(&msgs);
3006 // Flakyness of this test might indicate memory corruption issues with
3007 // for example the ResourceBuffer of AsyncResourceHandler.
3008 TEST_F(ResourceDispatcherHostTest, DataReceivedUnexpectedACKs) {
3009 EXPECT_EQ(0, host_.pending_requests());
3011 HandleScheme("big-job");
3012 MakeTestRequest(0, 1, GURL("big-job:0123456789,1000000"));
3014 base::RunLoop().RunUntilIdle();
3016 // Sort all the messages we saw by request.
3017 ResourceIPCAccumulator::ClassifiedMessages msgs;
3018 accum_.GetClassifiedMessages(&msgs);
3020 // We expect 1x ReceivedResponse, 1x SetDataBuffer, Nx ReceivedData messages.
3021 EXPECT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[0][0].type());
3022 EXPECT_EQ(ResourceMsg_SetDataBuffer::ID, msgs[0][1].type());
3023 for (size_t i = 2; i < msgs[0].size(); ++i)
3024 EXPECT_EQ(ResourceMsg_DataReceived::ID, msgs[0][i].type());
3026 // NOTE: If we fail the above checks then it means that we probably didn't
3027 // load a big enough response to trigger the delay mechanism.
3029 // Send some unexpected ACKs.
3030 for (size_t i = 0; i < 128; ++i) {
3031 ResourceHostMsg_DataReceived_ACK msg(1);
3032 host_.OnMessageReceived(msg, filter_.get());
3035 msgs[0].erase(msgs[0].begin());
3036 msgs[0].erase(msgs[0].begin());
3038 // ACK all DataReceived messages until we find a RequestComplete message.
3039 bool complete = false;
3040 while (!complete) {
3041 for (size_t i = 0; i < msgs[0].size(); ++i) {
3042 if (msgs[0][i].type() == ResourceMsg_RequestComplete::ID) {
3043 complete = true;
3044 break;
3047 EXPECT_EQ(ResourceMsg_DataReceived::ID, msgs[0][i].type());
3049 ResourceHostMsg_DataReceived_ACK msg(1);
3050 host_.OnMessageReceived(msg, filter_.get());
3053 base::MessageLoop::current()->RunUntilIdle();
3055 msgs.clear();
3056 accum_.GetClassifiedMessages(&msgs);
3060 // Tests the dispatcher host's temporary file management.
3061 TEST_F(ResourceDispatcherHostTest, RegisterDownloadedTempFile) {
3062 const int kRequestID = 1;
3064 // Create a temporary file.
3065 base::FilePath file_path;
3066 ASSERT_TRUE(base::CreateTemporaryFile(&file_path));
3067 scoped_refptr<ShareableFileReference> deletable_file =
3068 ShareableFileReference::GetOrCreate(
3069 file_path,
3070 ShareableFileReference::DELETE_ON_FINAL_RELEASE,
3071 BrowserThread::GetMessageLoopProxyForThread(
3072 BrowserThread::FILE).get());
3074 // Not readable.
3075 EXPECT_FALSE(ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
3076 filter_->child_id(), file_path));
3078 // Register it for a resource request.
3079 host_.RegisterDownloadedTempFile(filter_->child_id(), kRequestID, file_path);
3081 // Should be readable now.
3082 EXPECT_TRUE(ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
3083 filter_->child_id(), file_path));
3085 // The child releases from the request.
3086 ResourceHostMsg_ReleaseDownloadedFile release_msg(kRequestID);
3087 host_.OnMessageReceived(release_msg, filter_.get());
3089 // Still readable because there is another reference to the file. (The child
3090 // may take additional blob references.)
3091 EXPECT_TRUE(ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
3092 filter_->child_id(), file_path));
3094 // Release extra references and wait for the file to be deleted. (This relies
3095 // on the delete happening on the FILE thread which is mapped to main thread
3096 // in this test.)
3097 deletable_file = NULL;
3098 base::RunLoop().RunUntilIdle();
3100 // The file is no longer readable to the child and has been deleted.
3101 EXPECT_FALSE(ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
3102 filter_->child_id(), file_path));
3103 EXPECT_FALSE(base::PathExists(file_path));
3106 // Tests that temporary files held on behalf of child processes are released
3107 // when the child process dies.
3108 TEST_F(ResourceDispatcherHostTest, ReleaseTemporiesOnProcessExit) {
3109 const int kRequestID = 1;
3111 // Create a temporary file.
3112 base::FilePath file_path;
3113 ASSERT_TRUE(base::CreateTemporaryFile(&file_path));
3114 scoped_refptr<ShareableFileReference> deletable_file =
3115 ShareableFileReference::GetOrCreate(
3116 file_path,
3117 ShareableFileReference::DELETE_ON_FINAL_RELEASE,
3118 BrowserThread::GetMessageLoopProxyForThread(
3119 BrowserThread::FILE).get());
3121 // Register it for a resource request.
3122 host_.RegisterDownloadedTempFile(filter_->child_id(), kRequestID, file_path);
3123 deletable_file = NULL;
3125 // Should be readable now.
3126 EXPECT_TRUE(ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
3127 filter_->child_id(), file_path));
3129 // Let the process die.
3130 filter_->OnChannelClosing();
3131 base::RunLoop().RunUntilIdle();
3133 // The file is no longer readable to the child and has been deleted.
3134 EXPECT_FALSE(ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
3135 filter_->child_id(), file_path));
3136 EXPECT_FALSE(base::PathExists(file_path));
3139 TEST_F(ResourceDispatcherHostTest, DownloadToFile) {
3140 // Make a request which downloads to file.
3141 ResourceHostMsg_Request request = CreateResourceRequest(
3142 "GET", RESOURCE_TYPE_SUB_RESOURCE, net::URLRequestTestJob::test_url_1());
3143 request.download_to_file = true;
3144 ResourceHostMsg_RequestResource request_msg(0, 1, request);
3145 host_.OnMessageReceived(request_msg, filter_.get());
3147 // Running the message loop until idle does not work because
3148 // RedirectToFileResourceHandler posts things to base::WorkerPool. Instead,
3149 // wait for the ResourceMsg_RequestComplete to go out. Then run the event loop
3150 // until idle so the loader is gone.
3151 WaitForRequestComplete();
3152 base::RunLoop().RunUntilIdle();
3153 EXPECT_EQ(0, host_.pending_requests());
3155 ResourceIPCAccumulator::ClassifiedMessages msgs;
3156 accum_.GetClassifiedMessages(&msgs);
3158 ASSERT_EQ(1U, msgs.size());
3159 const std::vector<IPC::Message>& messages = msgs[0];
3161 // The request should contain the following messages:
3162 // ReceivedResponse (indicates headers received and filename)
3163 // DataDownloaded* (bytes downloaded and total length)
3164 // RequestComplete (request is done)
3166 // ReceivedResponse
3167 ResourceResponseHead response_head;
3168 GetResponseHead(messages, &response_head);
3169 ASSERT_FALSE(response_head.download_file_path.empty());
3171 // DataDownloaded
3172 size_t total_len = 0;
3173 for (size_t i = 1; i < messages.size() - 1; i++) {
3174 ASSERT_EQ(ResourceMsg_DataDownloaded::ID, messages[i].type());
3175 base::PickleIterator iter(messages[i]);
3176 int request_id, data_len;
3177 ASSERT_TRUE(IPC::ReadParam(&messages[i], &iter, &request_id));
3178 ASSERT_TRUE(IPC::ReadParam(&messages[i], &iter, &data_len));
3179 total_len += data_len;
3181 EXPECT_EQ(net::URLRequestTestJob::test_data_1().size(), total_len);
3183 // RequestComplete
3184 CheckRequestCompleteErrorCode(messages.back(), net::OK);
3186 // Verify that the data ended up in the temporary file.
3187 std::string contents;
3188 ASSERT_TRUE(base::ReadFileToString(response_head.download_file_path,
3189 &contents));
3190 EXPECT_EQ(net::URLRequestTestJob::test_data_1(), contents);
3192 // The file should be readable by the child.
3193 EXPECT_TRUE(ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
3194 filter_->child_id(), response_head.download_file_path));
3196 // When the renderer releases the file, it should be deleted. Again,
3197 // RunUntilIdle doesn't work because base::WorkerPool is involved.
3198 ShareableFileReleaseWaiter waiter(response_head.download_file_path);
3199 ResourceHostMsg_ReleaseDownloadedFile release_msg(1);
3200 host_.OnMessageReceived(release_msg, filter_.get());
3201 waiter.Wait();
3202 // The release callback runs before the delete is scheduled, so pump the
3203 // message loop for the delete itself. (This relies on the delete happening on
3204 // the FILE thread which is mapped to main thread in this test.)
3205 base::RunLoop().RunUntilIdle();
3207 EXPECT_FALSE(base::PathExists(response_head.download_file_path));
3208 EXPECT_FALSE(ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
3209 filter_->child_id(), response_head.download_file_path));
3212 // Tests GetLoadInfoForAllRoutes when there are no pending requests.
3213 TEST_F(ResourceDispatcherHostTest, LoadInfoNoRequests) {
3214 scoped_ptr<LoadInfoMap> load_info_map = RunLoadInfoTest(nullptr, 0);
3215 EXPECT_EQ(0u, load_info_map->size());
3218 // Tests GetLoadInfoForAllRoutes when there are 3 requests from the same
3219 // RenderView. The second one is farthest along.
3220 TEST_F(ResourceDispatcherHostTest, LoadInfo) {
3221 const GlobalRoutingID kId(filter_->child_id(), 0);
3222 LoadInfoTestRequestInfo request_info[] = {
3223 {kId.route_id,
3224 GURL("test://1/"),
3225 net::LOAD_STATE_SENDING_REQUEST,
3226 net::UploadProgress(0, 0)},
3227 {kId.route_id,
3228 GURL("test://2/"),
3229 net::LOAD_STATE_READING_RESPONSE,
3230 net::UploadProgress(0, 0)},
3231 {kId.route_id,
3232 GURL("test://3/"),
3233 net::LOAD_STATE_SENDING_REQUEST,
3234 net::UploadProgress(0, 0)},
3236 scoped_ptr<LoadInfoMap> load_info_map =
3237 RunLoadInfoTest(request_info, arraysize(request_info));
3238 ASSERT_EQ(1u, load_info_map->size());
3239 ASSERT_TRUE(load_info_map->find(kId) != load_info_map->end());
3240 EXPECT_EQ(GURL("test://2/"), (*load_info_map)[kId].url);
3241 EXPECT_EQ(net::LOAD_STATE_READING_RESPONSE,
3242 (*load_info_map)[kId].load_state.state);
3243 EXPECT_EQ(0u, (*load_info_map)[kId].upload_position);
3244 EXPECT_EQ(0u, (*load_info_map)[kId].upload_size);
3247 // Tests GetLoadInfoForAllRoutes when there are 2 requests with the same
3248 // priority. The first one (Which will have the lowest ID) should be returned.
3249 TEST_F(ResourceDispatcherHostTest, LoadInfoSamePriority) {
3250 const GlobalRoutingID kId(filter_->child_id(), 0);
3251 LoadInfoTestRequestInfo request_info[] = {
3252 {kId.route_id,
3253 GURL("test://1/"),
3254 net::LOAD_STATE_IDLE,
3255 net::UploadProgress(0, 0)},
3256 {kId.route_id,
3257 GURL("test://2/"),
3258 net::LOAD_STATE_IDLE,
3259 net::UploadProgress(0, 0)},
3261 scoped_ptr<LoadInfoMap> load_info_map =
3262 RunLoadInfoTest(request_info, arraysize(request_info));
3263 ASSERT_EQ(1u, load_info_map->size());
3264 ASSERT_TRUE(load_info_map->find(kId) != load_info_map->end());
3265 EXPECT_EQ(GURL("test://1/"), (*load_info_map)[kId].url);
3266 EXPECT_EQ(net::LOAD_STATE_IDLE, (*load_info_map)[kId].load_state.state);
3267 EXPECT_EQ(0u, (*load_info_map)[kId].upload_position);
3268 EXPECT_EQ(0u, (*load_info_map)[kId].upload_size);
3271 // Tests GetLoadInfoForAllRoutes when a request is uploading a body.
3272 TEST_F(ResourceDispatcherHostTest, LoadInfoUploadProgress) {
3273 const GlobalRoutingID kId(filter_->child_id(), 0);
3274 LoadInfoTestRequestInfo request_info[] = {
3275 {kId.route_id,
3276 GURL("test://1/"),
3277 net::LOAD_STATE_READING_RESPONSE,
3278 net::UploadProgress(0, 0)},
3279 {kId.route_id,
3280 GURL("test://1/"),
3281 net::LOAD_STATE_READING_RESPONSE,
3282 net::UploadProgress(1000, 1000)},
3283 {kId.route_id,
3284 GURL("test://2/"),
3285 net::LOAD_STATE_SENDING_REQUEST,
3286 net::UploadProgress(50, 100)},
3287 {kId.route_id,
3288 GURL("test://1/"),
3289 net::LOAD_STATE_READING_RESPONSE,
3290 net::UploadProgress(1000, 1000)},
3291 {kId.route_id,
3292 GURL("test://3/"),
3293 net::LOAD_STATE_READING_RESPONSE,
3294 net::UploadProgress(0, 0)},
3296 scoped_ptr<LoadInfoMap> load_info_map =
3297 RunLoadInfoTest(request_info, arraysize(request_info));
3298 ASSERT_EQ(1u, load_info_map->size());
3299 ASSERT_TRUE(load_info_map->find(kId) != load_info_map->end());
3300 EXPECT_EQ(GURL("test://2/"), (*load_info_map)[kId].url);
3301 EXPECT_EQ(net::LOAD_STATE_SENDING_REQUEST,
3302 (*load_info_map)[kId].load_state.state);
3303 EXPECT_EQ(50u, (*load_info_map)[kId].upload_position);
3304 EXPECT_EQ(100u, (*load_info_map)[kId].upload_size);
3307 // Tests GetLoadInfoForAllRoutes when there are 4 requests from 2 different
3308 // RenderViews. Also tests the case where the first / last requests are the
3309 // most interesting ones.
3310 TEST_F(ResourceDispatcherHostTest, LoadInfoTwoRenderViews) {
3311 const GlobalRoutingID kId1(filter_->child_id(), 0);
3312 const GlobalRoutingID kId2(filter_->child_id(), 1);
3313 LoadInfoTestRequestInfo request_info[] = {
3314 {kId1.route_id,
3315 GURL("test://1/"),
3316 net::LOAD_STATE_CONNECTING,
3317 net::UploadProgress(0, 0)},
3318 {kId2.route_id,
3319 GURL("test://2/"),
3320 net::LOAD_STATE_IDLE,
3321 net::UploadProgress(0, 0)},
3322 {kId1.route_id,
3323 GURL("test://3/"),
3324 net::LOAD_STATE_IDLE,
3325 net::UploadProgress(0, 0)},
3326 {kId2.route_id,
3327 GURL("test://4/"),
3328 net::LOAD_STATE_CONNECTING,
3329 net::UploadProgress(0, 0)},
3331 scoped_ptr<LoadInfoMap> load_info_map =
3332 RunLoadInfoTest(request_info, arraysize(request_info));
3333 ASSERT_EQ(2u, load_info_map->size());
3335 ASSERT_TRUE(load_info_map->find(kId1) != load_info_map->end());
3336 EXPECT_EQ(GURL("test://1/"), (*load_info_map)[kId1].url);
3337 EXPECT_EQ(net::LOAD_STATE_CONNECTING,
3338 (*load_info_map)[kId1].load_state.state);
3339 EXPECT_EQ(0u, (*load_info_map)[kId1].upload_position);
3340 EXPECT_EQ(0u, (*load_info_map)[kId1].upload_size);
3342 ASSERT_TRUE(load_info_map->find(kId2) != load_info_map->end());
3343 EXPECT_EQ(GURL("test://4/"), (*load_info_map)[kId2].url);
3344 EXPECT_EQ(net::LOAD_STATE_CONNECTING,
3345 (*load_info_map)[kId2].load_state.state);
3346 EXPECT_EQ(0u, (*load_info_map)[kId2].upload_position);
3347 EXPECT_EQ(0u, (*load_info_map)[kId2].upload_size);
3350 // Confirm that resource response started notifications are correctly
3351 // transmitted to the WebContents.
3352 TEST_F(ResourceDispatcherHostTest, TransferResponseStarted) {
3353 int initial_count = web_contents_observer_->resource_response_start_count();
3355 MakeWebContentsAssociatedTestRequest(1, net::URLRequestTestJob::test_url_1());
3356 base::MessageLoop::current()->RunUntilIdle();
3358 EXPECT_EQ(initial_count + 1,
3359 web_contents_observer_->resource_response_start_count());
3362 // Confirm that request redirected notifications are correctly
3363 // transmitted to the WebContents.
3364 TEST_F(ResourceDispatcherHostTest, TransferRequestRedirected) {
3365 int initial_count = web_contents_observer_->resource_request_redirect_count();
3367 MakeWebContentsAssociatedTestRequest(
3368 1, net::URLRequestTestJob::test_url_redirect_to_url_2());
3369 base::MessageLoop::current()->RunUntilIdle();
3371 EXPECT_EQ(initial_count + 1,
3372 web_contents_observer_->resource_request_redirect_count());
3375 // Confirm that DidChangePriority messages are respected.
3376 TEST_F(ResourceDispatcherHostTest, DidChangePriority) {
3377 // ResourceScheduler only throttles http and https requests.
3378 HandleScheme("http");
3380 // Needed to enable scheduling for this child.
3381 host_.OnRenderViewHostCreated(filter_->child_id(), // child_id
3382 0, // route_id
3383 true, // is_visible
3384 false); // is_audible
3386 // Prevent any of these requests from completing.
3387 job_factory_->SetDelayedCompleteJobGeneration(true);
3388 SetResponse("HTTP/1.1 200 OK\n\n", "<title>Dummy body</title>");
3390 // Only one idle priority request will run while a high-priority request
3391 // exists.
3392 MakeTestRequestWithPriority(0, 1, net::HIGHEST);
3393 MakeTestRequestWithPriority(0, 2, net::IDLE);
3394 MakeTestRequestWithPriority(0, 3, net::IDLE);
3396 KickOffRequest();
3398 EXPECT_EQ(2, job_factory_->url_request_jobs_created_count());
3400 // Increase the priority of the second idle priority request. It was
3401 // scheduled later, so it is not currently running.
3402 ResourceHostMsg_DidChangePriority priority_msg(3, net::MAXIMUM_PRIORITY, 0);
3403 host_.OnMessageReceived(priority_msg, filter_.get());
3404 base::MessageLoop::current()->RunUntilIdle();
3406 EXPECT_EQ(3, job_factory_->url_request_jobs_created_count());
3408 // Cleanup.
3409 host_.OnRenderViewHostDeleted(filter_->child_id(), // child_id
3410 0); // route_id
3413 // Confirm that resource response started notifications for downloads are not
3414 // transmitted to the WebContents.
3415 TEST_F(ResourceDispatcherHostTest, TransferResponseStartedDownload) {
3416 int initial_count(web_contents_observer_->resource_response_start_count());
3418 MakeWebContentsAssociatedDownloadRequest(
3419 1, net::URLRequestTestJob::test_url_1());
3420 base::MessageLoop::current()->RunUntilIdle();
3421 EXPECT_EQ(initial_count,
3422 web_contents_observer_->resource_response_start_count());
3425 // Confirm that request redirected notifications for downloads are not
3426 // transmitted to the WebContents.
3427 TEST_F(ResourceDispatcherHostTest, TransferRequestRedirectedDownload) {
3428 int initial_count(web_contents_observer_->resource_request_redirect_count());
3430 MakeWebContentsAssociatedDownloadRequest(
3431 1, net::URLRequestTestJob::test_url_redirect_to_url_2());
3432 base::MessageLoop::current()->RunUntilIdle();
3433 EXPECT_EQ(initial_count,
3434 web_contents_observer_->resource_request_redirect_count());
3437 net::URLRequestJob* TestURLRequestJobFactory::MaybeCreateJobWithProtocolHandler(
3438 const std::string& scheme,
3439 net::URLRequest* request,
3440 net::NetworkDelegate* network_delegate) const {
3441 url_request_jobs_created_count_++;
3442 if (test_fixture_->wait_for_request_create_loop_)
3443 test_fixture_->wait_for_request_create_loop_->Quit();
3444 if (test_fixture_->loader_test_request_info_) {
3445 DCHECK_EQ(test_fixture_->loader_test_request_info_->url, request->url());
3446 scoped_ptr<LoadInfoTestRequestInfo> info =
3447 test_fixture_->loader_test_request_info_.Pass();
3448 return new URLRequestLoadInfoJob(request, network_delegate,
3449 info->load_state, info->upload_progress);
3451 if (test_fixture_->response_headers_.empty()) {
3452 if (delay_start_) {
3453 return new URLRequestTestDelayedStartJob(request, network_delegate);
3454 } else if (delay_complete_) {
3455 return new URLRequestTestDelayedCompletionJob(request,
3456 network_delegate);
3457 } else if (network_start_notification_) {
3458 return new URLRequestTestDelayedNetworkJob(request, network_delegate);
3459 } else if (scheme == "big-job") {
3460 return new URLRequestBigJob(request, network_delegate);
3461 } else {
3462 return new net::URLRequestTestJob(request, network_delegate);
3464 } else {
3465 if (delay_start_) {
3466 return new URLRequestTestDelayedStartJob(
3467 request, network_delegate,
3468 test_fixture_->response_headers_, test_fixture_->response_data_,
3469 false);
3470 } else if (delay_complete_) {
3471 return new URLRequestTestDelayedCompletionJob(
3472 request, network_delegate,
3473 test_fixture_->response_headers_, test_fixture_->response_data_,
3474 false);
3475 } else {
3476 return new net::URLRequestTestJob(
3477 request, network_delegate,
3478 test_fixture_->response_headers_, test_fixture_->response_data_,
3479 false);
3484 net::URLRequestJob* TestURLRequestJobFactory::MaybeInterceptRedirect(
3485 net::URLRequest* request,
3486 net::NetworkDelegate* network_delegate,
3487 const GURL& location) const {
3488 return nullptr;
3491 net::URLRequestJob* TestURLRequestJobFactory::MaybeInterceptResponse(
3492 net::URLRequest* request,
3493 net::NetworkDelegate* network_delegate) const {
3494 return nullptr;
3497 } // namespace content