Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / content / browser / loader / resource_dispatcher_host_unittest.cc
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.
4
5 #include <vector>
6
7 #include "base/basictypes.h"
8 #include "base/bind.h"
9 #include "base/file_util.h"
10 #include "base/files/file_path.h"
11 #include "base/memory/scoped_vector.h"
12 #include "base/memory/shared_memory.h"
13 #include "base/message_loop/message_loop.h"
14 #include "base/pickle.h"
15 #include "base/run_loop.h"
16 #include "base/strings/string_number_conversions.h"
17 #include "base/strings/string_split.h"
18 #include "content/browser/browser_thread_impl.h"
19 #include "content/browser/child_process_security_policy_impl.h"
20 #include "content/browser/loader/cross_site_resource_handler.h"
21 #include "content/browser/loader/detachable_resource_handler.h"
22 #include "content/browser/loader/resource_dispatcher_host_impl.h"
23 #include "content/browser/loader/resource_loader.h"
24 #include "content/browser/loader/resource_message_filter.h"
25 #include "content/browser/loader/resource_request_info_impl.h"
26 #include "content/common/appcache_interfaces.h"
27 #include "content/common/child_process_host_impl.h"
28 #include "content/common/resource_messages.h"
29 #include "content/common/view_messages.h"
30 #include "content/public/browser/global_request_id.h"
31 #include "content/public/browser/resource_context.h"
32 #include "content/public/browser/resource_dispatcher_host_delegate.h"
33 #include "content/public/browser/resource_request_info.h"
34 #include "content/public/browser/resource_throttle.h"
35 #include "content/public/common/process_type.h"
36 #include "content/public/common/resource_response.h"
37 #include "content/public/test/test_browser_context.h"
38 #include "content/public/test/test_browser_thread_bundle.h"
39 #include "content/test/test_content_browser_client.h"
40 #include "net/base/net_errors.h"
41 #include "net/base/request_priority.h"
42 #include "net/base/upload_bytes_element_reader.h"
43 #include "net/base/upload_data_stream.h"
44 #include "net/http/http_util.h"
45 #include "net/url_request/url_request.h"
46 #include "net/url_request/url_request_context.h"
47 #include "net/url_request/url_request_job.h"
48 #include "net/url_request/url_request_job_factory.h"
49 #include "net/url_request/url_request_simple_job.h"
50 #include "net/url_request/url_request_test_job.h"
51 #include "net/url_request/url_request_test_util.h"
52 #include "testing/gtest/include/gtest/gtest.h"
53 #include "webkit/common/blob/shareable_file_reference.h"
54
55 // TODO(eroman): Write unit tests for SafeBrowsing that exercise
56 //               SafeBrowsingResourceHandler.
57
58 using webkit_blob::ShareableFileReference;
59
60 namespace content {
61
62 namespace {
63
64 // Returns the resource response header structure for this request.
65 void GetResponseHead(const std::vector<IPC::Message>& messages,
66                      ResourceResponseHead* response_head) {
67   ASSERT_GE(messages.size(), 2U);
68
69   // The first messages should be received response.
70   ASSERT_EQ(ResourceMsg_ReceivedResponse::ID, messages[0].type());
71
72   PickleIterator iter(messages[0]);
73   int request_id;
74   ASSERT_TRUE(IPC::ReadParam(&messages[0], &iter, &request_id));
75   ASSERT_TRUE(IPC::ReadParam(&messages[0], &iter, response_head));
76 }
77
78 void GenerateIPCMessage(
79     scoped_refptr<ResourceMessageFilter> filter,
80     scoped_ptr<IPC::Message> message) {
81   ResourceDispatcherHostImpl::Get()->OnMessageReceived(
82       *message, filter.get());
83 }
84
85 // On Windows, ResourceMsg_SetDataBuffer supplies a HANDLE which is not
86 // automatically released.
87 //
88 // See ResourceDispatcher::ReleaseResourcesInDataMessage.
89 //
90 // TODO(davidben): It would be nice if the behavior for base::SharedMemoryHandle
91 // were more like it is in POSIX where the received fds are tracked in a
92 // ref-counted core that closes them if not extracted.
93 void ReleaseHandlesInMessage(const IPC::Message& message) {
94   if (message.type() == ResourceMsg_SetDataBuffer::ID) {
95     PickleIterator iter(message);
96     int request_id;
97     CHECK(message.ReadInt(&iter, &request_id));
98     base::SharedMemoryHandle shm_handle;
99     if (IPC::ParamTraits<base::SharedMemoryHandle>::Read(&message,
100                                                          &iter,
101                                                          &shm_handle)) {
102       if (base::SharedMemory::IsHandleValid(shm_handle))
103         base::SharedMemory::CloseHandle(shm_handle);
104     }
105   }
106 }
107
108 }  // namespace
109
110 static int RequestIDForMessage(const IPC::Message& msg) {
111   int request_id = -1;
112   switch (msg.type()) {
113     case ResourceMsg_UploadProgress::ID:
114     case ResourceMsg_ReceivedResponse::ID:
115     case ResourceMsg_ReceivedRedirect::ID:
116     case ResourceMsg_SetDataBuffer::ID:
117     case ResourceMsg_DataReceived::ID:
118     case ResourceMsg_DataDownloaded::ID:
119     case ResourceMsg_RequestComplete::ID: {
120       bool result = PickleIterator(msg).ReadInt(&request_id);
121       DCHECK(result);
122       break;
123     }
124   }
125   return request_id;
126 }
127
128 static ResourceHostMsg_Request CreateResourceRequest(const char* method,
129                                                      ResourceType type,
130                                                      const GURL& url) {
131   ResourceHostMsg_Request request;
132   request.method = std::string(method);
133   request.url = url;
134   request.first_party_for_cookies = url;  // bypass third-party cookie blocking
135   request.referrer_policy = blink::WebReferrerPolicyDefault;
136   request.load_flags = 0;
137   request.origin_pid = 0;
138   request.resource_type = type;
139   request.request_context = 0;
140   request.appcache_host_id = kAppCacheNoHostId;
141   request.download_to_file = false;
142   request.is_main_frame = true;
143   request.parent_is_main_frame = false;
144   request.parent_render_frame_id = -1;
145   request.transition_type = PAGE_TRANSITION_LINK;
146   request.allow_download = true;
147   return request;
148 }
149
150 // Spin up the message loop to kick off the request.
151 static void KickOffRequest() {
152   base::MessageLoop::current()->RunUntilIdle();
153 }
154
155 // We may want to move this to a shared space if it is useful for something else
156 class ResourceIPCAccumulator {
157  public:
158   ~ResourceIPCAccumulator() {
159     for (size_t i = 0; i < messages_.size(); i++) {
160       ReleaseHandlesInMessage(messages_[i]);
161     }
162   }
163
164   // On Windows, takes ownership of SharedMemoryHandles in |msg|.
165   void AddMessage(const IPC::Message& msg) {
166     messages_.push_back(msg);
167   }
168
169   // This groups the messages by their request ID. The groups will be in order
170   // that the first message for each request ID was received, and the messages
171   // within the groups will be in the order that they appeared.
172   // Note that this clears messages_. The caller takes ownership of any
173   // SharedMemoryHandles in messages placed into |msgs|.
174   typedef std::vector< std::vector<IPC::Message> > ClassifiedMessages;
175   void GetClassifiedMessages(ClassifiedMessages* msgs);
176
177  private:
178   std::vector<IPC::Message> messages_;
179 };
180
181 // This is very inefficient as a result of repeatedly extracting the ID, use
182 // only for tests!
183 void ResourceIPCAccumulator::GetClassifiedMessages(ClassifiedMessages* msgs) {
184   while (!messages_.empty()) {
185     // Ignore unknown message types as it is valid for code to generated other
186     // IPCs as side-effects that we are not testing here.
187     int cur_id = RequestIDForMessage(messages_[0]);
188     if (cur_id != -1) {
189       std::vector<IPC::Message> cur_requests;
190       cur_requests.push_back(messages_[0]);
191       // find all other messages with this ID
192       for (int i = 1; i < static_cast<int>(messages_.size()); i++) {
193         int id = RequestIDForMessage(messages_[i]);
194         if (id == cur_id) {
195           cur_requests.push_back(messages_[i]);
196           messages_.erase(messages_.begin() + i);
197           i--;
198         }
199       }
200       msgs->push_back(cur_requests);
201     }
202     messages_.erase(messages_.begin());
203   }
204 }
205
206 // This is used to emulate different sub-processes, since this filter will
207 // have a different ID than the original.
208 class TestFilter : public ResourceMessageFilter {
209  public:
210   explicit TestFilter(ResourceContext* resource_context)
211       : ResourceMessageFilter(
212             ChildProcessHostImpl::GenerateChildProcessUniqueId(),
213             PROCESS_TYPE_RENDERER, NULL, NULL, NULL, NULL,
214             base::Bind(&TestFilter::GetContexts, base::Unretained(this))),
215         resource_context_(resource_context),
216         canceled_(false),
217         received_after_canceled_(0) {
218     ChildProcessSecurityPolicyImpl::GetInstance()->Add(child_id());
219     set_peer_pid_for_testing(base::GetCurrentProcId());
220   }
221
222   void set_canceled(bool canceled) { canceled_ = canceled; }
223   int received_after_canceled() const { return received_after_canceled_; }
224
225   // ResourceMessageFilter override
226   virtual bool Send(IPC::Message* msg) OVERRIDE {
227     // No messages should be received when the process has been canceled.
228     if (canceled_)
229       received_after_canceled_++;
230     ReleaseHandlesInMessage(*msg);
231     delete msg;
232     return true;
233   }
234
235   ResourceContext* resource_context() { return resource_context_; }
236
237  protected:
238   virtual ~TestFilter() {}
239
240  private:
241   void GetContexts(const ResourceHostMsg_Request& request,
242                    ResourceContext** resource_context,
243                    net::URLRequestContext** request_context) {
244     *resource_context = resource_context_;
245     *request_context = resource_context_->GetRequestContext();
246   }
247
248   ResourceContext* resource_context_;
249   bool canceled_;
250   int received_after_canceled_;
251
252   DISALLOW_COPY_AND_ASSIGN(TestFilter);
253 };
254
255
256 // This class forwards the incoming messages to the ResourceDispatcherHostTest.
257 // For the test, we want all the incoming messages to go to the same place,
258 // which is why this forwards.
259 class ForwardingFilter : public TestFilter {
260  public:
261   explicit ForwardingFilter(IPC::Sender* dest,
262                             ResourceContext* resource_context)
263       : TestFilter(resource_context),
264         dest_(dest) {
265   }
266
267   // TestFilter override
268   virtual bool Send(IPC::Message* msg) OVERRIDE {
269     return dest_->Send(msg);
270   }
271
272  private:
273   virtual ~ForwardingFilter() {}
274
275   IPC::Sender* dest_;
276
277   DISALLOW_COPY_AND_ASSIGN(ForwardingFilter);
278 };
279
280 // This class is a variation on URLRequestTestJob that will call
281 // URLRequest::WillStartUsingNetwork before starting.
282 class URLRequestTestDelayedNetworkJob : public net::URLRequestTestJob {
283  public:
284   URLRequestTestDelayedNetworkJob(net::URLRequest* request,
285                                   net::NetworkDelegate* network_delegate)
286       : net::URLRequestTestJob(request, network_delegate) {}
287
288   // Only start if not deferred for network start.
289   virtual void Start() OVERRIDE {
290     bool defer = false;
291     NotifyBeforeNetworkStart(&defer);
292     if (defer)
293       return;
294     net::URLRequestTestJob::Start();
295   }
296
297   virtual void ResumeNetworkStart() OVERRIDE {
298     net::URLRequestTestJob::StartAsync();
299   }
300
301  private:
302   virtual ~URLRequestTestDelayedNetworkJob() {}
303
304   DISALLOW_COPY_AND_ASSIGN(URLRequestTestDelayedNetworkJob);
305 };
306
307 // This class is a variation on URLRequestTestJob in that it does
308 // not complete start upon entry, only when specifically told to.
309 class URLRequestTestDelayedStartJob : public net::URLRequestTestJob {
310  public:
311   URLRequestTestDelayedStartJob(net::URLRequest* request,
312                                 net::NetworkDelegate* network_delegate)
313       : net::URLRequestTestJob(request, network_delegate) {
314     Init();
315   }
316   URLRequestTestDelayedStartJob(net::URLRequest* request,
317                                 net::NetworkDelegate* network_delegate,
318                                 bool auto_advance)
319       : net::URLRequestTestJob(request, network_delegate, auto_advance) {
320     Init();
321   }
322   URLRequestTestDelayedStartJob(net::URLRequest* request,
323                                 net::NetworkDelegate* network_delegate,
324                                 const std::string& response_headers,
325                                 const std::string& response_data,
326                                 bool auto_advance)
327       : net::URLRequestTestJob(request,
328                                network_delegate,
329                                response_headers,
330                                response_data,
331                                auto_advance) {
332     Init();
333   }
334
335   // Do nothing until you're told to.
336   virtual void Start() OVERRIDE {}
337
338   // Finish starting a URL request whose job is an instance of
339   // URLRequestTestDelayedStartJob.  It is illegal to call this routine
340   // with a URLRequest that does not use URLRequestTestDelayedStartJob.
341   static void CompleteStart(net::URLRequest* request) {
342     for (URLRequestTestDelayedStartJob* job = list_head_;
343          job;
344          job = job->next_) {
345       if (job->request() == request) {
346         job->net::URLRequestTestJob::Start();
347         return;
348       }
349     }
350     NOTREACHED();
351   }
352
353   static bool DelayedStartQueueEmpty() {
354     return !list_head_;
355   }
356
357   static void ClearQueue() {
358     if (list_head_) {
359       LOG(ERROR)
360           << "Unreleased entries on URLRequestTestDelayedStartJob delay queue"
361           << "; may result in leaks.";
362       list_head_ = NULL;
363     }
364   }
365
366  protected:
367   virtual ~URLRequestTestDelayedStartJob() {
368     for (URLRequestTestDelayedStartJob** job = &list_head_; *job;
369          job = &(*job)->next_) {
370       if (*job == this) {
371         *job = (*job)->next_;
372         return;
373       }
374     }
375     NOTREACHED();
376   }
377
378  private:
379   void Init() {
380     next_ = list_head_;
381     list_head_ = this;
382   }
383
384   static URLRequestTestDelayedStartJob* list_head_;
385   URLRequestTestDelayedStartJob* next_;
386 };
387
388 URLRequestTestDelayedStartJob*
389 URLRequestTestDelayedStartJob::list_head_ = NULL;
390
391 // This class is a variation on URLRequestTestJob in that it
392 // returns IO_pending errors before every read, not just the first one.
393 class URLRequestTestDelayedCompletionJob : public net::URLRequestTestJob {
394  public:
395   URLRequestTestDelayedCompletionJob(net::URLRequest* request,
396                                      net::NetworkDelegate* network_delegate)
397       : net::URLRequestTestJob(request, network_delegate) {}
398   URLRequestTestDelayedCompletionJob(net::URLRequest* request,
399                                      net::NetworkDelegate* network_delegate,
400                                      bool auto_advance)
401       : net::URLRequestTestJob(request, network_delegate, auto_advance) {}
402   URLRequestTestDelayedCompletionJob(net::URLRequest* request,
403                                      net::NetworkDelegate* network_delegate,
404                                      const std::string& response_headers,
405                                      const std::string& response_data,
406                                      bool auto_advance)
407       : net::URLRequestTestJob(request,
408                                network_delegate,
409                                response_headers,
410                                response_data,
411                                auto_advance) {}
412
413  protected:
414   virtual ~URLRequestTestDelayedCompletionJob() {}
415
416  private:
417   virtual bool NextReadAsync() OVERRIDE { return true; }
418 };
419
420 class URLRequestBigJob : public net::URLRequestSimpleJob {
421  public:
422   URLRequestBigJob(net::URLRequest* request,
423                    net::NetworkDelegate* network_delegate)
424       : net::URLRequestSimpleJob(request, network_delegate) {
425   }
426
427   virtual int GetData(std::string* mime_type,
428                       std::string* charset,
429                       std::string* data,
430                       const net::CompletionCallback& callback) const OVERRIDE {
431     *mime_type = "text/plain";
432     *charset = "UTF-8";
433
434     std::string text;
435     int count;
436     if (!ParseURL(request_->url(), &text, &count))
437       return net::ERR_INVALID_URL;
438
439     data->reserve(text.size() * count);
440     for (int i = 0; i < count; ++i)
441       data->append(text);
442
443     return net::OK;
444   }
445
446  private:
447   virtual ~URLRequestBigJob() {}
448
449   // big-job:substring,N
450   static bool ParseURL(const GURL& url, std::string* text, int* count) {
451     std::vector<std::string> parts;
452     base::SplitString(url.path(), ',', &parts);
453
454     if (parts.size() != 2)
455       return false;
456
457     *text = parts[0];
458     return base::StringToInt(parts[1], count);
459   }
460 };
461
462 class ResourceDispatcherHostTest;
463
464 class TestURLRequestJobFactory : public net::URLRequestJobFactory {
465  public:
466   explicit TestURLRequestJobFactory(ResourceDispatcherHostTest* test_fixture)
467       : test_fixture_(test_fixture),
468         delay_start_(false),
469         delay_complete_(false),
470         network_start_notification_(false),
471         url_request_jobs_created_count_(0) {
472   }
473
474   void HandleScheme(const std::string& scheme) {
475     supported_schemes_.insert(scheme);
476   }
477
478   int url_request_jobs_created_count() const {
479     return url_request_jobs_created_count_;
480   }
481
482   void SetDelayedStartJobGeneration(bool delay_job_start) {
483     delay_start_ = delay_job_start;
484   }
485
486   void SetDelayedCompleteJobGeneration(bool delay_job_complete) {
487     delay_complete_ = delay_job_complete;
488   }
489
490   void SetNetworkStartNotificationJobGeneration(bool notification) {
491     network_start_notification_ = notification;
492   }
493
494   virtual net::URLRequestJob* MaybeCreateJobWithProtocolHandler(
495       const std::string& scheme,
496       net::URLRequest* request,
497       net::NetworkDelegate* network_delegate) const OVERRIDE;
498
499   virtual bool IsHandledProtocol(const std::string& scheme) const OVERRIDE {
500     return supported_schemes_.count(scheme) > 0;
501   }
502
503   virtual bool IsHandledURL(const GURL& url) const OVERRIDE {
504     return supported_schemes_.count(url.scheme()) > 0;
505   }
506
507   virtual bool IsSafeRedirectTarget(const GURL& location) const OVERRIDE {
508     return false;
509   }
510
511  private:
512   ResourceDispatcherHostTest* test_fixture_;
513   bool delay_start_;
514   bool delay_complete_;
515   bool network_start_notification_;
516   mutable int url_request_jobs_created_count_;
517   std::set<std::string> supported_schemes_;
518
519   DISALLOW_COPY_AND_ASSIGN(TestURLRequestJobFactory);
520 };
521
522 // Associated with an URLRequest to determine if the URLRequest gets deleted.
523 class TestUserData : public base::SupportsUserData::Data {
524  public:
525   explicit TestUserData(bool* was_deleted)
526       : was_deleted_(was_deleted) {
527   }
528
529   virtual ~TestUserData() {
530     *was_deleted_ = true;
531   }
532
533  private:
534   bool* was_deleted_;
535 };
536
537 class TransfersAllNavigationsContentBrowserClient
538     : public TestContentBrowserClient {
539  public:
540   virtual bool ShouldSwapProcessesForRedirect(ResourceContext* resource_context,
541                                               const GURL& current_url,
542                                               const GURL& new_url) OVERRIDE {
543     return true;
544   }
545 };
546
547 enum GenericResourceThrottleFlags {
548   NONE                      = 0,
549   DEFER_STARTING_REQUEST    = 1 << 0,
550   DEFER_PROCESSING_RESPONSE = 1 << 1,
551   CANCEL_BEFORE_START       = 1 << 2,
552   DEFER_NETWORK_START       = 1 << 3
553 };
554
555 // Throttle that tracks the current throttle blocking a request.  Only one
556 // can throttle any request at a time.
557 class GenericResourceThrottle : public ResourceThrottle {
558  public:
559   // The value is used to indicate that the throttle should not provide
560   // a error code when cancelling a request. net::OK is used, because this
561   // is not an error code.
562   static const int USE_DEFAULT_CANCEL_ERROR_CODE = net::OK;
563
564   GenericResourceThrottle(int flags, int code)
565       : flags_(flags),
566         error_code_for_cancellation_(code) {
567   }
568
569   virtual ~GenericResourceThrottle() {
570     if (active_throttle_ == this)
571       active_throttle_ = NULL;
572   }
573
574   // ResourceThrottle implementation:
575   virtual void WillStartRequest(bool* defer) OVERRIDE {
576     ASSERT_EQ(NULL, active_throttle_);
577     if (flags_ & DEFER_STARTING_REQUEST) {
578       active_throttle_ = this;
579       *defer = true;
580     }
581
582     if (flags_ & CANCEL_BEFORE_START) {
583       if (error_code_for_cancellation_ == USE_DEFAULT_CANCEL_ERROR_CODE) {
584         controller()->Cancel();
585       } else {
586         controller()->CancelWithError(error_code_for_cancellation_);
587       }
588     }
589   }
590
591   virtual void WillProcessResponse(bool* defer) OVERRIDE {
592     ASSERT_EQ(NULL, active_throttle_);
593     if (flags_ & DEFER_PROCESSING_RESPONSE) {
594       active_throttle_ = this;
595       *defer = true;
596     }
597   }
598
599   virtual void WillStartUsingNetwork(bool* defer) OVERRIDE {
600     ASSERT_EQ(NULL, active_throttle_);
601
602     if (flags_ & DEFER_NETWORK_START) {
603       active_throttle_ = this;
604       *defer = true;
605     }
606   }
607
608   virtual const char* GetNameForLogging() const OVERRIDE {
609     return "GenericResourceThrottle";
610   }
611
612   void Resume() {
613     ASSERT_TRUE(this == active_throttle_);
614     active_throttle_ = NULL;
615     controller()->Resume();
616   }
617
618   static GenericResourceThrottle* active_throttle() {
619     return active_throttle_;
620   }
621
622  private:
623   int flags_;  // bit-wise union of GenericResourceThrottleFlags.
624   int error_code_for_cancellation_;
625
626   // The currently active throttle, if any.
627   static GenericResourceThrottle* active_throttle_;
628 };
629 // static
630 GenericResourceThrottle* GenericResourceThrottle::active_throttle_ = NULL;
631
632 class TestResourceDispatcherHostDelegate
633     : public ResourceDispatcherHostDelegate {
634  public:
635   TestResourceDispatcherHostDelegate()
636       : create_two_throttles_(false),
637         flags_(NONE),
638         error_code_for_cancellation_(
639             GenericResourceThrottle::USE_DEFAULT_CANCEL_ERROR_CODE) {
640   }
641
642   void set_url_request_user_data(base::SupportsUserData::Data* user_data) {
643     user_data_.reset(user_data);
644   }
645
646   void set_flags(int value) {
647     flags_ = value;
648   }
649
650   void set_error_code_for_cancellation(int code) {
651     error_code_for_cancellation_ = code;
652   }
653
654   void set_create_two_throttles(bool create_two_throttles) {
655     create_two_throttles_ = create_two_throttles;
656   }
657
658   // ResourceDispatcherHostDelegate implementation:
659
660   virtual void RequestBeginning(
661       net::URLRequest* request,
662       ResourceContext* resource_context,
663       AppCacheService* appcache_service,
664       ResourceType resource_type,
665       int child_id,
666       int route_id,
667       ScopedVector<ResourceThrottle>* throttles) OVERRIDE {
668     if (user_data_) {
669       const void* key = user_data_.get();
670       request->SetUserData(key, user_data_.release());
671     }
672
673     if (flags_ != NONE) {
674       throttles->push_back(new GenericResourceThrottle(
675           flags_, error_code_for_cancellation_));
676       if (create_two_throttles_)
677         throttles->push_back(new GenericResourceThrottle(
678             flags_, error_code_for_cancellation_));
679     }
680   }
681
682  private:
683   bool create_two_throttles_;
684   int flags_;
685   int error_code_for_cancellation_;
686   scoped_ptr<base::SupportsUserData::Data> user_data_;
687 };
688
689 // Waits for a ShareableFileReference to be released.
690 class ShareableFileReleaseWaiter {
691  public:
692   ShareableFileReleaseWaiter(const base::FilePath& path) {
693     scoped_refptr<ShareableFileReference> file =
694         ShareableFileReference::Get(path);
695     file->AddFinalReleaseCallback(
696         base::Bind(&ShareableFileReleaseWaiter::Released,
697                    base::Unretained(this)));
698   }
699
700   void Wait() {
701     loop_.Run();
702   }
703
704  private:
705   void Released(const base::FilePath& path) {
706     loop_.Quit();
707   }
708
709   base::RunLoop loop_;
710
711   DISALLOW_COPY_AND_ASSIGN(ShareableFileReleaseWaiter);
712 };
713
714 class ResourceDispatcherHostTest : public testing::Test,
715                                    public IPC::Sender {
716  public:
717   ResourceDispatcherHostTest()
718       : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP),
719         old_factory_(NULL),
720         send_data_received_acks_(false) {
721     browser_context_.reset(new TestBrowserContext());
722     BrowserContext::EnsureResourceContextInitialized(browser_context_.get());
723     base::RunLoop().RunUntilIdle();
724     filter_ = MakeForwardingFilter();
725     // TODO(cbentzel): Better way to get URLRequestContext?
726     net::URLRequestContext* request_context =
727         browser_context_->GetResourceContext()->GetRequestContext();
728     job_factory_.reset(new TestURLRequestJobFactory(this));
729     request_context->set_job_factory(job_factory_.get());
730     request_context->set_network_delegate(&network_delegate_);
731   }
732
733   // IPC::Sender implementation
734   virtual bool Send(IPC::Message* msg) OVERRIDE {
735     accum_.AddMessage(*msg);
736
737     if (send_data_received_acks_ &&
738         msg->type() == ResourceMsg_DataReceived::ID) {
739       GenerateDataReceivedACK(*msg);
740     }
741
742     if (wait_for_request_complete_loop_ &&
743         msg->type() == ResourceMsg_RequestComplete::ID) {
744       wait_for_request_complete_loop_->Quit();
745     }
746
747     // Do not release handles in it yet; the accumulator owns them now.
748     delete msg;
749     return true;
750   }
751
752  protected:
753   friend class TestURLRequestJobFactory;
754
755   // testing::Test
756   virtual void SetUp() OVERRIDE {
757     ChildProcessSecurityPolicyImpl::GetInstance()->Add(0);
758     HandleScheme("test");
759   }
760
761   virtual void TearDown() {
762     EXPECT_TRUE(URLRequestTestDelayedStartJob::DelayedStartQueueEmpty());
763     URLRequestTestDelayedStartJob::ClearQueue();
764
765     for (std::set<int>::iterator it = child_ids_.begin();
766          it != child_ids_.end(); ++it) {
767       host_.CancelRequestsForProcess(*it);
768     }
769
770     host_.Shutdown();
771
772     ChildProcessSecurityPolicyImpl::GetInstance()->Remove(0);
773
774     // Flush the message loop to make application verifiers happy.
775     if (ResourceDispatcherHostImpl::Get())
776       ResourceDispatcherHostImpl::Get()->CancelRequestsForContext(
777           browser_context_->GetResourceContext());
778
779     browser_context_.reset();
780     base::RunLoop().RunUntilIdle();
781   }
782
783   // Creates a new ForwardingFilter and registers it with |child_ids_| so as not
784   // to leak per-child state on test shutdown.
785   ForwardingFilter* MakeForwardingFilter() {
786     ForwardingFilter* filter =
787         new ForwardingFilter(this, browser_context_->GetResourceContext());
788     child_ids_.insert(filter->child_id());
789     return filter;
790   }
791
792   // Creates a request using the current test object as the filter and
793   // SubResource as the resource type.
794   void MakeTestRequest(int render_view_id,
795                        int request_id,
796                        const GURL& url);
797
798   // Generates a request using the given filter and resource type.
799   void MakeTestRequestWithResourceType(ResourceMessageFilter* filter,
800                                        int render_view_id,
801                                        int request_id,
802                                        const GURL& url,
803                                        ResourceType type);
804
805   void CancelRequest(int request_id);
806   void RendererCancelRequest(int request_id) {
807     ResourceMessageFilter* old_filter = SetFilter(filter_.get());
808     host_.OnCancelRequest(request_id);
809     SetFilter(old_filter);
810   }
811
812   void CompleteStartRequest(int request_id);
813   void CompleteStartRequest(ResourceMessageFilter* filter, int request_id);
814
815   net::TestNetworkDelegate* network_delegate() { return &network_delegate_; }
816
817   void EnsureSchemeIsAllowed(const std::string& scheme) {
818     ChildProcessSecurityPolicyImpl* policy =
819         ChildProcessSecurityPolicyImpl::GetInstance();
820     if (!policy->IsWebSafeScheme(scheme))
821       policy->RegisterWebSafeScheme(scheme);
822   }
823
824   // Sets a particular response for any request from now on. To switch back to
825   // the default bahavior, pass an empty |headers|. |headers| should be raw-
826   // formatted (NULLs instead of EOLs).
827   void SetResponse(const std::string& headers, const std::string& data) {
828     response_headers_ = net::HttpUtil::AssembleRawHeaders(headers.data(),
829                                                           headers.size());
830     response_data_ = data;
831   }
832   void SetResponse(const std::string& headers) {
833     SetResponse(headers, std::string());
834   }
835
836   void SendDataReceivedACKs(bool send_acks) {
837     send_data_received_acks_ = send_acks;
838   }
839
840   // Intercepts requests for the given protocol.
841   void HandleScheme(const std::string& scheme) {
842     job_factory_->HandleScheme(scheme);
843     EnsureSchemeIsAllowed(scheme);
844   }
845
846   void GenerateDataReceivedACK(const IPC::Message& msg) {
847     EXPECT_EQ(ResourceMsg_DataReceived::ID, msg.type());
848
849     int request_id = -1;
850     bool result = PickleIterator(msg).ReadInt(&request_id);
851     DCHECK(result);
852     scoped_ptr<IPC::Message> ack(
853         new ResourceHostMsg_DataReceived_ACK(request_id));
854
855     base::MessageLoop::current()->PostTask(
856         FROM_HERE,
857         base::Bind(&GenerateIPCMessage, filter_, base::Passed(&ack)));
858   }
859
860   // Setting filters for testing renderer messages.
861   // Returns the previous filter.
862   ResourceMessageFilter* SetFilter(ResourceMessageFilter* new_filter) {
863     ResourceMessageFilter* old_filter = host_.filter_;
864     host_.filter_ = new_filter;
865     return old_filter;
866   }
867
868   void WaitForRequestComplete() {
869     DCHECK(!wait_for_request_complete_loop_);
870     wait_for_request_complete_loop_.reset(new base::RunLoop);
871     wait_for_request_complete_loop_->Run();
872     wait_for_request_complete_loop_.reset();
873   }
874
875   content::TestBrowserThreadBundle thread_bundle_;
876   scoped_ptr<TestBrowserContext> browser_context_;
877   scoped_ptr<TestURLRequestJobFactory> job_factory_;
878   scoped_refptr<ForwardingFilter> filter_;
879   net::TestNetworkDelegate network_delegate_;
880   ResourceDispatcherHostImpl host_;
881   ResourceIPCAccumulator accum_;
882   std::string response_headers_;
883   std::string response_data_;
884   std::string scheme_;
885   net::URLRequest::ProtocolFactory* old_factory_;
886   bool send_data_received_acks_;
887   std::set<int> child_ids_;
888   scoped_ptr<base::RunLoop> wait_for_request_complete_loop_;
889 };
890
891 void ResourceDispatcherHostTest::MakeTestRequest(int render_view_id,
892                                                  int request_id,
893                                                  const GURL& url) {
894   MakeTestRequestWithResourceType(filter_.get(), render_view_id, request_id,
895                                   url, RESOURCE_TYPE_SUB_RESOURCE);
896 }
897
898 void ResourceDispatcherHostTest::MakeTestRequestWithResourceType(
899     ResourceMessageFilter* filter,
900     int render_view_id,
901     int request_id,
902     const GURL& url,
903     ResourceType type) {
904   ResourceHostMsg_Request request =
905       CreateResourceRequest("GET", type, url);
906   ResourceHostMsg_RequestResource msg(render_view_id, request_id, request);
907   host_.OnMessageReceived(msg, filter);
908   KickOffRequest();
909 }
910
911 void ResourceDispatcherHostTest::CancelRequest(int request_id) {
912   host_.CancelRequest(filter_->child_id(), request_id);
913 }
914
915 void ResourceDispatcherHostTest::CompleteStartRequest(int request_id) {
916   CompleteStartRequest(filter_.get(), request_id);
917 }
918
919 void ResourceDispatcherHostTest::CompleteStartRequest(
920     ResourceMessageFilter* filter,
921     int request_id) {
922   GlobalRequestID gid(filter->child_id(), request_id);
923   net::URLRequest* req = host_.GetURLRequest(gid);
924   EXPECT_TRUE(req);
925   if (req)
926     URLRequestTestDelayedStartJob::CompleteStart(req);
927 }
928
929 void CheckRequestCompleteErrorCode(const IPC::Message& message,
930                                    int expected_error_code) {
931   // Verify the expected error code was received.
932   int request_id;
933   int error_code;
934
935   ASSERT_EQ(ResourceMsg_RequestComplete::ID, message.type());
936
937   PickleIterator iter(message);
938   ASSERT_TRUE(IPC::ReadParam(&message, &iter, &request_id));
939   ASSERT_TRUE(IPC::ReadParam(&message, &iter, &error_code));
940   ASSERT_EQ(expected_error_code, error_code);
941 }
942
943 testing::AssertionResult ExtractDataOffsetAndLength(const IPC::Message& message,
944                                                     int* data_offset,
945                                                     int* data_length) {
946   PickleIterator iter(message);
947   int request_id;
948   if (!IPC::ReadParam(&message, &iter, &request_id))
949     return testing::AssertionFailure() << "Could not read request_id";
950   if (!IPC::ReadParam(&message, &iter, data_offset))
951     return testing::AssertionFailure() << "Could not read data_offset";
952   if (!IPC::ReadParam(&message, &iter, data_length))
953     return testing::AssertionFailure() << "Could not read data_length";
954   return testing::AssertionSuccess();
955 }
956
957 void CheckSuccessfulRequestWithErrorCode(
958     const std::vector<IPC::Message>& messages,
959     const std::string& reference_data,
960     int expected_error) {
961   // A successful request will have received 4 messages:
962   //     ReceivedResponse    (indicates headers received)
963   //     SetDataBuffer       (contains shared memory handle)
964   //     DataReceived        (data offset and length into shared memory)
965   //     RequestComplete     (request is done)
966   //
967   // This function verifies that we received 4 messages and that they are
968   // appropriate. It allows for an error code other than net::OK if the request
969   // should successfully receive data and then abort, e.g., on cancel.
970   ASSERT_EQ(4U, messages.size());
971
972   // The first messages should be received response
973   ASSERT_EQ(ResourceMsg_ReceivedResponse::ID, messages[0].type());
974
975   ASSERT_EQ(ResourceMsg_SetDataBuffer::ID, messages[1].type());
976
977   PickleIterator iter(messages[1]);
978   int request_id;
979   ASSERT_TRUE(IPC::ReadParam(&messages[1], &iter, &request_id));
980   base::SharedMemoryHandle shm_handle;
981   ASSERT_TRUE(IPC::ReadParam(&messages[1], &iter, &shm_handle));
982   int shm_size;
983   ASSERT_TRUE(IPC::ReadParam(&messages[1], &iter, &shm_size));
984
985   // Followed by the data, currently we only do the data in one chunk, but
986   // should probably test multiple chunks later
987   ASSERT_EQ(ResourceMsg_DataReceived::ID, messages[2].type());
988
989   int data_offset;
990   int data_length;
991   ASSERT_TRUE(
992       ExtractDataOffsetAndLength(messages[2], &data_offset, &data_length));
993
994   ASSERT_EQ(reference_data.size(), static_cast<size_t>(data_length));
995   ASSERT_GE(shm_size, data_length);
996
997   base::SharedMemory shared_mem(shm_handle, true);  // read only
998   shared_mem.Map(data_length);
999   const char* data = static_cast<char*>(shared_mem.memory()) + data_offset;
1000   ASSERT_EQ(0, memcmp(reference_data.c_str(), data, data_length));
1001
1002   // The last message should be all data received.
1003   CheckRequestCompleteErrorCode(messages[3], expected_error);
1004 }
1005
1006 void CheckSuccessfulRequest(const std::vector<IPC::Message>& messages,
1007                             const std::string& reference_data) {
1008   CheckSuccessfulRequestWithErrorCode(messages, reference_data, net::OK);
1009 }
1010
1011 void CheckSuccessfulRedirect(const std::vector<IPC::Message>& messages,
1012                              const std::string& reference_data) {
1013   ASSERT_EQ(5U, messages.size());
1014   ASSERT_EQ(ResourceMsg_ReceivedRedirect::ID, messages[0].type());
1015
1016   const std::vector<IPC::Message> second_req_msgs =
1017       std::vector<IPC::Message>(messages.begin() + 1, messages.end());
1018   CheckSuccessfulRequest(second_req_msgs, reference_data);
1019 }
1020
1021 void CheckFailedRequest(const std::vector<IPC::Message>& messages,
1022                         const std::string& reference_data,
1023                         int expected_error) {
1024   ASSERT_LT(0U, messages.size());
1025   ASSERT_GE(2U, messages.size());
1026   size_t failure_index = messages.size() - 1;
1027
1028   if (messages.size() == 2) {
1029     EXPECT_EQ(ResourceMsg_ReceivedResponse::ID, messages[0].type());
1030   }
1031
1032   CheckRequestCompleteErrorCode(messages[failure_index], expected_error);
1033 }
1034
1035 // Tests whether many messages get dispatched properly.
1036 TEST_F(ResourceDispatcherHostTest, TestMany) {
1037   MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
1038   MakeTestRequest(0, 2, net::URLRequestTestJob::test_url_2());
1039   MakeTestRequest(0, 3, net::URLRequestTestJob::test_url_3());
1040   MakeTestRequestWithResourceType(filter_.get(), 0, 4,
1041                                   net::URLRequestTestJob::test_url_4(),
1042                                   RESOURCE_TYPE_PREFETCH);  // detachable type
1043   MakeTestRequest(0, 5, net::URLRequestTestJob::test_url_redirect_to_url_2());
1044
1045   // Finish the redirection
1046   ResourceHostMsg_FollowRedirect redirect_msg(5);
1047   host_.OnMessageReceived(redirect_msg, filter_.get());
1048   base::MessageLoop::current()->RunUntilIdle();
1049
1050   // flush all the pending requests
1051   while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1052
1053   // sorts out all the messages we saw by request
1054   ResourceIPCAccumulator::ClassifiedMessages msgs;
1055   accum_.GetClassifiedMessages(&msgs);
1056
1057   // there are five requests, so we should have gotten them classified as such
1058   ASSERT_EQ(5U, msgs.size());
1059
1060   CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_1());
1061   CheckSuccessfulRequest(msgs[1], net::URLRequestTestJob::test_data_2());
1062   CheckSuccessfulRequest(msgs[2], net::URLRequestTestJob::test_data_3());
1063   CheckSuccessfulRequest(msgs[3], net::URLRequestTestJob::test_data_4());
1064   CheckSuccessfulRedirect(msgs[4], net::URLRequestTestJob::test_data_2());
1065 }
1066
1067 // Tests whether messages get canceled properly. We issue four requests,
1068 // cancel two of them, and make sure that each sent the proper notifications.
1069 TEST_F(ResourceDispatcherHostTest, Cancel) {
1070   MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
1071   MakeTestRequest(0, 2, net::URLRequestTestJob::test_url_2());
1072   MakeTestRequest(0, 3, net::URLRequestTestJob::test_url_3());
1073
1074   MakeTestRequestWithResourceType(filter_.get(), 0, 4,
1075                                   net::URLRequestTestJob::test_url_4(),
1076                                   RESOURCE_TYPE_PREFETCH);  // detachable type
1077
1078   CancelRequest(2);
1079
1080   // Cancel request must come from the renderer for a detachable resource to
1081   // delay.
1082   RendererCancelRequest(4);
1083
1084   // The handler should have been detached now.
1085   GlobalRequestID global_request_id(filter_->child_id(), 4);
1086   ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest(
1087       host_.GetURLRequest(global_request_id));
1088   ASSERT_TRUE(info->detachable_handler()->is_detached());
1089
1090   // flush all the pending requests
1091   while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1092   base::MessageLoop::current()->RunUntilIdle();
1093
1094   // Everything should be out now.
1095   EXPECT_EQ(0, host_.pending_requests());
1096
1097   ResourceIPCAccumulator::ClassifiedMessages msgs;
1098   accum_.GetClassifiedMessages(&msgs);
1099
1100   // there are four requests, so we should have gotten them classified as such
1101   ASSERT_EQ(4U, msgs.size());
1102
1103   CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_1());
1104   CheckSuccessfulRequest(msgs[2], net::URLRequestTestJob::test_data_3());
1105
1106   // Check that request 2 and 4 got canceled, as far as the renderer is
1107   // concerned.  Request 2 will have been deleted.
1108   ASSERT_EQ(1U, msgs[1].size());
1109   ASSERT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[1][0].type());
1110
1111   ASSERT_EQ(2U, msgs[3].size());
1112   ASSERT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[3][0].type());
1113   CheckRequestCompleteErrorCode(msgs[3][1], net::ERR_ABORTED);
1114
1115   // However, request 4 should have actually gone to completion. (Only request 2
1116   // was canceled.)
1117   EXPECT_EQ(4, network_delegate()->completed_requests());
1118   EXPECT_EQ(1, network_delegate()->canceled_requests());
1119   EXPECT_EQ(0, network_delegate()->error_count());
1120 }
1121
1122 // Shows that detachable requests will timeout if the request takes too long to
1123 // complete.
1124 TEST_F(ResourceDispatcherHostTest, DetachedResourceTimesOut) {
1125   MakeTestRequestWithResourceType(filter_.get(), 0, 1,
1126                                   net::URLRequestTestJob::test_url_2(),
1127                                   RESOURCE_TYPE_PREFETCH);  // detachable type
1128   GlobalRequestID global_request_id(filter_->child_id(), 1);
1129   ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest(
1130       host_.GetURLRequest(global_request_id));
1131   ASSERT_TRUE(info->detachable_handler());
1132   info->detachable_handler()->set_cancel_delay(
1133       base::TimeDelta::FromMilliseconds(200));
1134   base::MessageLoop::current()->RunUntilIdle();
1135
1136   RendererCancelRequest(1);
1137
1138   // From the renderer's perspective, the request was cancelled.
1139   ResourceIPCAccumulator::ClassifiedMessages msgs;
1140   accum_.GetClassifiedMessages(&msgs);
1141   ASSERT_EQ(1U, msgs.size());
1142   ASSERT_EQ(2U, msgs[0].size());
1143   ASSERT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[0][0].type());
1144   CheckRequestCompleteErrorCode(msgs[0][1], net::ERR_ABORTED);
1145
1146   // But it continues detached.
1147   EXPECT_EQ(1, host_.pending_requests());
1148   EXPECT_TRUE(info->detachable_handler()->is_detached());
1149
1150   // Wait until after the delay timer times out before we start processing any
1151   // messages.
1152   base::OneShotTimer<base::MessageLoop> timer;
1153   timer.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(210),
1154               base::MessageLoop::current(), &base::MessageLoop::QuitWhenIdle);
1155   base::MessageLoop::current()->Run();
1156
1157   // The prefetch should be cancelled by now.
1158   EXPECT_EQ(0, host_.pending_requests());
1159   EXPECT_EQ(1, network_delegate()->completed_requests());
1160   EXPECT_EQ(1, network_delegate()->canceled_requests());
1161   EXPECT_EQ(0, network_delegate()->error_count());
1162 }
1163
1164 // If the filter has disappeared then detachable resources should continue to
1165 // load.
1166 TEST_F(ResourceDispatcherHostTest, DeletedFilterDetached) {
1167   // test_url_1's data is available synchronously, so use 2 and 3.
1168   ResourceHostMsg_Request request_prefetch = CreateResourceRequest(
1169       "GET", RESOURCE_TYPE_PREFETCH, net::URLRequestTestJob::test_url_2());
1170   ResourceHostMsg_Request request_ping = CreateResourceRequest(
1171       "GET", RESOURCE_TYPE_PING, net::URLRequestTestJob::test_url_3());
1172
1173   ResourceHostMsg_RequestResource msg_prefetch(0, 1, request_prefetch);
1174   host_.OnMessageReceived(msg_prefetch, filter_);
1175   ResourceHostMsg_RequestResource msg_ping(0, 2, request_ping);
1176   host_.OnMessageReceived(msg_ping, filter_);
1177
1178   // Remove the filter before processing the requests by simulating channel
1179   // closure.
1180   ResourceRequestInfoImpl* info_prefetch = ResourceRequestInfoImpl::ForRequest(
1181       host_.GetURLRequest(GlobalRequestID(filter_->child_id(), 1)));
1182   ResourceRequestInfoImpl* info_ping = ResourceRequestInfoImpl::ForRequest(
1183       host_.GetURLRequest(GlobalRequestID(filter_->child_id(), 2)));
1184   DCHECK_EQ(filter_.get(), info_prefetch->filter());
1185   DCHECK_EQ(filter_.get(), info_ping->filter());
1186   filter_->OnChannelClosing();
1187   info_prefetch->filter_.reset();
1188   info_ping->filter_.reset();
1189
1190   // From the renderer's perspective, the requests were cancelled.
1191   ResourceIPCAccumulator::ClassifiedMessages msgs;
1192   accum_.GetClassifiedMessages(&msgs);
1193   ASSERT_EQ(2U, msgs.size());
1194   CheckRequestCompleteErrorCode(msgs[0][0], net::ERR_ABORTED);
1195   CheckRequestCompleteErrorCode(msgs[1][0], net::ERR_ABORTED);
1196
1197   // But it continues detached.
1198   EXPECT_EQ(2, host_.pending_requests());
1199   EXPECT_TRUE(info_prefetch->detachable_handler()->is_detached());
1200   EXPECT_TRUE(info_ping->detachable_handler()->is_detached());
1201
1202   KickOffRequest();
1203
1204   // Make sure the requests weren't canceled early.
1205   EXPECT_EQ(2, host_.pending_requests());
1206
1207   while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1208   base::MessageLoop::current()->RunUntilIdle();
1209
1210   EXPECT_EQ(0, host_.pending_requests());
1211   EXPECT_EQ(2, network_delegate()->completed_requests());
1212   EXPECT_EQ(0, network_delegate()->canceled_requests());
1213   EXPECT_EQ(0, network_delegate()->error_count());
1214 }
1215
1216 // If the filter has disappeared (original process dies) then detachable
1217 // resources should continue to load, even when redirected.
1218 TEST_F(ResourceDispatcherHostTest, DeletedFilterDetachedRedirect) {
1219   ResourceHostMsg_Request request = CreateResourceRequest(
1220       "GET", RESOURCE_TYPE_PREFETCH,
1221       net::URLRequestTestJob::test_url_redirect_to_url_2());
1222
1223   ResourceHostMsg_RequestResource msg(0, 1, request);
1224   host_.OnMessageReceived(msg, filter_);
1225
1226   // Remove the filter before processing the request by simulating channel
1227   // closure.
1228   GlobalRequestID global_request_id(filter_->child_id(), 1);
1229   ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest(
1230       host_.GetURLRequest(global_request_id));
1231   info->filter_->OnChannelClosing();
1232   info->filter_.reset();
1233
1234   // From the renderer's perspective, the request was cancelled.
1235   ResourceIPCAccumulator::ClassifiedMessages msgs;
1236   accum_.GetClassifiedMessages(&msgs);
1237   ASSERT_EQ(1U, msgs.size());
1238   CheckRequestCompleteErrorCode(msgs[0][0], net::ERR_ABORTED);
1239
1240   // But it continues detached.
1241   EXPECT_EQ(1, host_.pending_requests());
1242   EXPECT_TRUE(info->detachable_handler()->is_detached());
1243
1244   // Verify no redirects before resetting the filter.
1245   net::URLRequest* url_request = host_.GetURLRequest(global_request_id);
1246   EXPECT_EQ(1u, url_request->url_chain().size());
1247   KickOffRequest();
1248
1249   // Verify that a redirect was followed.
1250   EXPECT_EQ(2u, url_request->url_chain().size());
1251
1252   // Make sure the request wasn't canceled early.
1253   EXPECT_EQ(1, host_.pending_requests());
1254
1255   // Finish up the request.
1256   while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1257   base::MessageLoop::current()->RunUntilIdle();
1258
1259   EXPECT_EQ(0, host_.pending_requests());
1260   EXPECT_EQ(1, network_delegate()->completed_requests());
1261   EXPECT_EQ(0, network_delegate()->canceled_requests());
1262   EXPECT_EQ(0, network_delegate()->error_count());
1263 }
1264
1265 TEST_F(ResourceDispatcherHostTest, CancelWhileStartIsDeferred) {
1266   bool was_deleted = false;
1267
1268   // Arrange to have requests deferred before starting.
1269   TestResourceDispatcherHostDelegate delegate;
1270   delegate.set_flags(DEFER_STARTING_REQUEST);
1271   delegate.set_url_request_user_data(new TestUserData(&was_deleted));
1272   host_.SetDelegate(&delegate);
1273
1274   MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
1275   // We cancel from the renderer because all non-renderer cancels delete
1276   // the request synchronously.
1277   RendererCancelRequest(1);
1278
1279   // Our TestResourceThrottle should not have been deleted yet.  This is to
1280   // ensure that destruction of the URLRequest happens asynchronously to
1281   // calling CancelRequest.
1282   EXPECT_FALSE(was_deleted);
1283
1284   base::MessageLoop::current()->RunUntilIdle();
1285
1286   EXPECT_TRUE(was_deleted);
1287 }
1288
1289 TEST_F(ResourceDispatcherHostTest, DetachWhileStartIsDeferred) {
1290   bool was_deleted = false;
1291
1292   // Arrange to have requests deferred before starting.
1293   TestResourceDispatcherHostDelegate delegate;
1294   delegate.set_flags(DEFER_STARTING_REQUEST);
1295   delegate.set_url_request_user_data(new TestUserData(&was_deleted));
1296   host_.SetDelegate(&delegate);
1297
1298   MakeTestRequestWithResourceType(filter_.get(), 0, 1,
1299                                   net::URLRequestTestJob::test_url_1(),
1300                                   RESOURCE_TYPE_PREFETCH);  // detachable type
1301   // Cancel request must come from the renderer for a detachable resource to
1302   // detach.
1303   RendererCancelRequest(1);
1304
1305   // Even after driving the event loop, the request has not been deleted.
1306   EXPECT_FALSE(was_deleted);
1307
1308   // However, it is still throttled because the defer happened above the
1309   // DetachableResourceHandler.
1310   while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1311   base::MessageLoop::current()->RunUntilIdle();
1312   EXPECT_FALSE(was_deleted);
1313
1314   // Resume the request.
1315   GenericResourceThrottle* throttle =
1316       GenericResourceThrottle::active_throttle();
1317   ASSERT_TRUE(throttle);
1318   throttle->Resume();
1319
1320   // Now, the request completes.
1321   while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1322   base::MessageLoop::current()->RunUntilIdle();
1323   EXPECT_TRUE(was_deleted);
1324   EXPECT_EQ(1, network_delegate()->completed_requests());
1325   EXPECT_EQ(0, network_delegate()->canceled_requests());
1326   EXPECT_EQ(0, network_delegate()->error_count());
1327 }
1328
1329 // Tests if cancel is called in ResourceThrottle::WillStartRequest, then the
1330 // URLRequest will not be started.
1331 TEST_F(ResourceDispatcherHostTest, CancelInResourceThrottleWillStartRequest) {
1332   TestResourceDispatcherHostDelegate delegate;
1333   delegate.set_flags(CANCEL_BEFORE_START);
1334   host_.SetDelegate(&delegate);
1335
1336   MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
1337
1338   // flush all the pending requests
1339   while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1340   base::MessageLoop::current()->RunUntilIdle();
1341
1342   ResourceIPCAccumulator::ClassifiedMessages msgs;
1343   accum_.GetClassifiedMessages(&msgs);
1344
1345   // Check that request got canceled.
1346   ASSERT_EQ(1U, msgs[0].size());
1347   CheckRequestCompleteErrorCode(msgs[0][0], net::ERR_ABORTED);
1348
1349   // Make sure URLRequest is never started.
1350   EXPECT_EQ(0, job_factory_->url_request_jobs_created_count());
1351 }
1352
1353 TEST_F(ResourceDispatcherHostTest, PausedStartError) {
1354   // Arrange to have requests deferred before processing response headers.
1355   TestResourceDispatcherHostDelegate delegate;
1356   delegate.set_flags(DEFER_PROCESSING_RESPONSE);
1357   host_.SetDelegate(&delegate);
1358
1359   job_factory_->SetDelayedStartJobGeneration(true);
1360   MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_error());
1361   CompleteStartRequest(1);
1362
1363   // flush all the pending requests
1364   while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1365   base::MessageLoop::current()->RunUntilIdle();
1366
1367   EXPECT_EQ(0, host_.pending_requests());
1368 }
1369
1370 // Test the WillStartUsingNetwork throttle.
1371 TEST_F(ResourceDispatcherHostTest, ThrottleNetworkStart) {
1372   // Arrange to have requests deferred before processing response headers.
1373   TestResourceDispatcherHostDelegate delegate;
1374   delegate.set_flags(DEFER_NETWORK_START);
1375   host_.SetDelegate(&delegate);
1376
1377   job_factory_->SetNetworkStartNotificationJobGeneration(true);
1378   MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_2());
1379
1380   // Should have deferred for network start.
1381   GenericResourceThrottle* first_throttle =
1382       GenericResourceThrottle::active_throttle();
1383   ASSERT_TRUE(first_throttle);
1384   EXPECT_EQ(0, network_delegate()->completed_requests());
1385   EXPECT_EQ(1, host_.pending_requests());
1386
1387   first_throttle->Resume();
1388
1389   // Flush all the pending requests.
1390   while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1391   base::MessageLoop::current()->RunUntilIdle();
1392
1393   EXPECT_EQ(1, network_delegate()->completed_requests());
1394   EXPECT_EQ(0, host_.pending_requests());
1395 }
1396
1397 TEST_F(ResourceDispatcherHostTest, ThrottleAndResumeTwice) {
1398   // Arrange to have requests deferred before starting.
1399   TestResourceDispatcherHostDelegate delegate;
1400   delegate.set_flags(DEFER_STARTING_REQUEST);
1401   delegate.set_create_two_throttles(true);
1402   host_.SetDelegate(&delegate);
1403
1404   // Make sure the first throttle blocked the request, and then resume.
1405   MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
1406   GenericResourceThrottle* first_throttle =
1407       GenericResourceThrottle::active_throttle();
1408   ASSERT_TRUE(first_throttle);
1409   first_throttle->Resume();
1410
1411   // Make sure the second throttle blocked the request, and then resume.
1412   ASSERT_TRUE(GenericResourceThrottle::active_throttle());
1413   ASSERT_NE(first_throttle, GenericResourceThrottle::active_throttle());
1414   GenericResourceThrottle::active_throttle()->Resume();
1415
1416   ASSERT_FALSE(GenericResourceThrottle::active_throttle());
1417
1418   // The request is started asynchronously.
1419   base::MessageLoop::current()->RunUntilIdle();
1420
1421   // Flush all the pending requests.
1422   while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1423
1424   EXPECT_EQ(0, host_.pending_requests());
1425
1426   // Make sure the request completed successfully.
1427   ResourceIPCAccumulator::ClassifiedMessages msgs;
1428   accum_.GetClassifiedMessages(&msgs);
1429   ASSERT_EQ(1U, msgs.size());
1430   CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_1());
1431 }
1432
1433
1434 // Tests that the delegate can cancel a request and provide a error code.
1435 TEST_F(ResourceDispatcherHostTest, CancelInDelegate) {
1436   TestResourceDispatcherHostDelegate delegate;
1437   delegate.set_flags(CANCEL_BEFORE_START);
1438   delegate.set_error_code_for_cancellation(net::ERR_ACCESS_DENIED);
1439   host_.SetDelegate(&delegate);
1440
1441   MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
1442   // The request will get cancelled by the throttle.
1443
1444   // flush all the pending requests
1445   while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1446   base::MessageLoop::current()->RunUntilIdle();
1447
1448   ResourceIPCAccumulator::ClassifiedMessages msgs;
1449   accum_.GetClassifiedMessages(&msgs);
1450
1451   // Check the cancellation
1452   ASSERT_EQ(1U, msgs.size());
1453   ASSERT_EQ(1U, msgs[0].size());
1454
1455   CheckRequestCompleteErrorCode(msgs[0][0], net::ERR_ACCESS_DENIED);
1456 }
1457
1458 // Tests CancelRequestsForProcess
1459 TEST_F(ResourceDispatcherHostTest, TestProcessCancel) {
1460   scoped_refptr<TestFilter> test_filter = new TestFilter(
1461       browser_context_->GetResourceContext());
1462   child_ids_.insert(test_filter->child_id());
1463
1464   // request 1 goes to the test delegate
1465   ResourceHostMsg_Request request = CreateResourceRequest(
1466       "GET", RESOURCE_TYPE_SUB_RESOURCE, net::URLRequestTestJob::test_url_1());
1467
1468   MakeTestRequestWithResourceType(test_filter.get(), 0, 1,
1469                                   net::URLRequestTestJob::test_url_1(),
1470                                   RESOURCE_TYPE_SUB_RESOURCE);
1471
1472   // request 2 goes to us
1473   MakeTestRequest(0, 2, net::URLRequestTestJob::test_url_2());
1474
1475   // request 3 goes to the test delegate
1476   MakeTestRequestWithResourceType(test_filter.get(), 0, 3,
1477                                   net::URLRequestTestJob::test_url_3(),
1478                                   RESOURCE_TYPE_SUB_RESOURCE);
1479
1480   // request 4 goes to us
1481   MakeTestRequestWithResourceType(filter_.get(), 0, 4,
1482                                   net::URLRequestTestJob::test_url_4(),
1483                                   RESOURCE_TYPE_PREFETCH);  // detachable type
1484
1485
1486   // Make sure all requests have finished stage one. test_url_1 will have
1487   // finished.
1488   base::MessageLoop::current()->RunUntilIdle();
1489
1490   // TODO(mbelshe):
1491   // Now that the async IO path is in place, the IO always completes on the
1492   // initial call; so the requests have already completed.  This basically
1493   // breaks the whole test.
1494   //EXPECT_EQ(3, host_.pending_requests());
1495
1496   // Process test_url_2 and test_url_3 for one level so one callback is called.
1497   // We'll cancel test_url_4 (detachable) before processing it to verify that it
1498   // delays the cancel.
1499   for (int i = 0; i < 2; i++)
1500     EXPECT_TRUE(net::URLRequestTestJob::ProcessOnePendingMessage());
1501
1502   // Cancel the requests to the test process.
1503   host_.CancelRequestsForProcess(filter_->child_id());
1504   test_filter->set_canceled(true);
1505
1506   // The requests should all be cancelled, except request 4, which is detached.
1507   EXPECT_EQ(1, host_.pending_requests());
1508   GlobalRequestID global_request_id(filter_->child_id(), 4);
1509   ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest(
1510       host_.GetURLRequest(global_request_id));
1511   ASSERT_TRUE(info->detachable_handler()->is_detached());
1512
1513   // Flush all the pending requests.
1514   while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1515
1516   EXPECT_EQ(0, host_.pending_requests());
1517
1518   // The test delegate should not have gotten any messages after being canceled.
1519   ASSERT_EQ(0, test_filter->received_after_canceled());
1520
1521   // There should be two results.
1522   ResourceIPCAccumulator::ClassifiedMessages msgs;
1523   accum_.GetClassifiedMessages(&msgs);
1524   ASSERT_EQ(2U, msgs.size());
1525   CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_2());
1526   // The detachable request was cancelled by the renderer before it
1527   // finished. From the perspective of the renderer, it should have cancelled.
1528   ASSERT_EQ(2U, msgs[1].size());
1529   ASSERT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[1][0].type());
1530   CheckRequestCompleteErrorCode(msgs[1][1], net::ERR_ABORTED);
1531   // But it completed anyway. For the network stack, no requests were canceled.
1532   EXPECT_EQ(4, network_delegate()->completed_requests());
1533   EXPECT_EQ(0, network_delegate()->canceled_requests());
1534   EXPECT_EQ(0, network_delegate()->error_count());
1535 }
1536
1537 TEST_F(ResourceDispatcherHostTest, TestProcessCancelDetachedTimesOut) {
1538   MakeTestRequestWithResourceType(filter_.get(), 0, 1,
1539                                   net::URLRequestTestJob::test_url_4(),
1540                                   RESOURCE_TYPE_PREFETCH);  // detachable type
1541   GlobalRequestID global_request_id(filter_->child_id(), 1);
1542   ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest(
1543       host_.GetURLRequest(global_request_id));
1544   ASSERT_TRUE(info->detachable_handler());
1545   info->detachable_handler()->set_cancel_delay(
1546       base::TimeDelta::FromMilliseconds(200));
1547   base::MessageLoop::current()->RunUntilIdle();
1548
1549   // Cancel the requests to the test process.
1550   host_.CancelRequestsForProcess(filter_->child_id());
1551   EXPECT_EQ(1, host_.pending_requests());
1552
1553   // Wait until after the delay timer times out before we start processing any
1554   // messages.
1555   base::OneShotTimer<base::MessageLoop> timer;
1556   timer.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(210),
1557               base::MessageLoop::current(), &base::MessageLoop::QuitWhenIdle);
1558   base::MessageLoop::current()->Run();
1559
1560   // The prefetch should be cancelled by now.
1561   EXPECT_EQ(0, host_.pending_requests());
1562
1563   // In case any messages are still to be processed.
1564   while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1565   base::MessageLoop::current()->RunUntilIdle();
1566
1567   ResourceIPCAccumulator::ClassifiedMessages msgs;
1568   accum_.GetClassifiedMessages(&msgs);
1569
1570   ASSERT_EQ(1U, msgs.size());
1571
1572   // The request should have cancelled.
1573   ASSERT_EQ(2U, msgs[0].size());
1574   ASSERT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[0][0].type());
1575   CheckRequestCompleteErrorCode(msgs[0][1], net::ERR_ABORTED);
1576   // And not run to completion.
1577   EXPECT_EQ(1, network_delegate()->completed_requests());
1578   EXPECT_EQ(1, network_delegate()->canceled_requests());
1579   EXPECT_EQ(0, network_delegate()->error_count());
1580 }
1581
1582 // Tests blocking and resuming requests.
1583 TEST_F(ResourceDispatcherHostTest, TestBlockingResumingRequests) {
1584   host_.BlockRequestsForRoute(filter_->child_id(), 1);
1585   host_.BlockRequestsForRoute(filter_->child_id(), 2);
1586   host_.BlockRequestsForRoute(filter_->child_id(), 3);
1587
1588   MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
1589   MakeTestRequest(1, 2, net::URLRequestTestJob::test_url_2());
1590   MakeTestRequest(0, 3, net::URLRequestTestJob::test_url_3());
1591   MakeTestRequest(1, 4, net::URLRequestTestJob::test_url_1());
1592   MakeTestRequest(2, 5, net::URLRequestTestJob::test_url_2());
1593   MakeTestRequest(3, 6, net::URLRequestTestJob::test_url_3());
1594
1595   // Flush all the pending requests
1596   while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1597
1598   // Sort out all the messages we saw by request
1599   ResourceIPCAccumulator::ClassifiedMessages msgs;
1600   accum_.GetClassifiedMessages(&msgs);
1601
1602   // All requests but the 2 for the RVH 0 should have been blocked.
1603   ASSERT_EQ(2U, msgs.size());
1604
1605   CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_1());
1606   CheckSuccessfulRequest(msgs[1], net::URLRequestTestJob::test_data_3());
1607
1608   // Resume requests for RVH 1 and flush pending requests.
1609   host_.ResumeBlockedRequestsForRoute(filter_->child_id(), 1);
1610   KickOffRequest();
1611   while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1612
1613   msgs.clear();
1614   accum_.GetClassifiedMessages(&msgs);
1615   ASSERT_EQ(2U, msgs.size());
1616   CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_2());
1617   CheckSuccessfulRequest(msgs[1], net::URLRequestTestJob::test_data_1());
1618
1619   // Test that new requests are not blocked for RVH 1.
1620   MakeTestRequest(1, 7, net::URLRequestTestJob::test_url_1());
1621   while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1622   msgs.clear();
1623   accum_.GetClassifiedMessages(&msgs);
1624   ASSERT_EQ(1U, msgs.size());
1625   CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_1());
1626
1627   // Now resumes requests for all RVH (2 and 3).
1628   host_.ResumeBlockedRequestsForRoute(filter_->child_id(), 2);
1629   host_.ResumeBlockedRequestsForRoute(filter_->child_id(), 3);
1630   KickOffRequest();
1631   while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1632
1633   msgs.clear();
1634   accum_.GetClassifiedMessages(&msgs);
1635   ASSERT_EQ(2U, msgs.size());
1636   CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_2());
1637   CheckSuccessfulRequest(msgs[1], net::URLRequestTestJob::test_data_3());
1638 }
1639
1640 // Tests blocking and canceling requests.
1641 TEST_F(ResourceDispatcherHostTest, TestBlockingCancelingRequests) {
1642   host_.BlockRequestsForRoute(filter_->child_id(), 1);
1643
1644   MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
1645   MakeTestRequest(1, 2, net::URLRequestTestJob::test_url_2());
1646   MakeTestRequest(0, 3, net::URLRequestTestJob::test_url_3());
1647   MakeTestRequest(1, 4, net::URLRequestTestJob::test_url_1());
1648   // Blocked detachable resources should not delay cancellation.
1649   MakeTestRequestWithResourceType(filter_.get(), 1, 5,
1650                                   net::URLRequestTestJob::test_url_4(),
1651                                   RESOURCE_TYPE_PREFETCH);  // detachable type
1652
1653   // Flush all the pending requests.
1654   while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1655
1656   // Sort out all the messages we saw by request.
1657   ResourceIPCAccumulator::ClassifiedMessages msgs;
1658   accum_.GetClassifiedMessages(&msgs);
1659
1660   // The 2 requests for the RVH 0 should have been processed.
1661   ASSERT_EQ(2U, msgs.size());
1662
1663   CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_1());
1664   CheckSuccessfulRequest(msgs[1], net::URLRequestTestJob::test_data_3());
1665
1666   // Cancel requests for RVH 1.
1667   host_.CancelBlockedRequestsForRoute(filter_->child_id(), 1);
1668   KickOffRequest();
1669   while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1670
1671   msgs.clear();
1672   accum_.GetClassifiedMessages(&msgs);
1673   ASSERT_EQ(0U, msgs.size());
1674 }
1675
1676 // Tests that blocked requests are canceled if their associated process dies.
1677 TEST_F(ResourceDispatcherHostTest, TestBlockedRequestsProcessDies) {
1678   // This second filter is used to emulate a second process.
1679   scoped_refptr<ForwardingFilter> second_filter = MakeForwardingFilter();
1680
1681   host_.BlockRequestsForRoute(second_filter->child_id(), 0);
1682
1683   MakeTestRequestWithResourceType(filter_.get(), 0, 1,
1684                                   net::URLRequestTestJob::test_url_1(),
1685                                   RESOURCE_TYPE_SUB_RESOURCE);
1686   MakeTestRequestWithResourceType(second_filter.get(), 0, 2,
1687                                   net::URLRequestTestJob::test_url_2(),
1688                                   RESOURCE_TYPE_SUB_RESOURCE);
1689   MakeTestRequestWithResourceType(filter_.get(), 0, 3,
1690                                   net::URLRequestTestJob::test_url_3(),
1691                                   RESOURCE_TYPE_SUB_RESOURCE);
1692   MakeTestRequestWithResourceType(second_filter.get(), 0, 4,
1693                                   net::URLRequestTestJob::test_url_1(),
1694                                   RESOURCE_TYPE_SUB_RESOURCE);
1695   MakeTestRequestWithResourceType(second_filter.get(), 0, 5,
1696                                   net::URLRequestTestJob::test_url_4(),
1697                                   RESOURCE_TYPE_PREFETCH);  // detachable type
1698
1699   // Simulate process death.
1700   host_.CancelRequestsForProcess(second_filter->child_id());
1701
1702   // Flush all the pending requests.
1703   while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1704
1705   // Sort out all the messages we saw by request.
1706   ResourceIPCAccumulator::ClassifiedMessages msgs;
1707   accum_.GetClassifiedMessages(&msgs);
1708
1709   // The 2 requests for the RVH 0 should have been processed.  Note that
1710   // blocked detachable requests are canceled without delay.
1711   ASSERT_EQ(2U, msgs.size());
1712
1713   CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_1());
1714   CheckSuccessfulRequest(msgs[1], net::URLRequestTestJob::test_data_3());
1715
1716   EXPECT_TRUE(host_.blocked_loaders_map_.empty());
1717 }
1718
1719 // Tests that blocked requests don't leak when the ResourceDispatcherHost goes
1720 // away.  Note that we rely on Purify for finding the leaks if any.
1721 // If this test turns the Purify bot red, check the ResourceDispatcherHost
1722 // destructor to make sure the blocked requests are deleted.
1723 TEST_F(ResourceDispatcherHostTest, TestBlockedRequestsDontLeak) {
1724   // This second filter is used to emulate a second process.
1725   scoped_refptr<ForwardingFilter> second_filter = MakeForwardingFilter();
1726
1727   host_.BlockRequestsForRoute(filter_->child_id(), 1);
1728   host_.BlockRequestsForRoute(filter_->child_id(), 2);
1729   host_.BlockRequestsForRoute(second_filter->child_id(), 1);
1730
1731   MakeTestRequestWithResourceType(filter_.get(), 0, 1,
1732                                   net::URLRequestTestJob::test_url_1(),
1733                                   RESOURCE_TYPE_SUB_RESOURCE);
1734   MakeTestRequestWithResourceType(filter_.get(), 1, 2,
1735                                   net::URLRequestTestJob::test_url_2(),
1736                                   RESOURCE_TYPE_SUB_RESOURCE);
1737   MakeTestRequestWithResourceType(filter_.get(), 0, 3,
1738                                   net::URLRequestTestJob::test_url_3(),
1739                                   RESOURCE_TYPE_SUB_RESOURCE);
1740   MakeTestRequestWithResourceType(second_filter.get(), 1, 4,
1741                                   net::URLRequestTestJob::test_url_1(),
1742                                   RESOURCE_TYPE_SUB_RESOURCE);
1743   MakeTestRequestWithResourceType(filter_.get(), 2, 5,
1744                                   net::URLRequestTestJob::test_url_2(),
1745                                   RESOURCE_TYPE_SUB_RESOURCE);
1746   MakeTestRequestWithResourceType(filter_.get(), 2, 6,
1747                                   net::URLRequestTestJob::test_url_3(),
1748                                   RESOURCE_TYPE_SUB_RESOURCE);
1749   MakeTestRequestWithResourceType(filter_.get(), 0, 7,
1750                                   net::URLRequestTestJob::test_url_4(),
1751                                   RESOURCE_TYPE_PREFETCH);  // detachable type
1752   MakeTestRequestWithResourceType(second_filter.get(), 1, 8,
1753                                   net::URLRequestTestJob::test_url_4(),
1754                                   RESOURCE_TYPE_PREFETCH);  // detachable type
1755
1756   host_.CancelRequestsForProcess(filter_->child_id());
1757   host_.CancelRequestsForProcess(second_filter->child_id());
1758
1759   // Flush all the pending requests.
1760   while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1761 }
1762
1763 // Test the private helper method "CalculateApproximateMemoryCost()".
1764 TEST_F(ResourceDispatcherHostTest, CalculateApproximateMemoryCost) {
1765   net::URLRequestContext context;
1766   net::URLRequest req(
1767       GURL("http://www.google.com"), net::DEFAULT_PRIORITY, NULL, &context);
1768   EXPECT_EQ(4427,
1769             ResourceDispatcherHostImpl::CalculateApproximateMemoryCost(&req));
1770
1771   // Add 9 bytes of referrer.
1772   req.SetReferrer("123456789");
1773   EXPECT_EQ(4436,
1774             ResourceDispatcherHostImpl::CalculateApproximateMemoryCost(&req));
1775
1776   // Add 33 bytes of upload content.
1777   std::string upload_content;
1778   upload_content.resize(33);
1779   std::fill(upload_content.begin(), upload_content.end(), 'x');
1780   scoped_ptr<net::UploadElementReader> reader(new net::UploadBytesElementReader(
1781       upload_content.data(), upload_content.size()));
1782   req.set_upload(make_scoped_ptr(
1783       net::UploadDataStream::CreateWithReader(reader.Pass(), 0)));
1784
1785   // Since the upload throttling is disabled, this has no effect on the cost.
1786   EXPECT_EQ(4436,
1787             ResourceDispatcherHostImpl::CalculateApproximateMemoryCost(&req));
1788 }
1789
1790 // Test that too much memory for outstanding requests for a particular
1791 // render_process_host_id causes requests to fail.
1792 TEST_F(ResourceDispatcherHostTest, TooMuchOutstandingRequestsMemory) {
1793   // Expected cost of each request as measured by
1794   // ResourceDispatcherHost::CalculateApproximateMemoryCost().
1795   int kMemoryCostOfTest2Req =
1796       ResourceDispatcherHostImpl::kAvgBytesPerOutstandingRequest +
1797       std::string("GET").size() +
1798       net::URLRequestTestJob::test_url_2().spec().size();
1799
1800   // Tighten the bound on the ResourceDispatcherHost, to speed things up.
1801   int kMaxCostPerProcess = 440000;
1802   host_.set_max_outstanding_requests_cost_per_process(kMaxCostPerProcess);
1803
1804   // Determine how many instance of test_url_2() we can request before
1805   // throttling kicks in.
1806   size_t kMaxRequests = kMaxCostPerProcess / kMemoryCostOfTest2Req;
1807
1808   // This second filter is used to emulate a second process.
1809   scoped_refptr<ForwardingFilter> second_filter = MakeForwardingFilter();
1810
1811   // Saturate the number of outstanding requests for our process.
1812   for (size_t i = 0; i < kMaxRequests; ++i) {
1813     MakeTestRequestWithResourceType(filter_.get(), 0, i + 1,
1814                                     net::URLRequestTestJob::test_url_2(),
1815                                     RESOURCE_TYPE_SUB_RESOURCE);
1816   }
1817
1818   // Issue two more requests for our process -- these should fail immediately.
1819   MakeTestRequestWithResourceType(filter_.get(), 0, kMaxRequests + 1,
1820                                   net::URLRequestTestJob::test_url_2(),
1821                                   RESOURCE_TYPE_SUB_RESOURCE);
1822   MakeTestRequestWithResourceType(filter_.get(), 0, kMaxRequests + 2,
1823                                   net::URLRequestTestJob::test_url_2(),
1824                                   RESOURCE_TYPE_SUB_RESOURCE);
1825
1826   // Issue two requests for the second process -- these should succeed since
1827   // it is just process 0 that is saturated.
1828   MakeTestRequestWithResourceType(second_filter.get(), 0, kMaxRequests + 3,
1829                                   net::URLRequestTestJob::test_url_2(),
1830                                   RESOURCE_TYPE_SUB_RESOURCE);
1831   MakeTestRequestWithResourceType(second_filter.get(), 0, kMaxRequests + 4,
1832                                   net::URLRequestTestJob::test_url_2(),
1833                                   RESOURCE_TYPE_SUB_RESOURCE);
1834
1835   // Flush all the pending requests.
1836   while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1837   base::MessageLoop::current()->RunUntilIdle();
1838
1839   // Sorts out all the messages we saw by request.
1840   ResourceIPCAccumulator::ClassifiedMessages msgs;
1841   accum_.GetClassifiedMessages(&msgs);
1842
1843   // We issued (kMaxRequests + 4) total requests.
1844   ASSERT_EQ(kMaxRequests + 4, msgs.size());
1845
1846   // Check that the first kMaxRequests succeeded.
1847   for (size_t i = 0; i < kMaxRequests; ++i)
1848     CheckSuccessfulRequest(msgs[i], net::URLRequestTestJob::test_data_2());
1849
1850   // Check that the subsequent two requests (kMaxRequests + 1) and
1851   // (kMaxRequests + 2) were failed, since the per-process bound was reached.
1852   for (int i = 0; i < 2; ++i) {
1853     // Should have sent a single RequestComplete message.
1854     int index = kMaxRequests + i;
1855     CheckFailedRequest(msgs[index], net::URLRequestTestJob::test_data_2(),
1856                        net::ERR_INSUFFICIENT_RESOURCES);
1857   }
1858
1859   // The final 2 requests should have succeeded.
1860   CheckSuccessfulRequest(msgs[kMaxRequests + 2],
1861                          net::URLRequestTestJob::test_data_2());
1862   CheckSuccessfulRequest(msgs[kMaxRequests + 3],
1863                          net::URLRequestTestJob::test_data_2());
1864 }
1865
1866 // Test that when too many requests are outstanding for a particular
1867 // render_process_host_id, any subsequent request from it fails. Also verify
1868 // that the global limit is honored.
1869 TEST_F(ResourceDispatcherHostTest, TooManyOutstandingRequests) {
1870   // Tighten the bound on the ResourceDispatcherHost, to speed things up.
1871   const size_t kMaxRequestsPerProcess = 2;
1872   host_.set_max_num_in_flight_requests_per_process(kMaxRequestsPerProcess);
1873   const size_t kMaxRequests = 3;
1874   host_.set_max_num_in_flight_requests(kMaxRequests);
1875
1876   // Needed to emulate additional processes.
1877   scoped_refptr<ForwardingFilter> second_filter = MakeForwardingFilter();
1878   scoped_refptr<ForwardingFilter> third_filter = MakeForwardingFilter();
1879
1880   // Saturate the number of outstanding requests for our process.
1881   for (size_t i = 0; i < kMaxRequestsPerProcess; ++i) {
1882     MakeTestRequestWithResourceType(filter_.get(), 0, i + 1,
1883                                     net::URLRequestTestJob::test_url_2(),
1884                                     RESOURCE_TYPE_SUB_RESOURCE);
1885   }
1886
1887   // Issue another request for our process -- this should fail immediately.
1888   MakeTestRequestWithResourceType(filter_.get(), 0, kMaxRequestsPerProcess + 1,
1889                                   net::URLRequestTestJob::test_url_2(),
1890                                   RESOURCE_TYPE_SUB_RESOURCE);
1891
1892   // Issue a request for the second process -- this should succeed, because it
1893   // is just process 0 that is saturated.
1894   MakeTestRequestWithResourceType(
1895       second_filter.get(), 0, kMaxRequestsPerProcess + 2,
1896       net::URLRequestTestJob::test_url_2(), RESOURCE_TYPE_SUB_RESOURCE);
1897
1898   // Issue a request for the third process -- this should fail, because the
1899   // global limit has been reached.
1900   MakeTestRequestWithResourceType(
1901       third_filter.get(), 0, kMaxRequestsPerProcess + 3,
1902       net::URLRequestTestJob::test_url_2(), RESOURCE_TYPE_SUB_RESOURCE);
1903
1904   // Flush all the pending requests.
1905   while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1906   base::MessageLoop::current()->RunUntilIdle();
1907
1908   // Sorts out all the messages we saw by request.
1909   ResourceIPCAccumulator::ClassifiedMessages msgs;
1910   accum_.GetClassifiedMessages(&msgs);
1911
1912   // The processes issued the following requests:
1913   // #1 issued kMaxRequestsPerProcess that passed + 1 that failed
1914   // #2 issued 1 request that passed
1915   // #3 issued 1 request that failed
1916   ASSERT_EQ((kMaxRequestsPerProcess + 1) + 1 + 1, msgs.size());
1917
1918   for (size_t i = 0; i < kMaxRequestsPerProcess; ++i)
1919     CheckSuccessfulRequest(msgs[i], net::URLRequestTestJob::test_data_2());
1920
1921   CheckFailedRequest(msgs[kMaxRequestsPerProcess + 0],
1922                      net::URLRequestTestJob::test_data_2(),
1923                      net::ERR_INSUFFICIENT_RESOURCES);
1924   CheckSuccessfulRequest(msgs[kMaxRequestsPerProcess + 1],
1925                          net::URLRequestTestJob::test_data_2());
1926   CheckFailedRequest(msgs[kMaxRequestsPerProcess + 2],
1927                      net::URLRequestTestJob::test_data_2(),
1928                      net::ERR_INSUFFICIENT_RESOURCES);
1929 }
1930
1931 // Tests that we sniff the mime type for a simple request.
1932 TEST_F(ResourceDispatcherHostTest, MimeSniffed) {
1933   std::string raw_headers("HTTP/1.1 200 OK\n\n");
1934   std::string response_data("<html><title>Test One</title></html>");
1935   SetResponse(raw_headers, response_data);
1936
1937   HandleScheme("http");
1938   MakeTestRequest(0, 1, GURL("http:bla"));
1939
1940   // Flush all pending requests.
1941   while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1942
1943   // Sorts out all the messages we saw by request.
1944   ResourceIPCAccumulator::ClassifiedMessages msgs;
1945   accum_.GetClassifiedMessages(&msgs);
1946   ASSERT_EQ(1U, msgs.size());
1947
1948   ResourceResponseHead response_head;
1949   GetResponseHead(msgs[0], &response_head);
1950   ASSERT_EQ("text/html", response_head.mime_type);
1951 }
1952
1953 // Tests that we don't sniff the mime type when the server provides one.
1954 TEST_F(ResourceDispatcherHostTest, MimeNotSniffed) {
1955   std::string raw_headers("HTTP/1.1 200 OK\n"
1956                           "Content-type: image/jpeg\n\n");
1957   std::string response_data("<html><title>Test One</title></html>");
1958   SetResponse(raw_headers, response_data);
1959
1960   HandleScheme("http");
1961   MakeTestRequest(0, 1, GURL("http:bla"));
1962
1963   // Flush all pending requests.
1964   while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1965
1966   // Sorts out all the messages we saw by request.
1967   ResourceIPCAccumulator::ClassifiedMessages msgs;
1968   accum_.GetClassifiedMessages(&msgs);
1969   ASSERT_EQ(1U, msgs.size());
1970
1971   ResourceResponseHead response_head;
1972   GetResponseHead(msgs[0], &response_head);
1973   ASSERT_EQ("image/jpeg", response_head.mime_type);
1974 }
1975
1976 // Tests that we don't sniff the mime type when there is no message body.
1977 TEST_F(ResourceDispatcherHostTest, MimeNotSniffed2) {
1978   SetResponse("HTTP/1.1 304 Not Modified\n\n");
1979
1980   HandleScheme("http");
1981   MakeTestRequest(0, 1, GURL("http:bla"));
1982
1983   // Flush all pending requests.
1984   while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1985
1986   // Sorts out all the messages we saw by request.
1987   ResourceIPCAccumulator::ClassifiedMessages msgs;
1988   accum_.GetClassifiedMessages(&msgs);
1989   ASSERT_EQ(1U, msgs.size());
1990
1991   ResourceResponseHead response_head;
1992   GetResponseHead(msgs[0], &response_head);
1993   ASSERT_EQ("", response_head.mime_type);
1994 }
1995
1996 TEST_F(ResourceDispatcherHostTest, MimeSniff204) {
1997   SetResponse("HTTP/1.1 204 No Content\n\n");
1998
1999   HandleScheme("http");
2000   MakeTestRequest(0, 1, GURL("http:bla"));
2001
2002   // Flush all pending requests.
2003   while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2004
2005   // Sorts out all the messages we saw by request.
2006   ResourceIPCAccumulator::ClassifiedMessages msgs;
2007   accum_.GetClassifiedMessages(&msgs);
2008   ASSERT_EQ(1U, msgs.size());
2009
2010   ResourceResponseHead response_head;
2011   GetResponseHead(msgs[0], &response_head);
2012   ASSERT_EQ("text/plain", response_head.mime_type);
2013 }
2014
2015 TEST_F(ResourceDispatcherHostTest, MimeSniffEmpty) {
2016   SetResponse("HTTP/1.1 200 OK\n\n");
2017
2018   HandleScheme("http");
2019   MakeTestRequest(0, 1, GURL("http:bla"));
2020
2021   // Flush all pending requests.
2022   while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2023
2024   // Sorts out all the messages we saw by request.
2025   ResourceIPCAccumulator::ClassifiedMessages msgs;
2026   accum_.GetClassifiedMessages(&msgs);
2027   ASSERT_EQ(1U, msgs.size());
2028
2029   ResourceResponseHead response_head;
2030   GetResponseHead(msgs[0], &response_head);
2031   ASSERT_EQ("text/plain", response_head.mime_type);
2032 }
2033
2034 // Tests for crbug.com/31266 (Non-2xx + application/octet-stream).
2035 TEST_F(ResourceDispatcherHostTest, ForbiddenDownload) {
2036   std::string raw_headers("HTTP/1.1 403 Forbidden\n"
2037                           "Content-disposition: attachment; filename=blah\n"
2038                           "Content-type: application/octet-stream\n\n");
2039   std::string response_data("<html><title>Test One</title></html>");
2040   SetResponse(raw_headers, response_data);
2041
2042   HandleScheme("http");
2043
2044   // Only MAIN_FRAMEs can trigger a download.
2045   MakeTestRequestWithResourceType(filter_.get(), 0, 1, GURL("http:bla"),
2046                                   RESOURCE_TYPE_MAIN_FRAME);
2047
2048   // Flush all pending requests.
2049   while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2050   base::MessageLoop::current()->RunUntilIdle();
2051
2052   // Sorts out all the messages we saw by request.
2053   ResourceIPCAccumulator::ClassifiedMessages msgs;
2054   accum_.GetClassifiedMessages(&msgs);
2055
2056   // We should have gotten one RequestComplete message.
2057   ASSERT_EQ(1U, msgs.size());
2058   ASSERT_EQ(1U, msgs[0].size());
2059   EXPECT_EQ(ResourceMsg_RequestComplete::ID, msgs[0][0].type());
2060
2061   // The RequestComplete message should have had the error code of
2062   // ERR_INVALID_RESPONSE.
2063   CheckRequestCompleteErrorCode(msgs[0][0], net::ERR_INVALID_RESPONSE);
2064 }
2065
2066 // Test for http://crbug.com/76202 .  We don't want to destroy a
2067 // download request prematurely when processing a cancellation from
2068 // the renderer.
2069 TEST_F(ResourceDispatcherHostTest, IgnoreCancelForDownloads) {
2070   EXPECT_EQ(0, host_.pending_requests());
2071
2072   int render_view_id = 0;
2073   int request_id = 1;
2074
2075   std::string raw_headers("HTTP\n"
2076                           "Content-disposition: attachment; filename=foo\n\n");
2077   std::string response_data("01234567890123456789\x01foobar");
2078
2079   // Get past sniffing metrics in the BufferedResourceHandler.  Note that
2080   // if we don't get past the sniffing metrics, the result will be that
2081   // the BufferedResourceHandler won't have figured out that it's a download,
2082   // won't have constructed a DownloadResourceHandler, and and the request
2083   // will be successfully canceled below, failing the test.
2084   response_data.resize(1025, ' ');
2085
2086   SetResponse(raw_headers, response_data);
2087   job_factory_->SetDelayedCompleteJobGeneration(true);
2088   HandleScheme("http");
2089
2090   MakeTestRequestWithResourceType(filter_.get(), render_view_id, request_id,
2091                                   GURL("http://example.com/blah"),
2092                                   RESOURCE_TYPE_MAIN_FRAME);
2093   // Return some data so that the request is identified as a download
2094   // and the proper resource handlers are created.
2095   EXPECT_TRUE(net::URLRequestTestJob::ProcessOnePendingMessage());
2096
2097   // And now simulate a cancellation coming from the renderer.
2098   ResourceHostMsg_CancelRequest msg(request_id);
2099   host_.OnMessageReceived(msg, filter_.get());
2100
2101   // Since the request had already started processing as a download,
2102   // the cancellation above should have been ignored and the request
2103   // should still be alive.
2104   EXPECT_EQ(1, host_.pending_requests());
2105
2106   while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2107 }
2108
2109 TEST_F(ResourceDispatcherHostTest, CancelRequestsForContext) {
2110   EXPECT_EQ(0, host_.pending_requests());
2111
2112   int render_view_id = 0;
2113   int request_id = 1;
2114
2115   std::string raw_headers("HTTP\n"
2116                           "Content-disposition: attachment; filename=foo\n\n");
2117   std::string response_data("01234567890123456789\x01foobar");
2118   // Get past sniffing metrics.
2119   response_data.resize(1025, ' ');
2120
2121   SetResponse(raw_headers, response_data);
2122   job_factory_->SetDelayedCompleteJobGeneration(true);
2123   HandleScheme("http");
2124
2125   MakeTestRequestWithResourceType(filter_.get(), render_view_id, request_id,
2126                                   GURL("http://example.com/blah"),
2127                                   RESOURCE_TYPE_MAIN_FRAME);
2128   // Return some data so that the request is identified as a download
2129   // and the proper resource handlers are created.
2130   EXPECT_TRUE(net::URLRequestTestJob::ProcessOnePendingMessage());
2131
2132   // And now simulate a cancellation coming from the renderer.
2133   ResourceHostMsg_CancelRequest msg(request_id);
2134   host_.OnMessageReceived(msg, filter_.get());
2135
2136   // Since the request had already started processing as a download,
2137   // the cancellation above should have been ignored and the request
2138   // should still be alive.
2139   EXPECT_EQ(1, host_.pending_requests());
2140
2141   // Cancelling by other methods shouldn't work either.
2142   host_.CancelRequestsForProcess(render_view_id);
2143   EXPECT_EQ(1, host_.pending_requests());
2144
2145   // Cancelling by context should work.
2146   host_.CancelRequestsForContext(filter_->resource_context());
2147   EXPECT_EQ(0, host_.pending_requests());
2148 }
2149
2150 TEST_F(ResourceDispatcherHostTest, CancelRequestsForContextDetached) {
2151   EXPECT_EQ(0, host_.pending_requests());
2152
2153   int render_view_id = 0;
2154   int request_id = 1;
2155
2156   MakeTestRequestWithResourceType(filter_.get(), render_view_id, request_id,
2157                                   net::URLRequestTestJob::test_url_4(),
2158                                   RESOURCE_TYPE_PREFETCH);  // detachable type
2159
2160   // Simulate a cancel coming from the renderer.
2161   RendererCancelRequest(request_id);
2162
2163   // Since the request had already started processing as detachable,
2164   // the cancellation above should have been ignored and the request
2165   // should have been detached.
2166   EXPECT_EQ(1, host_.pending_requests());
2167
2168   // Cancelling by other methods should also leave it detached.
2169   host_.CancelRequestsForProcess(render_view_id);
2170   EXPECT_EQ(1, host_.pending_requests());
2171
2172   // Cancelling by context should work.
2173   host_.CancelRequestsForContext(filter_->resource_context());
2174   EXPECT_EQ(0, host_.pending_requests());
2175 }
2176
2177 // Test the cancelling of requests that are being transferred to a new renderer
2178 // due to a redirection.
2179 TEST_F(ResourceDispatcherHostTest, CancelRequestsForContextTransferred) {
2180   EXPECT_EQ(0, host_.pending_requests());
2181
2182   int render_view_id = 0;
2183   int request_id = 1;
2184
2185   std::string raw_headers("HTTP/1.1 200 OK\n"
2186                           "Content-Type: text/html; charset=utf-8\n\n");
2187   std::string response_data("<html>foobar</html>");
2188
2189   SetResponse(raw_headers, response_data);
2190   HandleScheme("http");
2191
2192   MakeTestRequestWithResourceType(filter_.get(), render_view_id, request_id,
2193                                   GURL("http://example.com/blah"),
2194                                   RESOURCE_TYPE_MAIN_FRAME);
2195
2196
2197   GlobalRequestID global_request_id(filter_->child_id(), request_id);
2198   host_.MarkAsTransferredNavigation(global_request_id);
2199
2200   // And now simulate a cancellation coming from the renderer.
2201   ResourceHostMsg_CancelRequest msg(request_id);
2202   host_.OnMessageReceived(msg, filter_.get());
2203
2204   // Since the request is marked as being transferred,
2205   // the cancellation above should have been ignored and the request
2206   // should still be alive.
2207   EXPECT_EQ(1, host_.pending_requests());
2208
2209   // Cancelling by other methods shouldn't work either.
2210   host_.CancelRequestsForProcess(render_view_id);
2211   EXPECT_EQ(1, host_.pending_requests());
2212
2213   // Cancelling by context should work.
2214   host_.CancelRequestsForContext(filter_->resource_context());
2215   EXPECT_EQ(0, host_.pending_requests());
2216 }
2217
2218 // Test transferred navigations with text/html, which doesn't trigger any
2219 // content sniffing.
2220 TEST_F(ResourceDispatcherHostTest, TransferNavigationHtml) {
2221   // This test expects the cross site request to be leaked, so it can transfer
2222   // the request directly.
2223   CrossSiteResourceHandler::SetLeakRequestsForTesting(true);
2224
2225   EXPECT_EQ(0, host_.pending_requests());
2226
2227   int render_view_id = 0;
2228   int request_id = 1;
2229
2230   // Configure initial request.
2231   SetResponse("HTTP/1.1 302 Found\n"
2232               "Location: http://other.com/blech\n\n");
2233
2234   HandleScheme("http");
2235
2236   // Temporarily replace ContentBrowserClient with one that will trigger the
2237   // transfer navigation code paths.
2238   TransfersAllNavigationsContentBrowserClient new_client;
2239   ContentBrowserClient* old_client = SetBrowserClientForTesting(&new_client);
2240
2241   MakeTestRequestWithResourceType(filter_.get(), render_view_id, request_id,
2242                                   GURL("http://example.com/blah"),
2243                                   RESOURCE_TYPE_MAIN_FRAME);
2244
2245   // Now that we're blocked on the redirect, update the response and unblock by
2246   // telling the AsyncResourceHandler to follow the redirect.
2247   const std::string kResponseBody = "hello world";
2248   SetResponse("HTTP/1.1 200 OK\n"
2249               "Content-Type: text/html\n\n",
2250               kResponseBody);
2251   ResourceHostMsg_FollowRedirect redirect_msg(request_id);
2252   host_.OnMessageReceived(redirect_msg, filter_.get());
2253   base::MessageLoop::current()->RunUntilIdle();
2254
2255   // Flush all the pending requests to get the response through the
2256   // BufferedResourceHandler.
2257   while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2258
2259   // Restore, now that we've set up a transfer.
2260   SetBrowserClientForTesting(old_client);
2261
2262   // This second filter is used to emulate a second process.
2263   scoped_refptr<ForwardingFilter> second_filter = MakeForwardingFilter();
2264
2265   int new_render_view_id = 1;
2266   int new_request_id = 2;
2267
2268   ResourceHostMsg_Request request =
2269       CreateResourceRequest("GET", RESOURCE_TYPE_MAIN_FRAME,
2270                             GURL("http://other.com/blech"));
2271   request.transferred_request_child_id = filter_->child_id();
2272   request.transferred_request_request_id = request_id;
2273
2274   ResourceHostMsg_RequestResource transfer_request_msg(
2275       new_render_view_id, new_request_id, request);
2276   host_.OnMessageReceived(transfer_request_msg, second_filter.get());
2277   base::MessageLoop::current()->RunUntilIdle();
2278
2279   // Check generated messages.
2280   ResourceIPCAccumulator::ClassifiedMessages msgs;
2281   accum_.GetClassifiedMessages(&msgs);
2282
2283   ASSERT_EQ(2U, msgs.size());
2284   EXPECT_EQ(ResourceMsg_ReceivedRedirect::ID, msgs[0][0].type());
2285   CheckSuccessfulRequest(msgs[1], kResponseBody);
2286 }
2287
2288 // Test transferred navigations with text/plain, which causes
2289 // BufferedResourceHandler to buffer the response to sniff the content
2290 // before the transfer occurs.
2291 TEST_F(ResourceDispatcherHostTest, TransferNavigationText) {
2292   // This test expects the cross site request to be leaked, so it can transfer
2293   // the request directly.
2294   CrossSiteResourceHandler::SetLeakRequestsForTesting(true);
2295
2296   EXPECT_EQ(0, host_.pending_requests());
2297
2298   int render_view_id = 0;
2299   int request_id = 1;
2300
2301   // Configure initial request.
2302   SetResponse("HTTP/1.1 302 Found\n"
2303               "Location: http://other.com/blech\n\n");
2304
2305   HandleScheme("http");
2306
2307   // Temporarily replace ContentBrowserClient with one that will trigger the
2308   // transfer navigation code paths.
2309   TransfersAllNavigationsContentBrowserClient new_client;
2310   ContentBrowserClient* old_client = SetBrowserClientForTesting(&new_client);
2311
2312   MakeTestRequestWithResourceType(filter_.get(), render_view_id, request_id,
2313                                   GURL("http://example.com/blah"),
2314                                   RESOURCE_TYPE_MAIN_FRAME);
2315
2316   // Now that we're blocked on the redirect, update the response and unblock by
2317   // telling the AsyncResourceHandler to follow the redirect.  Use a text/plain
2318   // MIME type, which causes BufferedResourceHandler to buffer it before the
2319   // transfer occurs.
2320   const std::string kResponseBody = "hello world";
2321   SetResponse("HTTP/1.1 200 OK\n"
2322               "Content-Type: text/plain\n\n",
2323               kResponseBody);
2324   ResourceHostMsg_FollowRedirect redirect_msg(request_id);
2325   host_.OnMessageReceived(redirect_msg, filter_.get());
2326   base::MessageLoop::current()->RunUntilIdle();
2327
2328   // Flush all the pending requests to get the response through the
2329   // BufferedResourceHandler.
2330   while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2331
2332   // Restore, now that we've set up a transfer.
2333   SetBrowserClientForTesting(old_client);
2334
2335   // This second filter is used to emulate a second process.
2336   scoped_refptr<ForwardingFilter> second_filter = MakeForwardingFilter();
2337
2338   int new_render_view_id = 1;
2339   int new_request_id = 2;
2340
2341   ResourceHostMsg_Request request =
2342       CreateResourceRequest("GET", RESOURCE_TYPE_MAIN_FRAME,
2343                             GURL("http://other.com/blech"));
2344   request.transferred_request_child_id = filter_->child_id();
2345   request.transferred_request_request_id = request_id;
2346
2347   ResourceHostMsg_RequestResource transfer_request_msg(
2348       new_render_view_id, new_request_id, request);
2349   host_.OnMessageReceived(transfer_request_msg, second_filter.get());
2350   base::MessageLoop::current()->RunUntilIdle();
2351
2352   // Check generated messages.
2353   ResourceIPCAccumulator::ClassifiedMessages msgs;
2354   accum_.GetClassifiedMessages(&msgs);
2355
2356   ASSERT_EQ(2U, msgs.size());
2357   EXPECT_EQ(ResourceMsg_ReceivedRedirect::ID, msgs[0][0].type());
2358   CheckSuccessfulRequest(msgs[1], kResponseBody);
2359 }
2360
2361 TEST_F(ResourceDispatcherHostTest, TransferNavigationWithProcessCrash) {
2362   // This test expects the cross site request to be leaked, so it can transfer
2363   // the request directly.
2364   CrossSiteResourceHandler::SetLeakRequestsForTesting(true);
2365
2366   EXPECT_EQ(0, host_.pending_requests());
2367
2368   int render_view_id = 0;
2369   int request_id = 1;
2370   int first_child_id = -1;
2371
2372   // Configure initial request.
2373   SetResponse("HTTP/1.1 302 Found\n"
2374               "Location: http://other.com/blech\n\n");
2375   const std::string kResponseBody = "hello world";
2376
2377   HandleScheme("http");
2378
2379   // Temporarily replace ContentBrowserClient with one that will trigger the
2380   // transfer navigation code paths.
2381   TransfersAllNavigationsContentBrowserClient new_client;
2382   ContentBrowserClient* old_client = SetBrowserClientForTesting(&new_client);
2383
2384   // Create a first filter that can be deleted before the second one starts.
2385   {
2386     scoped_refptr<ForwardingFilter> first_filter = MakeForwardingFilter();
2387     first_child_id = first_filter->child_id();
2388
2389     ResourceHostMsg_Request first_request =
2390         CreateResourceRequest("GET", RESOURCE_TYPE_MAIN_FRAME,
2391                               GURL("http://example.com/blah"));
2392
2393     ResourceHostMsg_RequestResource first_request_msg(
2394         render_view_id, request_id, first_request);
2395     host_.OnMessageReceived(first_request_msg, first_filter.get());
2396     base::MessageLoop::current()->RunUntilIdle();
2397
2398     // Now that we're blocked on the redirect, update the response and unblock
2399     // by telling the AsyncResourceHandler to follow the redirect.
2400     SetResponse("HTTP/1.1 200 OK\n"
2401                 "Content-Type: text/html\n\n",
2402                 kResponseBody);
2403     ResourceHostMsg_FollowRedirect redirect_msg(request_id);
2404     host_.OnMessageReceived(redirect_msg, first_filter.get());
2405     base::MessageLoop::current()->RunUntilIdle();
2406
2407     // Flush all the pending requests to get the response through the
2408     // BufferedResourceHandler.
2409     while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2410   }
2411   // The first filter is now deleted, as if the child process died.
2412
2413   // Restore.
2414   SetBrowserClientForTesting(old_client);
2415
2416   // Make sure we don't hold onto the ResourceMessageFilter after it is deleted.
2417   GlobalRequestID first_global_request_id(first_child_id, request_id);
2418
2419   // This second filter is used to emulate a second process.
2420   scoped_refptr<ForwardingFilter> second_filter = MakeForwardingFilter();
2421
2422   int new_render_view_id = 1;
2423   int new_request_id = 2;
2424
2425   ResourceHostMsg_Request request =
2426       CreateResourceRequest("GET", RESOURCE_TYPE_MAIN_FRAME,
2427                             GURL("http://other.com/blech"));
2428   request.transferred_request_child_id = first_child_id;
2429   request.transferred_request_request_id = request_id;
2430
2431   // For cleanup.
2432   child_ids_.insert(second_filter->child_id());
2433   ResourceHostMsg_RequestResource transfer_request_msg(
2434       new_render_view_id, new_request_id, request);
2435   host_.OnMessageReceived(transfer_request_msg, second_filter.get());
2436   base::MessageLoop::current()->RunUntilIdle();
2437
2438   // Check generated messages.
2439   ResourceIPCAccumulator::ClassifiedMessages msgs;
2440   accum_.GetClassifiedMessages(&msgs);
2441
2442   ASSERT_EQ(2U, msgs.size());
2443   EXPECT_EQ(ResourceMsg_ReceivedRedirect::ID, msgs[0][0].type());
2444   CheckSuccessfulRequest(msgs[1], kResponseBody);
2445 }
2446
2447 TEST_F(ResourceDispatcherHostTest, TransferNavigationWithTwoRedirects) {
2448   // This test expects the cross site request to be leaked, so it can transfer
2449   // the request directly.
2450   CrossSiteResourceHandler::SetLeakRequestsForTesting(true);
2451
2452   EXPECT_EQ(0, host_.pending_requests());
2453
2454   int render_view_id = 0;
2455   int request_id = 1;
2456
2457   // Configure initial request.
2458   SetResponse("HTTP/1.1 302 Found\n"
2459               "Location: http://other.com/blech\n\n");
2460
2461   HandleScheme("http");
2462
2463   // Temporarily replace ContentBrowserClient with one that will trigger the
2464   // transfer navigation code paths.
2465   TransfersAllNavigationsContentBrowserClient new_client;
2466   ContentBrowserClient* old_client = SetBrowserClientForTesting(&new_client);
2467
2468   MakeTestRequestWithResourceType(filter_.get(), render_view_id, request_id,
2469                                   GURL("http://example.com/blah"),
2470                                   RESOURCE_TYPE_MAIN_FRAME);
2471
2472   // Now that we're blocked on the redirect, simulate hitting another redirect.
2473   SetResponse("HTTP/1.1 302 Found\n"
2474               "Location: http://other.com/blerg\n\n");
2475   ResourceHostMsg_FollowRedirect redirect_msg(request_id);
2476   host_.OnMessageReceived(redirect_msg, filter_.get());
2477   base::MessageLoop::current()->RunUntilIdle();
2478
2479   // Now that we're blocked on the second redirect, update the response and
2480   // unblock by telling the AsyncResourceHandler to follow the redirect.
2481   // Again, use text/plain to force BufferedResourceHandler to buffer before
2482   // the transfer.
2483   const std::string kResponseBody = "hello world";
2484   SetResponse("HTTP/1.1 200 OK\n"
2485               "Content-Type: text/plain\n\n",
2486               kResponseBody);
2487   ResourceHostMsg_FollowRedirect redirect_msg2(request_id);
2488   host_.OnMessageReceived(redirect_msg2, filter_.get());
2489   base::MessageLoop::current()->RunUntilIdle();
2490
2491   // Flush all the pending requests to get the response through the
2492   // BufferedResourceHandler.
2493   while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2494
2495   // Restore.
2496   SetBrowserClientForTesting(old_client);
2497
2498   // This second filter is used to emulate a second process.
2499   scoped_refptr<ForwardingFilter> second_filter = MakeForwardingFilter();
2500
2501   int new_render_view_id = 1;
2502   int new_request_id = 2;
2503
2504   ResourceHostMsg_Request request =
2505       CreateResourceRequest("GET", RESOURCE_TYPE_MAIN_FRAME,
2506                             GURL("http://other.com/blech"));
2507   request.transferred_request_child_id = filter_->child_id();
2508   request.transferred_request_request_id = request_id;
2509
2510   // For cleanup.
2511   child_ids_.insert(second_filter->child_id());
2512   ResourceHostMsg_RequestResource transfer_request_msg(
2513       new_render_view_id, new_request_id, request);
2514   host_.OnMessageReceived(transfer_request_msg, second_filter.get());
2515
2516   // Verify that we update the ResourceRequestInfo.
2517   GlobalRequestID global_request_id(second_filter->child_id(), new_request_id);
2518   const ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest(
2519       host_.GetURLRequest(global_request_id));
2520   EXPECT_EQ(second_filter->child_id(), info->GetChildID());
2521   EXPECT_EQ(new_render_view_id, info->GetRouteID());
2522   EXPECT_EQ(new_request_id, info->GetRequestID());
2523   EXPECT_EQ(second_filter, info->filter());
2524
2525   // Let request complete.
2526   base::MessageLoop::current()->RunUntilIdle();
2527
2528   // Check generated messages.
2529   ResourceIPCAccumulator::ClassifiedMessages msgs;
2530   accum_.GetClassifiedMessages(&msgs);
2531
2532   ASSERT_EQ(2U, msgs.size());
2533   EXPECT_EQ(ResourceMsg_ReceivedRedirect::ID, msgs[0][0].type());
2534   CheckSuccessfulRequest(msgs[1], kResponseBody);
2535 }
2536
2537 TEST_F(ResourceDispatcherHostTest, UnknownURLScheme) {
2538   EXPECT_EQ(0, host_.pending_requests());
2539
2540   HandleScheme("http");
2541
2542   MakeTestRequestWithResourceType(filter_.get(), 0, 1, GURL("foo://bar"),
2543                                   RESOURCE_TYPE_MAIN_FRAME);
2544
2545   // Flush all pending requests.
2546   while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2547
2548   // Sort all the messages we saw by request.
2549   ResourceIPCAccumulator::ClassifiedMessages msgs;
2550   accum_.GetClassifiedMessages(&msgs);
2551
2552   // We should have gotten one RequestComplete message.
2553   ASSERT_EQ(1U, msgs[0].size());
2554   EXPECT_EQ(ResourceMsg_RequestComplete::ID, msgs[0][0].type());
2555
2556   // The RequestComplete message should have the error code of
2557   // ERR_UNKNOWN_URL_SCHEME.
2558   CheckRequestCompleteErrorCode(msgs[0][0], net::ERR_UNKNOWN_URL_SCHEME);
2559 }
2560
2561 TEST_F(ResourceDispatcherHostTest, DataReceivedACKs) {
2562   EXPECT_EQ(0, host_.pending_requests());
2563
2564   SendDataReceivedACKs(true);
2565
2566   HandleScheme("big-job");
2567   MakeTestRequest(0, 1, GURL("big-job:0123456789,1000000"));
2568
2569   // Sort all the messages we saw by request.
2570   ResourceIPCAccumulator::ClassifiedMessages msgs;
2571   accum_.GetClassifiedMessages(&msgs);
2572
2573   size_t size = msgs[0].size();
2574
2575   EXPECT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[0][0].type());
2576   EXPECT_EQ(ResourceMsg_SetDataBuffer::ID, msgs[0][1].type());
2577   for (size_t i = 2; i < size - 1; ++i)
2578     EXPECT_EQ(ResourceMsg_DataReceived::ID, msgs[0][i].type());
2579   EXPECT_EQ(ResourceMsg_RequestComplete::ID, msgs[0][size - 1].type());
2580 }
2581
2582 // Request a very large detachable resource and cancel part way. Some of the
2583 // data should have been sent to the renderer, but not all.
2584 TEST_F(ResourceDispatcherHostTest, DataSentBeforeDetach) {
2585   EXPECT_EQ(0, host_.pending_requests());
2586
2587   int render_view_id = 0;
2588   int request_id = 1;
2589
2590   std::string raw_headers("HTTP\n"
2591                           "Content-type: image/jpeg\n\n");
2592   std::string response_data("01234567890123456789\x01foobar");
2593
2594   // Create a response larger than kMaxAllocationSize (currently 32K). Note
2595   // that if this increase beyond 512K we'll need to make the response longer.
2596   const int kAllocSize = 1024*512;
2597   response_data.resize(kAllocSize, ' ');
2598
2599   SetResponse(raw_headers, response_data);
2600   job_factory_->SetDelayedCompleteJobGeneration(true);
2601   HandleScheme("http");
2602
2603   MakeTestRequestWithResourceType(filter_.get(), render_view_id, request_id,
2604                                   GURL("http://example.com/blah"),
2605                                   RESOURCE_TYPE_PREFETCH);
2606
2607   // Get a bit of data before cancelling.
2608   EXPECT_TRUE(net::URLRequestTestJob::ProcessOnePendingMessage());
2609
2610   // Simulate a cancellation coming from the renderer.
2611   ResourceHostMsg_CancelRequest msg(request_id);
2612   host_.OnMessageReceived(msg, filter_.get());
2613
2614   EXPECT_EQ(1, host_.pending_requests());
2615
2616   while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2617
2618   // Sort all the messages we saw by request.
2619   ResourceIPCAccumulator::ClassifiedMessages msgs;
2620   accum_.GetClassifiedMessages(&msgs);
2621
2622   EXPECT_EQ(4U, msgs[0].size());
2623
2624   // Figure out how many bytes were received by the renderer.
2625   int data_offset;
2626   int data_length;
2627   ASSERT_TRUE(
2628       ExtractDataOffsetAndLength(msgs[0][2], &data_offset, &data_length));
2629   EXPECT_LT(0, data_length);
2630   EXPECT_GT(kAllocSize, data_length);
2631
2632   // Verify the data that was received before cancellation. The request should
2633   // have appeared to cancel, however.
2634   CheckSuccessfulRequestWithErrorCode(
2635       msgs[0],
2636       std::string(response_data.begin(), response_data.begin() + data_length),
2637       net::ERR_ABORTED);
2638 }
2639
2640 TEST_F(ResourceDispatcherHostTest, DelayedDataReceivedACKs) {
2641   EXPECT_EQ(0, host_.pending_requests());
2642
2643   HandleScheme("big-job");
2644   MakeTestRequest(0, 1, GURL("big-job:0123456789,1000000"));
2645
2646   // Sort all the messages we saw by request.
2647   ResourceIPCAccumulator::ClassifiedMessages msgs;
2648   accum_.GetClassifiedMessages(&msgs);
2649
2650   // We expect 1x ReceivedResponse, 1x SetDataBuffer, Nx ReceivedData messages.
2651   EXPECT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[0][0].type());
2652   EXPECT_EQ(ResourceMsg_SetDataBuffer::ID, msgs[0][1].type());
2653   for (size_t i = 2; i < msgs[0].size(); ++i)
2654     EXPECT_EQ(ResourceMsg_DataReceived::ID, msgs[0][i].type());
2655
2656   // NOTE: If we fail the above checks then it means that we probably didn't
2657   // load a big enough response to trigger the delay mechanism we are trying to
2658   // test!
2659
2660   msgs[0].erase(msgs[0].begin());
2661   msgs[0].erase(msgs[0].begin());
2662
2663   // ACK all DataReceived messages until we find a RequestComplete message.
2664   bool complete = false;
2665   while (!complete) {
2666     for (size_t i = 0; i < msgs[0].size(); ++i) {
2667       if (msgs[0][i].type() == ResourceMsg_RequestComplete::ID) {
2668         complete = true;
2669         break;
2670       }
2671
2672       EXPECT_EQ(ResourceMsg_DataReceived::ID, msgs[0][i].type());
2673
2674       ResourceHostMsg_DataReceived_ACK msg(1);
2675       host_.OnMessageReceived(msg, filter_.get());
2676     }
2677
2678     base::MessageLoop::current()->RunUntilIdle();
2679
2680     msgs.clear();
2681     accum_.GetClassifiedMessages(&msgs);
2682   }
2683 }
2684
2685 // Flakyness of this test might indicate memory corruption issues with
2686 // for example the ResourceBuffer of AsyncResourceHandler.
2687 TEST_F(ResourceDispatcherHostTest, DataReceivedUnexpectedACKs) {
2688   EXPECT_EQ(0, host_.pending_requests());
2689
2690   HandleScheme("big-job");
2691   MakeTestRequest(0, 1, GURL("big-job:0123456789,1000000"));
2692
2693   // Sort all the messages we saw by request.
2694   ResourceIPCAccumulator::ClassifiedMessages msgs;
2695   accum_.GetClassifiedMessages(&msgs);
2696
2697   // We expect 1x ReceivedResponse, 1x SetDataBuffer, Nx ReceivedData messages.
2698   EXPECT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[0][0].type());
2699   EXPECT_EQ(ResourceMsg_SetDataBuffer::ID, msgs[0][1].type());
2700   for (size_t i = 2; i < msgs[0].size(); ++i)
2701     EXPECT_EQ(ResourceMsg_DataReceived::ID, msgs[0][i].type());
2702
2703   // NOTE: If we fail the above checks then it means that we probably didn't
2704   // load a big enough response to trigger the delay mechanism.
2705
2706   // Send some unexpected ACKs.
2707   for (size_t i = 0; i < 128; ++i) {
2708     ResourceHostMsg_DataReceived_ACK msg(1);
2709     host_.OnMessageReceived(msg, filter_.get());
2710   }
2711
2712   msgs[0].erase(msgs[0].begin());
2713   msgs[0].erase(msgs[0].begin());
2714
2715   // ACK all DataReceived messages until we find a RequestComplete message.
2716   bool complete = false;
2717   while (!complete) {
2718     for (size_t i = 0; i < msgs[0].size(); ++i) {
2719       if (msgs[0][i].type() == ResourceMsg_RequestComplete::ID) {
2720         complete = true;
2721         break;
2722       }
2723
2724       EXPECT_EQ(ResourceMsg_DataReceived::ID, msgs[0][i].type());
2725
2726       ResourceHostMsg_DataReceived_ACK msg(1);
2727       host_.OnMessageReceived(msg, filter_.get());
2728     }
2729
2730     base::MessageLoop::current()->RunUntilIdle();
2731
2732     msgs.clear();
2733     accum_.GetClassifiedMessages(&msgs);
2734   }
2735 }
2736
2737 // Tests the dispatcher host's temporary file management.
2738 TEST_F(ResourceDispatcherHostTest, RegisterDownloadedTempFile) {
2739   const int kRequestID = 1;
2740
2741   // Create a temporary file.
2742   base::FilePath file_path;
2743   ASSERT_TRUE(base::CreateTemporaryFile(&file_path));
2744   scoped_refptr<ShareableFileReference> deletable_file =
2745       ShareableFileReference::GetOrCreate(
2746           file_path,
2747           ShareableFileReference::DELETE_ON_FINAL_RELEASE,
2748           BrowserThread::GetMessageLoopProxyForThread(
2749               BrowserThread::FILE).get());
2750
2751   // Not readable.
2752   EXPECT_FALSE(ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
2753       filter_->child_id(), file_path));
2754
2755   // Register it for a resource request.
2756   host_.RegisterDownloadedTempFile(filter_->child_id(), kRequestID, file_path);
2757
2758   // Should be readable now.
2759   EXPECT_TRUE(ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
2760       filter_->child_id(), file_path));
2761
2762   // The child releases from the request.
2763   ResourceHostMsg_ReleaseDownloadedFile release_msg(kRequestID);
2764   host_.OnMessageReceived(release_msg, filter_);
2765
2766   // Still readable because there is another reference to the file. (The child
2767   // may take additional blob references.)
2768   EXPECT_TRUE(ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
2769       filter_->child_id(), file_path));
2770
2771   // Release extra references and wait for the file to be deleted. (This relies
2772   // on the delete happening on the FILE thread which is mapped to main thread
2773   // in this test.)
2774   deletable_file = NULL;
2775   base::RunLoop().RunUntilIdle();
2776
2777   // The file is no longer readable to the child and has been deleted.
2778   EXPECT_FALSE(ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
2779       filter_->child_id(), file_path));
2780   EXPECT_FALSE(base::PathExists(file_path));
2781 }
2782
2783 // Tests that temporary files held on behalf of child processes are released
2784 // when the child process dies.
2785 TEST_F(ResourceDispatcherHostTest, ReleaseTemporiesOnProcessExit) {
2786   const int kRequestID = 1;
2787
2788   // Create a temporary file.
2789   base::FilePath file_path;
2790   ASSERT_TRUE(base::CreateTemporaryFile(&file_path));
2791   scoped_refptr<ShareableFileReference> deletable_file =
2792       ShareableFileReference::GetOrCreate(
2793           file_path,
2794           ShareableFileReference::DELETE_ON_FINAL_RELEASE,
2795           BrowserThread::GetMessageLoopProxyForThread(
2796               BrowserThread::FILE).get());
2797
2798   // Register it for a resource request.
2799   host_.RegisterDownloadedTempFile(filter_->child_id(), kRequestID, file_path);
2800   deletable_file = NULL;
2801
2802   // Should be readable now.
2803   EXPECT_TRUE(ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
2804       filter_->child_id(), file_path));
2805
2806   // Let the process die.
2807   filter_->OnChannelClosing();
2808   base::RunLoop().RunUntilIdle();
2809
2810   // The file is no longer readable to the child and has been deleted.
2811   EXPECT_FALSE(ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
2812       filter_->child_id(), file_path));
2813   EXPECT_FALSE(base::PathExists(file_path));
2814 }
2815
2816 TEST_F(ResourceDispatcherHostTest, DownloadToFile) {
2817   // Make a request which downloads to file.
2818   ResourceHostMsg_Request request = CreateResourceRequest(
2819       "GET", RESOURCE_TYPE_SUB_RESOURCE, net::URLRequestTestJob::test_url_1());
2820   request.download_to_file = true;
2821   ResourceHostMsg_RequestResource request_msg(0, 1, request);
2822   host_.OnMessageReceived(request_msg, filter_);
2823
2824   // Running the message loop until idle does not work because
2825   // RedirectToFileResourceHandler posts things to base::WorkerPool. Instead,
2826   // wait for the ResourceMsg_RequestComplete to go out. Then run the event loop
2827   // until idle so the loader is gone.
2828   WaitForRequestComplete();
2829   base::RunLoop().RunUntilIdle();
2830   EXPECT_EQ(0, host_.pending_requests());
2831
2832   ResourceIPCAccumulator::ClassifiedMessages msgs;
2833   accum_.GetClassifiedMessages(&msgs);
2834
2835   ASSERT_EQ(1U, msgs.size());
2836   const std::vector<IPC::Message>& messages = msgs[0];
2837
2838   // The request should contain the following messages:
2839   //     ReceivedResponse    (indicates headers received and filename)
2840   //     DataDownloaded*     (bytes downloaded and total length)
2841   //     RequestComplete     (request is done)
2842
2843   // ReceivedResponse
2844   ResourceResponseHead response_head;
2845   GetResponseHead(messages, &response_head);
2846   ASSERT_FALSE(response_head.download_file_path.empty());
2847
2848   // DataDownloaded
2849   size_t total_len = 0;
2850   for (size_t i = 1; i < messages.size() - 1; i++) {
2851     ASSERT_EQ(ResourceMsg_DataDownloaded::ID, messages[i].type());
2852     PickleIterator iter(messages[i]);
2853     int request_id, data_len;
2854     ASSERT_TRUE(IPC::ReadParam(&messages[i], &iter, &request_id));
2855     ASSERT_TRUE(IPC::ReadParam(&messages[i], &iter, &data_len));
2856     total_len += data_len;
2857   }
2858   EXPECT_EQ(net::URLRequestTestJob::test_data_1().size(), total_len);
2859
2860   // RequestComplete
2861   CheckRequestCompleteErrorCode(messages.back(), net::OK);
2862
2863   // Verify that the data ended up in the temporary file.
2864   std::string contents;
2865   ASSERT_TRUE(base::ReadFileToString(response_head.download_file_path,
2866                                      &contents));
2867   EXPECT_EQ(net::URLRequestTestJob::test_data_1(), contents);
2868
2869   // The file should be readable by the child.
2870   EXPECT_TRUE(ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
2871       filter_->child_id(), response_head.download_file_path));
2872
2873   // When the renderer releases the file, it should be deleted. Again,
2874   // RunUntilIdle doesn't work because base::WorkerPool is involved.
2875   ShareableFileReleaseWaiter waiter(response_head.download_file_path);
2876   ResourceHostMsg_ReleaseDownloadedFile release_msg(1);
2877   host_.OnMessageReceived(release_msg, filter_);
2878   waiter.Wait();
2879   // The release callback runs before the delete is scheduled, so pump the
2880   // message loop for the delete itself. (This relies on the delete happening on
2881   // the FILE thread which is mapped to main thread in this test.)
2882   base::RunLoop().RunUntilIdle();
2883
2884   EXPECT_FALSE(base::PathExists(response_head.download_file_path));
2885   EXPECT_FALSE(ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
2886       filter_->child_id(), response_head.download_file_path));
2887 }
2888
2889 net::URLRequestJob* TestURLRequestJobFactory::MaybeCreateJobWithProtocolHandler(
2890       const std::string& scheme,
2891       net::URLRequest* request,
2892       net::NetworkDelegate* network_delegate) const {
2893   url_request_jobs_created_count_++;
2894   if (test_fixture_->response_headers_.empty()) {
2895     if (delay_start_) {
2896       return new URLRequestTestDelayedStartJob(request, network_delegate);
2897     } else if (delay_complete_) {
2898       return new URLRequestTestDelayedCompletionJob(request,
2899                                                     network_delegate);
2900     } else if (network_start_notification_) {
2901       return new URLRequestTestDelayedNetworkJob(request, network_delegate);
2902     } else if (scheme == "big-job") {
2903       return new URLRequestBigJob(request, network_delegate);
2904     } else {
2905       return new net::URLRequestTestJob(request, network_delegate);
2906     }
2907   } else {
2908     if (delay_start_) {
2909       return new URLRequestTestDelayedStartJob(
2910           request, network_delegate,
2911           test_fixture_->response_headers_, test_fixture_->response_data_,
2912           false);
2913     } else if (delay_complete_) {
2914       return new URLRequestTestDelayedCompletionJob(
2915           request, network_delegate,
2916           test_fixture_->response_headers_, test_fixture_->response_data_,
2917           false);
2918     } else {
2919       return new net::URLRequestTestJob(
2920           request, network_delegate,
2921           test_fixture_->response_headers_, test_fixture_->response_data_,
2922           false);
2923     }
2924   }
2925 }
2926
2927 }  // namespace content