resource_dispatcher_host_unittest.cc revision 5f1c94371a64b3196d4be9466099bb892df9b88e
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
58using webkit_blob::ShareableFileReference;
59
60namespace content {
61
62namespace {
63
64// Returns the resource response header structure for this request.
65void 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
78void 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.
93void 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
110static 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
128static 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.
151static 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
156class 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!
183void 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.
208class 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.
259class 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.
282class 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.
309class 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
388URLRequestTestDelayedStartJob*
389URLRequestTestDelayedStartJob::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.
393class 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
420class 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
462class ResourceDispatcherHostTest;
463
464class 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.
523class 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
537class 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
547enum 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.
557class 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
630GenericResourceThrottle* GenericResourceThrottle::active_throttle_ = NULL;
631
632class 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.
690class 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
714class 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
891void 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
898void 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
911void ResourceDispatcherHostTest::CancelRequest(int request_id) {
912  host_.CancelRequest(filter_->child_id(), request_id);
913}
914
915void ResourceDispatcherHostTest::CompleteStartRequest(int request_id) {
916  CompleteStartRequest(filter_.get(), request_id);
917}
918
919void 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
929void 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
943testing::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
957void 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
1006void CheckSuccessfulRequest(const std::vector<IPC::Message>& messages,
1007                            const std::string& reference_data) {
1008  CheckSuccessfulRequestWithErrorCode(messages, reference_data, net::OK);
1009}
1010
1011void 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
1021void 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.
1036TEST_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.
1069TEST_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.
1124TEST_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.
1166TEST_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.
1218TEST_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
1265TEST_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
1289TEST_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.
1331TEST_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
1353TEST_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.
1371TEST_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
1397TEST_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.
1435TEST_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
1459TEST_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
1537TEST_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.
1583TEST_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.
1641TEST_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.
1677TEST_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.
1723TEST_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()".
1764TEST_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.
1792TEST_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.
1869TEST_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.
1932TEST_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.
1954TEST_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.
1977TEST_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
1996TEST_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
2015TEST_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).
2035TEST_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.
2069TEST_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
2109TEST_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
2150TEST_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.
2179TEST_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.
2220TEST_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.
2291TEST_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
2361TEST_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
2447TEST_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
2537TEST_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
2561TEST_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.
2584TEST_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
2640TEST_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.
2687TEST_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.
2738TEST_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.
2785TEST_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
2816TEST_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
2889net::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
2928