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/files/file_path.h"
10#include "base/files/file_util.h"
11#include "base/memory/scoped_vector.h"
12#include "base/memory/shared_memory.h"
13#include "base/message_loop/message_loop.h"
14#include "base/pickle.h"
15#include "base/run_loop.h"
16#include "base/strings/string_number_conversions.h"
17#include "base/strings/string_split.h"
18#include "content/browser/browser_thread_impl.h"
19#include "content/browser/child_process_security_policy_impl.h"
20#include "content/browser/loader/cross_site_resource_handler.h"
21#include "content/browser/loader/detachable_resource_handler.h"
22#include "content/browser/loader/resource_dispatcher_host_impl.h"
23#include "content/browser/loader/resource_loader.h"
24#include "content/browser/loader/resource_message_filter.h"
25#include "content/browser/loader/resource_request_info_impl.h"
26#include "content/common/appcache_interfaces.h"
27#include "content/common/child_process_host_impl.h"
28#include "content/common/resource_messages.h"
29#include "content/common/view_messages.h"
30#include "content/public/browser/global_request_id.h"
31#include "content/public/browser/resource_context.h"
32#include "content/public/browser/resource_dispatcher_host_delegate.h"
33#include "content/public/browser/resource_request_info.h"
34#include "content/public/browser/resource_throttle.h"
35#include "content/public/common/process_type.h"
36#include "content/public/common/resource_response.h"
37#include "content/public/test/test_browser_context.h"
38#include "content/public/test/test_browser_thread_bundle.h"
39#include "content/test/test_content_browser_client.h"
40#include "net/base/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 "storage/common/blob/shareable_file_reference.h"
53#include "testing/gtest/include/gtest/gtest.h"
54
55// TODO(eroman): Write unit tests for SafeBrowsing that exercise
56//               SafeBrowsingResourceHandler.
57
58using storage::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 = ui::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      ScopedVector<ResourceThrottle>* throttles) OVERRIDE {
666    if (user_data_) {
667      const void* key = user_data_.get();
668      request->SetUserData(key, user_data_.release());
669    }
670
671    if (flags_ != NONE) {
672      throttles->push_back(new GenericResourceThrottle(
673          flags_, error_code_for_cancellation_));
674      if (create_two_throttles_)
675        throttles->push_back(new GenericResourceThrottle(
676            flags_, error_code_for_cancellation_));
677    }
678  }
679
680 private:
681  bool create_two_throttles_;
682  int flags_;
683  int error_code_for_cancellation_;
684  scoped_ptr<base::SupportsUserData::Data> user_data_;
685};
686
687// Waits for a ShareableFileReference to be released.
688class ShareableFileReleaseWaiter {
689 public:
690  ShareableFileReleaseWaiter(const base::FilePath& path) {
691    scoped_refptr<ShareableFileReference> file =
692        ShareableFileReference::Get(path);
693    file->AddFinalReleaseCallback(
694        base::Bind(&ShareableFileReleaseWaiter::Released,
695                   base::Unretained(this)));
696  }
697
698  void Wait() {
699    loop_.Run();
700  }
701
702 private:
703  void Released(const base::FilePath& path) {
704    loop_.Quit();
705  }
706
707  base::RunLoop loop_;
708
709  DISALLOW_COPY_AND_ASSIGN(ShareableFileReleaseWaiter);
710};
711
712class ResourceDispatcherHostTest : public testing::Test,
713                                   public IPC::Sender {
714 public:
715  ResourceDispatcherHostTest()
716      : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP),
717        old_factory_(NULL),
718        send_data_received_acks_(false) {
719    browser_context_.reset(new TestBrowserContext());
720    BrowserContext::EnsureResourceContextInitialized(browser_context_.get());
721    base::RunLoop().RunUntilIdle();
722    filter_ = MakeForwardingFilter();
723    // TODO(cbentzel): Better way to get URLRequestContext?
724    net::URLRequestContext* request_context =
725        browser_context_->GetResourceContext()->GetRequestContext();
726    job_factory_.reset(new TestURLRequestJobFactory(this));
727    request_context->set_job_factory(job_factory_.get());
728    request_context->set_network_delegate(&network_delegate_);
729  }
730
731  // IPC::Sender implementation
732  virtual bool Send(IPC::Message* msg) OVERRIDE {
733    accum_.AddMessage(*msg);
734
735    if (send_data_received_acks_ &&
736        msg->type() == ResourceMsg_DataReceived::ID) {
737      GenerateDataReceivedACK(*msg);
738    }
739
740    if (wait_for_request_complete_loop_ &&
741        msg->type() == ResourceMsg_RequestComplete::ID) {
742      wait_for_request_complete_loop_->Quit();
743    }
744
745    // Do not release handles in it yet; the accumulator owns them now.
746    delete msg;
747    return true;
748  }
749
750 protected:
751  friend class TestURLRequestJobFactory;
752
753  // testing::Test
754  virtual void SetUp() OVERRIDE {
755    ChildProcessSecurityPolicyImpl::GetInstance()->Add(0);
756    HandleScheme("test");
757  }
758
759  virtual void TearDown() {
760    EXPECT_TRUE(URLRequestTestDelayedStartJob::DelayedStartQueueEmpty());
761    URLRequestTestDelayedStartJob::ClearQueue();
762
763    for (std::set<int>::iterator it = child_ids_.begin();
764         it != child_ids_.end(); ++it) {
765      host_.CancelRequestsForProcess(*it);
766    }
767
768    host_.Shutdown();
769
770    ChildProcessSecurityPolicyImpl::GetInstance()->Remove(0);
771
772    // Flush the message loop to make application verifiers happy.
773    if (ResourceDispatcherHostImpl::Get())
774      ResourceDispatcherHostImpl::Get()->CancelRequestsForContext(
775          browser_context_->GetResourceContext());
776
777    browser_context_.reset();
778    base::RunLoop().RunUntilIdle();
779  }
780
781  // Creates a new ForwardingFilter and registers it with |child_ids_| so as not
782  // to leak per-child state on test shutdown.
783  ForwardingFilter* MakeForwardingFilter() {
784    ForwardingFilter* filter =
785        new ForwardingFilter(this, browser_context_->GetResourceContext());
786    child_ids_.insert(filter->child_id());
787    return filter;
788  }
789
790  // Creates a request using the current test object as the filter and
791  // SubResource as the resource type.
792  void MakeTestRequest(int render_view_id,
793                       int request_id,
794                       const GURL& url);
795
796  // Generates a request using the given filter and resource type.
797  void MakeTestRequestWithResourceType(ResourceMessageFilter* filter,
798                                       int render_view_id,
799                                       int request_id,
800                                       const GURL& url,
801                                       ResourceType type);
802
803  void CancelRequest(int request_id);
804  void RendererCancelRequest(int request_id) {
805    ResourceMessageFilter* old_filter = SetFilter(filter_.get());
806    host_.OnCancelRequest(request_id);
807    SetFilter(old_filter);
808  }
809
810  void CompleteStartRequest(int request_id);
811  void CompleteStartRequest(ResourceMessageFilter* filter, int request_id);
812
813  net::TestNetworkDelegate* network_delegate() { return &network_delegate_; }
814
815  void EnsureSchemeIsAllowed(const std::string& scheme) {
816    ChildProcessSecurityPolicyImpl* policy =
817        ChildProcessSecurityPolicyImpl::GetInstance();
818    if (!policy->IsWebSafeScheme(scheme))
819      policy->RegisterWebSafeScheme(scheme);
820  }
821
822  // Sets a particular response for any request from now on. To switch back to
823  // the default bahavior, pass an empty |headers|. |headers| should be raw-
824  // formatted (NULLs instead of EOLs).
825  void SetResponse(const std::string& headers, const std::string& data) {
826    response_headers_ = net::HttpUtil::AssembleRawHeaders(headers.data(),
827                                                          headers.size());
828    response_data_ = data;
829  }
830  void SetResponse(const std::string& headers) {
831    SetResponse(headers, std::string());
832  }
833
834  void SendDataReceivedACKs(bool send_acks) {
835    send_data_received_acks_ = send_acks;
836  }
837
838  // Intercepts requests for the given protocol.
839  void HandleScheme(const std::string& scheme) {
840    job_factory_->HandleScheme(scheme);
841    EnsureSchemeIsAllowed(scheme);
842  }
843
844  void GenerateDataReceivedACK(const IPC::Message& msg) {
845    EXPECT_EQ(ResourceMsg_DataReceived::ID, msg.type());
846
847    int request_id = -1;
848    bool result = PickleIterator(msg).ReadInt(&request_id);
849    DCHECK(result);
850    scoped_ptr<IPC::Message> ack(
851        new ResourceHostMsg_DataReceived_ACK(request_id));
852
853    base::MessageLoop::current()->PostTask(
854        FROM_HERE,
855        base::Bind(&GenerateIPCMessage, filter_, base::Passed(&ack)));
856  }
857
858  // Setting filters for testing renderer messages.
859  // Returns the previous filter.
860  ResourceMessageFilter* SetFilter(ResourceMessageFilter* new_filter) {
861    ResourceMessageFilter* old_filter = host_.filter_;
862    host_.filter_ = new_filter;
863    return old_filter;
864  }
865
866  void WaitForRequestComplete() {
867    DCHECK(!wait_for_request_complete_loop_);
868    wait_for_request_complete_loop_.reset(new base::RunLoop);
869    wait_for_request_complete_loop_->Run();
870    wait_for_request_complete_loop_.reset();
871  }
872
873  content::TestBrowserThreadBundle thread_bundle_;
874  scoped_ptr<TestBrowserContext> browser_context_;
875  scoped_ptr<TestURLRequestJobFactory> job_factory_;
876  scoped_refptr<ForwardingFilter> filter_;
877  net::TestNetworkDelegate network_delegate_;
878  ResourceDispatcherHostImpl host_;
879  ResourceIPCAccumulator accum_;
880  std::string response_headers_;
881  std::string response_data_;
882  std::string scheme_;
883  net::URLRequest::ProtocolFactory* old_factory_;
884  bool send_data_received_acks_;
885  std::set<int> child_ids_;
886  scoped_ptr<base::RunLoop> wait_for_request_complete_loop_;
887};
888
889void ResourceDispatcherHostTest::MakeTestRequest(int render_view_id,
890                                                 int request_id,
891                                                 const GURL& url) {
892  MakeTestRequestWithResourceType(filter_.get(), render_view_id, request_id,
893                                  url, RESOURCE_TYPE_SUB_RESOURCE);
894}
895
896void ResourceDispatcherHostTest::MakeTestRequestWithResourceType(
897    ResourceMessageFilter* filter,
898    int render_view_id,
899    int request_id,
900    const GURL& url,
901    ResourceType type) {
902  ResourceHostMsg_Request request =
903      CreateResourceRequest("GET", type, url);
904  ResourceHostMsg_RequestResource msg(render_view_id, request_id, request);
905  host_.OnMessageReceived(msg, filter);
906  KickOffRequest();
907}
908
909void ResourceDispatcherHostTest::CancelRequest(int request_id) {
910  host_.CancelRequest(filter_->child_id(), request_id);
911}
912
913void ResourceDispatcherHostTest::CompleteStartRequest(int request_id) {
914  CompleteStartRequest(filter_.get(), request_id);
915}
916
917void ResourceDispatcherHostTest::CompleteStartRequest(
918    ResourceMessageFilter* filter,
919    int request_id) {
920  GlobalRequestID gid(filter->child_id(), request_id);
921  net::URLRequest* req = host_.GetURLRequest(gid);
922  EXPECT_TRUE(req);
923  if (req)
924    URLRequestTestDelayedStartJob::CompleteStart(req);
925}
926
927void CheckRequestCompleteErrorCode(const IPC::Message& message,
928                                   int expected_error_code) {
929  // Verify the expected error code was received.
930  int request_id;
931  int error_code;
932
933  ASSERT_EQ(ResourceMsg_RequestComplete::ID, message.type());
934
935  PickleIterator iter(message);
936  ASSERT_TRUE(IPC::ReadParam(&message, &iter, &request_id));
937  ASSERT_TRUE(IPC::ReadParam(&message, &iter, &error_code));
938  ASSERT_EQ(expected_error_code, error_code);
939}
940
941testing::AssertionResult ExtractDataOffsetAndLength(const IPC::Message& message,
942                                                    int* data_offset,
943                                                    int* data_length) {
944  PickleIterator iter(message);
945  int request_id;
946  if (!IPC::ReadParam(&message, &iter, &request_id))
947    return testing::AssertionFailure() << "Could not read request_id";
948  if (!IPC::ReadParam(&message, &iter, data_offset))
949    return testing::AssertionFailure() << "Could not read data_offset";
950  if (!IPC::ReadParam(&message, &iter, data_length))
951    return testing::AssertionFailure() << "Could not read data_length";
952  return testing::AssertionSuccess();
953}
954
955void CheckSuccessfulRequestWithErrorCode(
956    const std::vector<IPC::Message>& messages,
957    const std::string& reference_data,
958    int expected_error) {
959  // A successful request will have received 4 messages:
960  //     ReceivedResponse    (indicates headers received)
961  //     SetDataBuffer       (contains shared memory handle)
962  //     DataReceived        (data offset and length into shared memory)
963  //     RequestComplete     (request is done)
964  //
965  // This function verifies that we received 4 messages and that they are
966  // appropriate. It allows for an error code other than net::OK if the request
967  // should successfully receive data and then abort, e.g., on cancel.
968  ASSERT_EQ(4U, messages.size());
969
970  // The first messages should be received response
971  ASSERT_EQ(ResourceMsg_ReceivedResponse::ID, messages[0].type());
972
973  ASSERT_EQ(ResourceMsg_SetDataBuffer::ID, messages[1].type());
974
975  PickleIterator iter(messages[1]);
976  int request_id;
977  ASSERT_TRUE(IPC::ReadParam(&messages[1], &iter, &request_id));
978  base::SharedMemoryHandle shm_handle;
979  ASSERT_TRUE(IPC::ReadParam(&messages[1], &iter, &shm_handle));
980  int shm_size;
981  ASSERT_TRUE(IPC::ReadParam(&messages[1], &iter, &shm_size));
982
983  // Followed by the data, currently we only do the data in one chunk, but
984  // should probably test multiple chunks later
985  ASSERT_EQ(ResourceMsg_DataReceived::ID, messages[2].type());
986
987  int data_offset;
988  int data_length;
989  ASSERT_TRUE(
990      ExtractDataOffsetAndLength(messages[2], &data_offset, &data_length));
991
992  ASSERT_EQ(reference_data.size(), static_cast<size_t>(data_length));
993  ASSERT_GE(shm_size, data_length);
994
995  base::SharedMemory shared_mem(shm_handle, true);  // read only
996  shared_mem.Map(data_length);
997  const char* data = static_cast<char*>(shared_mem.memory()) + data_offset;
998  ASSERT_EQ(0, memcmp(reference_data.c_str(), data, data_length));
999
1000  // The last message should be all data received.
1001  CheckRequestCompleteErrorCode(messages[3], expected_error);
1002}
1003
1004void CheckSuccessfulRequest(const std::vector<IPC::Message>& messages,
1005                            const std::string& reference_data) {
1006  CheckSuccessfulRequestWithErrorCode(messages, reference_data, net::OK);
1007}
1008
1009void CheckSuccessfulRedirect(const std::vector<IPC::Message>& messages,
1010                             const std::string& reference_data) {
1011  ASSERT_EQ(5U, messages.size());
1012  ASSERT_EQ(ResourceMsg_ReceivedRedirect::ID, messages[0].type());
1013
1014  const std::vector<IPC::Message> second_req_msgs =
1015      std::vector<IPC::Message>(messages.begin() + 1, messages.end());
1016  CheckSuccessfulRequest(second_req_msgs, reference_data);
1017}
1018
1019void CheckFailedRequest(const std::vector<IPC::Message>& messages,
1020                        const std::string& reference_data,
1021                        int expected_error) {
1022  ASSERT_LT(0U, messages.size());
1023  ASSERT_GE(2U, messages.size());
1024  size_t failure_index = messages.size() - 1;
1025
1026  if (messages.size() == 2) {
1027    EXPECT_EQ(ResourceMsg_ReceivedResponse::ID, messages[0].type());
1028  }
1029
1030  CheckRequestCompleteErrorCode(messages[failure_index], expected_error);
1031}
1032
1033// Tests whether many messages get dispatched properly.
1034TEST_F(ResourceDispatcherHostTest, TestMany) {
1035  MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
1036  MakeTestRequest(0, 2, net::URLRequestTestJob::test_url_2());
1037  MakeTestRequest(0, 3, net::URLRequestTestJob::test_url_3());
1038  MakeTestRequestWithResourceType(filter_.get(), 0, 4,
1039                                  net::URLRequestTestJob::test_url_4(),
1040                                  RESOURCE_TYPE_PREFETCH);  // detachable type
1041  MakeTestRequest(0, 5, net::URLRequestTestJob::test_url_redirect_to_url_2());
1042
1043  // Finish the redirection
1044  ResourceHostMsg_FollowRedirect redirect_msg(5);
1045  host_.OnMessageReceived(redirect_msg, filter_.get());
1046  base::MessageLoop::current()->RunUntilIdle();
1047
1048  // flush all the pending requests
1049  while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1050
1051  // sorts out all the messages we saw by request
1052  ResourceIPCAccumulator::ClassifiedMessages msgs;
1053  accum_.GetClassifiedMessages(&msgs);
1054
1055  // there are five requests, so we should have gotten them classified as such
1056  ASSERT_EQ(5U, msgs.size());
1057
1058  CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_1());
1059  CheckSuccessfulRequest(msgs[1], net::URLRequestTestJob::test_data_2());
1060  CheckSuccessfulRequest(msgs[2], net::URLRequestTestJob::test_data_3());
1061  CheckSuccessfulRequest(msgs[3], net::URLRequestTestJob::test_data_4());
1062  CheckSuccessfulRedirect(msgs[4], net::URLRequestTestJob::test_data_2());
1063}
1064
1065// Tests whether messages get canceled properly. We issue four requests,
1066// cancel two of them, and make sure that each sent the proper notifications.
1067TEST_F(ResourceDispatcherHostTest, Cancel) {
1068  MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
1069  MakeTestRequest(0, 2, net::URLRequestTestJob::test_url_2());
1070  MakeTestRequest(0, 3, net::URLRequestTestJob::test_url_3());
1071
1072  MakeTestRequestWithResourceType(filter_.get(), 0, 4,
1073                                  net::URLRequestTestJob::test_url_4(),
1074                                  RESOURCE_TYPE_PREFETCH);  // detachable type
1075
1076  CancelRequest(2);
1077
1078  // Cancel request must come from the renderer for a detachable resource to
1079  // delay.
1080  RendererCancelRequest(4);
1081
1082  // The handler should have been detached now.
1083  GlobalRequestID global_request_id(filter_->child_id(), 4);
1084  ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest(
1085      host_.GetURLRequest(global_request_id));
1086  ASSERT_TRUE(info->detachable_handler()->is_detached());
1087
1088  // flush all the pending requests
1089  while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1090  base::MessageLoop::current()->RunUntilIdle();
1091
1092  // Everything should be out now.
1093  EXPECT_EQ(0, host_.pending_requests());
1094
1095  ResourceIPCAccumulator::ClassifiedMessages msgs;
1096  accum_.GetClassifiedMessages(&msgs);
1097
1098  // there are four requests, so we should have gotten them classified as such
1099  ASSERT_EQ(4U, msgs.size());
1100
1101  CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_1());
1102  CheckSuccessfulRequest(msgs[2], net::URLRequestTestJob::test_data_3());
1103
1104  // Check that request 2 and 4 got canceled, as far as the renderer is
1105  // concerned.  Request 2 will have been deleted.
1106  ASSERT_EQ(1U, msgs[1].size());
1107  ASSERT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[1][0].type());
1108
1109  ASSERT_EQ(2U, msgs[3].size());
1110  ASSERT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[3][0].type());
1111  CheckRequestCompleteErrorCode(msgs[3][1], net::ERR_ABORTED);
1112
1113  // However, request 4 should have actually gone to completion. (Only request 2
1114  // was canceled.)
1115  EXPECT_EQ(4, network_delegate()->completed_requests());
1116  EXPECT_EQ(1, network_delegate()->canceled_requests());
1117  EXPECT_EQ(0, network_delegate()->error_count());
1118}
1119
1120// Shows that detachable requests will timeout if the request takes too long to
1121// complete.
1122TEST_F(ResourceDispatcherHostTest, DetachedResourceTimesOut) {
1123  MakeTestRequestWithResourceType(filter_.get(), 0, 1,
1124                                  net::URLRequestTestJob::test_url_2(),
1125                                  RESOURCE_TYPE_PREFETCH);  // detachable type
1126  GlobalRequestID global_request_id(filter_->child_id(), 1);
1127  ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest(
1128      host_.GetURLRequest(global_request_id));
1129  ASSERT_TRUE(info->detachable_handler());
1130  info->detachable_handler()->set_cancel_delay(
1131      base::TimeDelta::FromMilliseconds(200));
1132  base::MessageLoop::current()->RunUntilIdle();
1133
1134  RendererCancelRequest(1);
1135
1136  // From the renderer's perspective, the request was cancelled.
1137  ResourceIPCAccumulator::ClassifiedMessages msgs;
1138  accum_.GetClassifiedMessages(&msgs);
1139  ASSERT_EQ(1U, msgs.size());
1140  ASSERT_EQ(2U, msgs[0].size());
1141  ASSERT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[0][0].type());
1142  CheckRequestCompleteErrorCode(msgs[0][1], net::ERR_ABORTED);
1143
1144  // But it continues detached.
1145  EXPECT_EQ(1, host_.pending_requests());
1146  EXPECT_TRUE(info->detachable_handler()->is_detached());
1147
1148  // Wait until after the delay timer times out before we start processing any
1149  // messages.
1150  base::OneShotTimer<base::MessageLoop> timer;
1151  timer.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(210),
1152              base::MessageLoop::current(), &base::MessageLoop::QuitWhenIdle);
1153  base::MessageLoop::current()->Run();
1154
1155  // The prefetch should be cancelled by now.
1156  EXPECT_EQ(0, host_.pending_requests());
1157  EXPECT_EQ(1, network_delegate()->completed_requests());
1158  EXPECT_EQ(1, network_delegate()->canceled_requests());
1159  EXPECT_EQ(0, network_delegate()->error_count());
1160}
1161
1162// If the filter has disappeared then detachable resources should continue to
1163// load.
1164TEST_F(ResourceDispatcherHostTest, DeletedFilterDetached) {
1165  // test_url_1's data is available synchronously, so use 2 and 3.
1166  ResourceHostMsg_Request request_prefetch = CreateResourceRequest(
1167      "GET", RESOURCE_TYPE_PREFETCH, net::URLRequestTestJob::test_url_2());
1168  ResourceHostMsg_Request request_ping = CreateResourceRequest(
1169      "GET", RESOURCE_TYPE_PING, net::URLRequestTestJob::test_url_3());
1170
1171  ResourceHostMsg_RequestResource msg_prefetch(0, 1, request_prefetch);
1172  host_.OnMessageReceived(msg_prefetch, filter_.get());
1173  ResourceHostMsg_RequestResource msg_ping(0, 2, request_ping);
1174  host_.OnMessageReceived(msg_ping, filter_.get());
1175
1176  // Remove the filter before processing the requests by simulating channel
1177  // closure.
1178  ResourceRequestInfoImpl* info_prefetch = ResourceRequestInfoImpl::ForRequest(
1179      host_.GetURLRequest(GlobalRequestID(filter_->child_id(), 1)));
1180  ResourceRequestInfoImpl* info_ping = ResourceRequestInfoImpl::ForRequest(
1181      host_.GetURLRequest(GlobalRequestID(filter_->child_id(), 2)));
1182  DCHECK_EQ(filter_.get(), info_prefetch->filter());
1183  DCHECK_EQ(filter_.get(), info_ping->filter());
1184  filter_->OnChannelClosing();
1185  info_prefetch->filter_.reset();
1186  info_ping->filter_.reset();
1187
1188  // From the renderer's perspective, the requests were cancelled.
1189  ResourceIPCAccumulator::ClassifiedMessages msgs;
1190  accum_.GetClassifiedMessages(&msgs);
1191  ASSERT_EQ(2U, msgs.size());
1192  CheckRequestCompleteErrorCode(msgs[0][0], net::ERR_ABORTED);
1193  CheckRequestCompleteErrorCode(msgs[1][0], net::ERR_ABORTED);
1194
1195  // But it continues detached.
1196  EXPECT_EQ(2, host_.pending_requests());
1197  EXPECT_TRUE(info_prefetch->detachable_handler()->is_detached());
1198  EXPECT_TRUE(info_ping->detachable_handler()->is_detached());
1199
1200  KickOffRequest();
1201
1202  // Make sure the requests weren't canceled early.
1203  EXPECT_EQ(2, host_.pending_requests());
1204
1205  while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1206  base::MessageLoop::current()->RunUntilIdle();
1207
1208  EXPECT_EQ(0, host_.pending_requests());
1209  EXPECT_EQ(2, network_delegate()->completed_requests());
1210  EXPECT_EQ(0, network_delegate()->canceled_requests());
1211  EXPECT_EQ(0, network_delegate()->error_count());
1212}
1213
1214// If the filter has disappeared (original process dies) then detachable
1215// resources should continue to load, even when redirected.
1216TEST_F(ResourceDispatcherHostTest, DeletedFilterDetachedRedirect) {
1217  ResourceHostMsg_Request request = CreateResourceRequest(
1218      "GET", RESOURCE_TYPE_PREFETCH,
1219      net::URLRequestTestJob::test_url_redirect_to_url_2());
1220
1221  ResourceHostMsg_RequestResource msg(0, 1, request);
1222  host_.OnMessageReceived(msg, filter_.get());
1223
1224  // Remove the filter before processing the request by simulating channel
1225  // closure.
1226  GlobalRequestID global_request_id(filter_->child_id(), 1);
1227  ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest(
1228      host_.GetURLRequest(global_request_id));
1229  info->filter_->OnChannelClosing();
1230  info->filter_.reset();
1231
1232  // From the renderer's perspective, the request was cancelled.
1233  ResourceIPCAccumulator::ClassifiedMessages msgs;
1234  accum_.GetClassifiedMessages(&msgs);
1235  ASSERT_EQ(1U, msgs.size());
1236  CheckRequestCompleteErrorCode(msgs[0][0], net::ERR_ABORTED);
1237
1238  // But it continues detached.
1239  EXPECT_EQ(1, host_.pending_requests());
1240  EXPECT_TRUE(info->detachable_handler()->is_detached());
1241
1242  // Verify no redirects before resetting the filter.
1243  net::URLRequest* url_request = host_.GetURLRequest(global_request_id);
1244  EXPECT_EQ(1u, url_request->url_chain().size());
1245  KickOffRequest();
1246
1247  // Verify that a redirect was followed.
1248  EXPECT_EQ(2u, url_request->url_chain().size());
1249
1250  // Make sure the request wasn't canceled early.
1251  EXPECT_EQ(1, host_.pending_requests());
1252
1253  // Finish up the request.
1254  while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1255  base::MessageLoop::current()->RunUntilIdle();
1256
1257  EXPECT_EQ(0, host_.pending_requests());
1258  EXPECT_EQ(1, network_delegate()->completed_requests());
1259  EXPECT_EQ(0, network_delegate()->canceled_requests());
1260  EXPECT_EQ(0, network_delegate()->error_count());
1261}
1262
1263TEST_F(ResourceDispatcherHostTest, CancelWhileStartIsDeferred) {
1264  bool was_deleted = false;
1265
1266  // Arrange to have requests deferred before starting.
1267  TestResourceDispatcherHostDelegate delegate;
1268  delegate.set_flags(DEFER_STARTING_REQUEST);
1269  delegate.set_url_request_user_data(new TestUserData(&was_deleted));
1270  host_.SetDelegate(&delegate);
1271
1272  MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
1273  // We cancel from the renderer because all non-renderer cancels delete
1274  // the request synchronously.
1275  RendererCancelRequest(1);
1276
1277  // Our TestResourceThrottle should not have been deleted yet.  This is to
1278  // ensure that destruction of the URLRequest happens asynchronously to
1279  // calling CancelRequest.
1280  EXPECT_FALSE(was_deleted);
1281
1282  base::MessageLoop::current()->RunUntilIdle();
1283
1284  EXPECT_TRUE(was_deleted);
1285}
1286
1287TEST_F(ResourceDispatcherHostTest, DetachWhileStartIsDeferred) {
1288  bool was_deleted = false;
1289
1290  // Arrange to have requests deferred before starting.
1291  TestResourceDispatcherHostDelegate delegate;
1292  delegate.set_flags(DEFER_STARTING_REQUEST);
1293  delegate.set_url_request_user_data(new TestUserData(&was_deleted));
1294  host_.SetDelegate(&delegate);
1295
1296  MakeTestRequestWithResourceType(filter_.get(), 0, 1,
1297                                  net::URLRequestTestJob::test_url_1(),
1298                                  RESOURCE_TYPE_PREFETCH);  // detachable type
1299  // Cancel request must come from the renderer for a detachable resource to
1300  // detach.
1301  RendererCancelRequest(1);
1302
1303  // Even after driving the event loop, the request has not been deleted.
1304  EXPECT_FALSE(was_deleted);
1305
1306  // However, it is still throttled because the defer happened above the
1307  // DetachableResourceHandler.
1308  while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1309  base::MessageLoop::current()->RunUntilIdle();
1310  EXPECT_FALSE(was_deleted);
1311
1312  // Resume the request.
1313  GenericResourceThrottle* throttle =
1314      GenericResourceThrottle::active_throttle();
1315  ASSERT_TRUE(throttle);
1316  throttle->Resume();
1317
1318  // Now, the request completes.
1319  while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1320  base::MessageLoop::current()->RunUntilIdle();
1321  EXPECT_TRUE(was_deleted);
1322  EXPECT_EQ(1, network_delegate()->completed_requests());
1323  EXPECT_EQ(0, network_delegate()->canceled_requests());
1324  EXPECT_EQ(0, network_delegate()->error_count());
1325}
1326
1327// Tests if cancel is called in ResourceThrottle::WillStartRequest, then the
1328// URLRequest will not be started.
1329TEST_F(ResourceDispatcherHostTest, CancelInResourceThrottleWillStartRequest) {
1330  TestResourceDispatcherHostDelegate delegate;
1331  delegate.set_flags(CANCEL_BEFORE_START);
1332  host_.SetDelegate(&delegate);
1333
1334  MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
1335
1336  // flush all the pending requests
1337  while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1338  base::MessageLoop::current()->RunUntilIdle();
1339
1340  ResourceIPCAccumulator::ClassifiedMessages msgs;
1341  accum_.GetClassifiedMessages(&msgs);
1342
1343  // Check that request got canceled.
1344  ASSERT_EQ(1U, msgs[0].size());
1345  CheckRequestCompleteErrorCode(msgs[0][0], net::ERR_ABORTED);
1346
1347  // Make sure URLRequest is never started.
1348  EXPECT_EQ(0, job_factory_->url_request_jobs_created_count());
1349}
1350
1351TEST_F(ResourceDispatcherHostTest, PausedStartError) {
1352  // Arrange to have requests deferred before processing response headers.
1353  TestResourceDispatcherHostDelegate delegate;
1354  delegate.set_flags(DEFER_PROCESSING_RESPONSE);
1355  host_.SetDelegate(&delegate);
1356
1357  job_factory_->SetDelayedStartJobGeneration(true);
1358  MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_error());
1359  CompleteStartRequest(1);
1360
1361  // flush all the pending requests
1362  while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1363  base::MessageLoop::current()->RunUntilIdle();
1364
1365  EXPECT_EQ(0, host_.pending_requests());
1366}
1367
1368// Test the WillStartUsingNetwork throttle.
1369TEST_F(ResourceDispatcherHostTest, ThrottleNetworkStart) {
1370  // Arrange to have requests deferred before processing response headers.
1371  TestResourceDispatcherHostDelegate delegate;
1372  delegate.set_flags(DEFER_NETWORK_START);
1373  host_.SetDelegate(&delegate);
1374
1375  job_factory_->SetNetworkStartNotificationJobGeneration(true);
1376  MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_2());
1377
1378  // Should have deferred for network start.
1379  GenericResourceThrottle* first_throttle =
1380      GenericResourceThrottle::active_throttle();
1381  ASSERT_TRUE(first_throttle);
1382  EXPECT_EQ(0, network_delegate()->completed_requests());
1383  EXPECT_EQ(1, host_.pending_requests());
1384
1385  first_throttle->Resume();
1386
1387  // Flush all the pending requests.
1388  while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1389  base::MessageLoop::current()->RunUntilIdle();
1390
1391  EXPECT_EQ(1, network_delegate()->completed_requests());
1392  EXPECT_EQ(0, host_.pending_requests());
1393}
1394
1395TEST_F(ResourceDispatcherHostTest, ThrottleAndResumeTwice) {
1396  // Arrange to have requests deferred before starting.
1397  TestResourceDispatcherHostDelegate delegate;
1398  delegate.set_flags(DEFER_STARTING_REQUEST);
1399  delegate.set_create_two_throttles(true);
1400  host_.SetDelegate(&delegate);
1401
1402  // Make sure the first throttle blocked the request, and then resume.
1403  MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
1404  GenericResourceThrottle* first_throttle =
1405      GenericResourceThrottle::active_throttle();
1406  ASSERT_TRUE(first_throttle);
1407  first_throttle->Resume();
1408
1409  // Make sure the second throttle blocked the request, and then resume.
1410  ASSERT_TRUE(GenericResourceThrottle::active_throttle());
1411  ASSERT_NE(first_throttle, GenericResourceThrottle::active_throttle());
1412  GenericResourceThrottle::active_throttle()->Resume();
1413
1414  ASSERT_FALSE(GenericResourceThrottle::active_throttle());
1415
1416  // The request is started asynchronously.
1417  base::MessageLoop::current()->RunUntilIdle();
1418
1419  // Flush all the pending requests.
1420  while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1421
1422  EXPECT_EQ(0, host_.pending_requests());
1423
1424  // Make sure the request completed successfully.
1425  ResourceIPCAccumulator::ClassifiedMessages msgs;
1426  accum_.GetClassifiedMessages(&msgs);
1427  ASSERT_EQ(1U, msgs.size());
1428  CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_1());
1429}
1430
1431
1432// Tests that the delegate can cancel a request and provide a error code.
1433TEST_F(ResourceDispatcherHostTest, CancelInDelegate) {
1434  TestResourceDispatcherHostDelegate delegate;
1435  delegate.set_flags(CANCEL_BEFORE_START);
1436  delegate.set_error_code_for_cancellation(net::ERR_ACCESS_DENIED);
1437  host_.SetDelegate(&delegate);
1438
1439  MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
1440  // The request will get cancelled by the throttle.
1441
1442  // flush all the pending requests
1443  while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1444  base::MessageLoop::current()->RunUntilIdle();
1445
1446  ResourceIPCAccumulator::ClassifiedMessages msgs;
1447  accum_.GetClassifiedMessages(&msgs);
1448
1449  // Check the cancellation
1450  ASSERT_EQ(1U, msgs.size());
1451  ASSERT_EQ(1U, msgs[0].size());
1452
1453  CheckRequestCompleteErrorCode(msgs[0][0], net::ERR_ACCESS_DENIED);
1454}
1455
1456// Tests CancelRequestsForProcess
1457TEST_F(ResourceDispatcherHostTest, TestProcessCancel) {
1458  scoped_refptr<TestFilter> test_filter = new TestFilter(
1459      browser_context_->GetResourceContext());
1460  child_ids_.insert(test_filter->child_id());
1461
1462  // request 1 goes to the test delegate
1463  ResourceHostMsg_Request request = CreateResourceRequest(
1464      "GET", RESOURCE_TYPE_SUB_RESOURCE, net::URLRequestTestJob::test_url_1());
1465
1466  MakeTestRequestWithResourceType(test_filter.get(), 0, 1,
1467                                  net::URLRequestTestJob::test_url_1(),
1468                                  RESOURCE_TYPE_SUB_RESOURCE);
1469
1470  // request 2 goes to us
1471  MakeTestRequest(0, 2, net::URLRequestTestJob::test_url_2());
1472
1473  // request 3 goes to the test delegate
1474  MakeTestRequestWithResourceType(test_filter.get(), 0, 3,
1475                                  net::URLRequestTestJob::test_url_3(),
1476                                  RESOURCE_TYPE_SUB_RESOURCE);
1477
1478  // request 4 goes to us
1479  MakeTestRequestWithResourceType(filter_.get(), 0, 4,
1480                                  net::URLRequestTestJob::test_url_4(),
1481                                  RESOURCE_TYPE_PREFETCH);  // detachable type
1482
1483
1484  // Make sure all requests have finished stage one. test_url_1 will have
1485  // finished.
1486  base::MessageLoop::current()->RunUntilIdle();
1487
1488  // TODO(mbelshe):
1489  // Now that the async IO path is in place, the IO always completes on the
1490  // initial call; so the requests have already completed.  This basically
1491  // breaks the whole test.
1492  //EXPECT_EQ(3, host_.pending_requests());
1493
1494  // Process test_url_2 and test_url_3 for one level so one callback is called.
1495  // We'll cancel test_url_4 (detachable) before processing it to verify that it
1496  // delays the cancel.
1497  for (int i = 0; i < 2; i++)
1498    EXPECT_TRUE(net::URLRequestTestJob::ProcessOnePendingMessage());
1499
1500  // Cancel the requests to the test process.
1501  host_.CancelRequestsForProcess(filter_->child_id());
1502  test_filter->set_canceled(true);
1503
1504  // The requests should all be cancelled, except request 4, which is detached.
1505  EXPECT_EQ(1, host_.pending_requests());
1506  GlobalRequestID global_request_id(filter_->child_id(), 4);
1507  ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest(
1508      host_.GetURLRequest(global_request_id));
1509  ASSERT_TRUE(info->detachable_handler()->is_detached());
1510
1511  // Flush all the pending requests.
1512  while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1513
1514  EXPECT_EQ(0, host_.pending_requests());
1515
1516  // The test delegate should not have gotten any messages after being canceled.
1517  ASSERT_EQ(0, test_filter->received_after_canceled());
1518
1519  // There should be two results.
1520  ResourceIPCAccumulator::ClassifiedMessages msgs;
1521  accum_.GetClassifiedMessages(&msgs);
1522  ASSERT_EQ(2U, msgs.size());
1523  CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_2());
1524  // The detachable request was cancelled by the renderer before it
1525  // finished. From the perspective of the renderer, it should have cancelled.
1526  ASSERT_EQ(2U, msgs[1].size());
1527  ASSERT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[1][0].type());
1528  CheckRequestCompleteErrorCode(msgs[1][1], net::ERR_ABORTED);
1529  // But it completed anyway. For the network stack, no requests were canceled.
1530  EXPECT_EQ(4, network_delegate()->completed_requests());
1531  EXPECT_EQ(0, network_delegate()->canceled_requests());
1532  EXPECT_EQ(0, network_delegate()->error_count());
1533}
1534
1535TEST_F(ResourceDispatcherHostTest, TestProcessCancelDetachedTimesOut) {
1536  MakeTestRequestWithResourceType(filter_.get(), 0, 1,
1537                                  net::URLRequestTestJob::test_url_4(),
1538                                  RESOURCE_TYPE_PREFETCH);  // detachable type
1539  GlobalRequestID global_request_id(filter_->child_id(), 1);
1540  ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest(
1541      host_.GetURLRequest(global_request_id));
1542  ASSERT_TRUE(info->detachable_handler());
1543  info->detachable_handler()->set_cancel_delay(
1544      base::TimeDelta::FromMilliseconds(200));
1545  base::MessageLoop::current()->RunUntilIdle();
1546
1547  // Cancel the requests to the test process.
1548  host_.CancelRequestsForProcess(filter_->child_id());
1549  EXPECT_EQ(1, host_.pending_requests());
1550
1551  // Wait until after the delay timer times out before we start processing any
1552  // messages.
1553  base::OneShotTimer<base::MessageLoop> timer;
1554  timer.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(210),
1555              base::MessageLoop::current(), &base::MessageLoop::QuitWhenIdle);
1556  base::MessageLoop::current()->Run();
1557
1558  // The prefetch should be cancelled by now.
1559  EXPECT_EQ(0, host_.pending_requests());
1560
1561  // In case any messages are still to be processed.
1562  while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1563  base::MessageLoop::current()->RunUntilIdle();
1564
1565  ResourceIPCAccumulator::ClassifiedMessages msgs;
1566  accum_.GetClassifiedMessages(&msgs);
1567
1568  ASSERT_EQ(1U, msgs.size());
1569
1570  // The request should have cancelled.
1571  ASSERT_EQ(2U, msgs[0].size());
1572  ASSERT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[0][0].type());
1573  CheckRequestCompleteErrorCode(msgs[0][1], net::ERR_ABORTED);
1574  // And not run to completion.
1575  EXPECT_EQ(1, network_delegate()->completed_requests());
1576  EXPECT_EQ(1, network_delegate()->canceled_requests());
1577  EXPECT_EQ(0, network_delegate()->error_count());
1578}
1579
1580// Tests blocking and resuming requests.
1581TEST_F(ResourceDispatcherHostTest, TestBlockingResumingRequests) {
1582  host_.BlockRequestsForRoute(filter_->child_id(), 1);
1583  host_.BlockRequestsForRoute(filter_->child_id(), 2);
1584  host_.BlockRequestsForRoute(filter_->child_id(), 3);
1585
1586  MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
1587  MakeTestRequest(1, 2, net::URLRequestTestJob::test_url_2());
1588  MakeTestRequest(0, 3, net::URLRequestTestJob::test_url_3());
1589  MakeTestRequest(1, 4, net::URLRequestTestJob::test_url_1());
1590  MakeTestRequest(2, 5, net::URLRequestTestJob::test_url_2());
1591  MakeTestRequest(3, 6, net::URLRequestTestJob::test_url_3());
1592
1593  // Flush all the pending requests
1594  while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1595
1596  // Sort out all the messages we saw by request
1597  ResourceIPCAccumulator::ClassifiedMessages msgs;
1598  accum_.GetClassifiedMessages(&msgs);
1599
1600  // All requests but the 2 for the RVH 0 should have been blocked.
1601  ASSERT_EQ(2U, msgs.size());
1602
1603  CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_1());
1604  CheckSuccessfulRequest(msgs[1], net::URLRequestTestJob::test_data_3());
1605
1606  // Resume requests for RVH 1 and flush pending requests.
1607  host_.ResumeBlockedRequestsForRoute(filter_->child_id(), 1);
1608  KickOffRequest();
1609  while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1610
1611  msgs.clear();
1612  accum_.GetClassifiedMessages(&msgs);
1613  ASSERT_EQ(2U, msgs.size());
1614  CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_2());
1615  CheckSuccessfulRequest(msgs[1], net::URLRequestTestJob::test_data_1());
1616
1617  // Test that new requests are not blocked for RVH 1.
1618  MakeTestRequest(1, 7, net::URLRequestTestJob::test_url_1());
1619  while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1620  msgs.clear();
1621  accum_.GetClassifiedMessages(&msgs);
1622  ASSERT_EQ(1U, msgs.size());
1623  CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_1());
1624
1625  // Now resumes requests for all RVH (2 and 3).
1626  host_.ResumeBlockedRequestsForRoute(filter_->child_id(), 2);
1627  host_.ResumeBlockedRequestsForRoute(filter_->child_id(), 3);
1628  KickOffRequest();
1629  while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1630
1631  msgs.clear();
1632  accum_.GetClassifiedMessages(&msgs);
1633  ASSERT_EQ(2U, msgs.size());
1634  CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_2());
1635  CheckSuccessfulRequest(msgs[1], net::URLRequestTestJob::test_data_3());
1636}
1637
1638// Tests blocking and canceling requests.
1639TEST_F(ResourceDispatcherHostTest, TestBlockingCancelingRequests) {
1640  host_.BlockRequestsForRoute(filter_->child_id(), 1);
1641
1642  MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
1643  MakeTestRequest(1, 2, net::URLRequestTestJob::test_url_2());
1644  MakeTestRequest(0, 3, net::URLRequestTestJob::test_url_3());
1645  MakeTestRequest(1, 4, net::URLRequestTestJob::test_url_1());
1646  // Blocked detachable resources should not delay cancellation.
1647  MakeTestRequestWithResourceType(filter_.get(), 1, 5,
1648                                  net::URLRequestTestJob::test_url_4(),
1649                                  RESOURCE_TYPE_PREFETCH);  // detachable type
1650
1651  // Flush all the pending requests.
1652  while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1653
1654  // Sort out all the messages we saw by request.
1655  ResourceIPCAccumulator::ClassifiedMessages msgs;
1656  accum_.GetClassifiedMessages(&msgs);
1657
1658  // The 2 requests for the RVH 0 should have been processed.
1659  ASSERT_EQ(2U, msgs.size());
1660
1661  CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_1());
1662  CheckSuccessfulRequest(msgs[1], net::URLRequestTestJob::test_data_3());
1663
1664  // Cancel requests for RVH 1.
1665  host_.CancelBlockedRequestsForRoute(filter_->child_id(), 1);
1666  KickOffRequest();
1667  while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1668
1669  msgs.clear();
1670  accum_.GetClassifiedMessages(&msgs);
1671  ASSERT_EQ(0U, msgs.size());
1672}
1673
1674// Tests that blocked requests are canceled if their associated process dies.
1675TEST_F(ResourceDispatcherHostTest, TestBlockedRequestsProcessDies) {
1676  // This second filter is used to emulate a second process.
1677  scoped_refptr<ForwardingFilter> second_filter = MakeForwardingFilter();
1678
1679  host_.BlockRequestsForRoute(second_filter->child_id(), 0);
1680
1681  MakeTestRequestWithResourceType(filter_.get(), 0, 1,
1682                                  net::URLRequestTestJob::test_url_1(),
1683                                  RESOURCE_TYPE_SUB_RESOURCE);
1684  MakeTestRequestWithResourceType(second_filter.get(), 0, 2,
1685                                  net::URLRequestTestJob::test_url_2(),
1686                                  RESOURCE_TYPE_SUB_RESOURCE);
1687  MakeTestRequestWithResourceType(filter_.get(), 0, 3,
1688                                  net::URLRequestTestJob::test_url_3(),
1689                                  RESOURCE_TYPE_SUB_RESOURCE);
1690  MakeTestRequestWithResourceType(second_filter.get(), 0, 4,
1691                                  net::URLRequestTestJob::test_url_1(),
1692                                  RESOURCE_TYPE_SUB_RESOURCE);
1693  MakeTestRequestWithResourceType(second_filter.get(), 0, 5,
1694                                  net::URLRequestTestJob::test_url_4(),
1695                                  RESOURCE_TYPE_PREFETCH);  // detachable type
1696
1697  // Simulate process death.
1698  host_.CancelRequestsForProcess(second_filter->child_id());
1699
1700  // Flush all the pending requests.
1701  while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1702
1703  // Sort out all the messages we saw by request.
1704  ResourceIPCAccumulator::ClassifiedMessages msgs;
1705  accum_.GetClassifiedMessages(&msgs);
1706
1707  // The 2 requests for the RVH 0 should have been processed.  Note that
1708  // blocked detachable requests are canceled without delay.
1709  ASSERT_EQ(2U, msgs.size());
1710
1711  CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_1());
1712  CheckSuccessfulRequest(msgs[1], net::URLRequestTestJob::test_data_3());
1713
1714  EXPECT_TRUE(host_.blocked_loaders_map_.empty());
1715}
1716
1717// Tests that blocked requests don't leak when the ResourceDispatcherHost goes
1718// away.  Note that we rely on Purify for finding the leaks if any.
1719// If this test turns the Purify bot red, check the ResourceDispatcherHost
1720// destructor to make sure the blocked requests are deleted.
1721TEST_F(ResourceDispatcherHostTest, TestBlockedRequestsDontLeak) {
1722  // This second filter is used to emulate a second process.
1723  scoped_refptr<ForwardingFilter> second_filter = MakeForwardingFilter();
1724
1725  host_.BlockRequestsForRoute(filter_->child_id(), 1);
1726  host_.BlockRequestsForRoute(filter_->child_id(), 2);
1727  host_.BlockRequestsForRoute(second_filter->child_id(), 1);
1728
1729  MakeTestRequestWithResourceType(filter_.get(), 0, 1,
1730                                  net::URLRequestTestJob::test_url_1(),
1731                                  RESOURCE_TYPE_SUB_RESOURCE);
1732  MakeTestRequestWithResourceType(filter_.get(), 1, 2,
1733                                  net::URLRequestTestJob::test_url_2(),
1734                                  RESOURCE_TYPE_SUB_RESOURCE);
1735  MakeTestRequestWithResourceType(filter_.get(), 0, 3,
1736                                  net::URLRequestTestJob::test_url_3(),
1737                                  RESOURCE_TYPE_SUB_RESOURCE);
1738  MakeTestRequestWithResourceType(second_filter.get(), 1, 4,
1739                                  net::URLRequestTestJob::test_url_1(),
1740                                  RESOURCE_TYPE_SUB_RESOURCE);
1741  MakeTestRequestWithResourceType(filter_.get(), 2, 5,
1742                                  net::URLRequestTestJob::test_url_2(),
1743                                  RESOURCE_TYPE_SUB_RESOURCE);
1744  MakeTestRequestWithResourceType(filter_.get(), 2, 6,
1745                                  net::URLRequestTestJob::test_url_3(),
1746                                  RESOURCE_TYPE_SUB_RESOURCE);
1747  MakeTestRequestWithResourceType(filter_.get(), 0, 7,
1748                                  net::URLRequestTestJob::test_url_4(),
1749                                  RESOURCE_TYPE_PREFETCH);  // detachable type
1750  MakeTestRequestWithResourceType(second_filter.get(), 1, 8,
1751                                  net::URLRequestTestJob::test_url_4(),
1752                                  RESOURCE_TYPE_PREFETCH);  // detachable type
1753
1754  host_.CancelRequestsForProcess(filter_->child_id());
1755  host_.CancelRequestsForProcess(second_filter->child_id());
1756
1757  // Flush all the pending requests.
1758  while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1759}
1760
1761// Test the private helper method "CalculateApproximateMemoryCost()".
1762TEST_F(ResourceDispatcherHostTest, CalculateApproximateMemoryCost) {
1763  net::URLRequestContext context;
1764  scoped_ptr<net::URLRequest> req(context.CreateRequest(
1765      GURL("http://www.google.com"), net::DEFAULT_PRIORITY, NULL, NULL));
1766  EXPECT_EQ(
1767      4427,
1768      ResourceDispatcherHostImpl::CalculateApproximateMemoryCost(req.get()));
1769
1770  // Add 9 bytes of referrer.
1771  req->SetReferrer("123456789");
1772  EXPECT_EQ(
1773      4436,
1774      ResourceDispatcherHostImpl::CalculateApproximateMemoryCost(req.get()));
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(
1787      4436,
1788      ResourceDispatcherHostImpl::CalculateApproximateMemoryCost(req.get()));
1789}
1790
1791// Test that too much memory for outstanding requests for a particular
1792// render_process_host_id causes requests to fail.
1793TEST_F(ResourceDispatcherHostTest, TooMuchOutstandingRequestsMemory) {
1794  // Expected cost of each request as measured by
1795  // ResourceDispatcherHost::CalculateApproximateMemoryCost().
1796  int kMemoryCostOfTest2Req =
1797      ResourceDispatcherHostImpl::kAvgBytesPerOutstandingRequest +
1798      std::string("GET").size() +
1799      net::URLRequestTestJob::test_url_2().spec().size();
1800
1801  // Tighten the bound on the ResourceDispatcherHost, to speed things up.
1802  int kMaxCostPerProcess = 440000;
1803  host_.set_max_outstanding_requests_cost_per_process(kMaxCostPerProcess);
1804
1805  // Determine how many instance of test_url_2() we can request before
1806  // throttling kicks in.
1807  size_t kMaxRequests = kMaxCostPerProcess / kMemoryCostOfTest2Req;
1808
1809  // This second filter is used to emulate a second process.
1810  scoped_refptr<ForwardingFilter> second_filter = MakeForwardingFilter();
1811
1812  // Saturate the number of outstanding requests for our process.
1813  for (size_t i = 0; i < kMaxRequests; ++i) {
1814    MakeTestRequestWithResourceType(filter_.get(), 0, i + 1,
1815                                    net::URLRequestTestJob::test_url_2(),
1816                                    RESOURCE_TYPE_SUB_RESOURCE);
1817  }
1818
1819  // Issue two more requests for our process -- these should fail immediately.
1820  MakeTestRequestWithResourceType(filter_.get(), 0, kMaxRequests + 1,
1821                                  net::URLRequestTestJob::test_url_2(),
1822                                  RESOURCE_TYPE_SUB_RESOURCE);
1823  MakeTestRequestWithResourceType(filter_.get(), 0, kMaxRequests + 2,
1824                                  net::URLRequestTestJob::test_url_2(),
1825                                  RESOURCE_TYPE_SUB_RESOURCE);
1826
1827  // Issue two requests for the second process -- these should succeed since
1828  // it is just process 0 that is saturated.
1829  MakeTestRequestWithResourceType(second_filter.get(), 0, kMaxRequests + 3,
1830                                  net::URLRequestTestJob::test_url_2(),
1831                                  RESOURCE_TYPE_SUB_RESOURCE);
1832  MakeTestRequestWithResourceType(second_filter.get(), 0, kMaxRequests + 4,
1833                                  net::URLRequestTestJob::test_url_2(),
1834                                  RESOURCE_TYPE_SUB_RESOURCE);
1835
1836  // Flush all the pending requests.
1837  while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1838  base::MessageLoop::current()->RunUntilIdle();
1839
1840  // Sorts out all the messages we saw by request.
1841  ResourceIPCAccumulator::ClassifiedMessages msgs;
1842  accum_.GetClassifiedMessages(&msgs);
1843
1844  // We issued (kMaxRequests + 4) total requests.
1845  ASSERT_EQ(kMaxRequests + 4, msgs.size());
1846
1847  // Check that the first kMaxRequests succeeded.
1848  for (size_t i = 0; i < kMaxRequests; ++i)
1849    CheckSuccessfulRequest(msgs[i], net::URLRequestTestJob::test_data_2());
1850
1851  // Check that the subsequent two requests (kMaxRequests + 1) and
1852  // (kMaxRequests + 2) were failed, since the per-process bound was reached.
1853  for (int i = 0; i < 2; ++i) {
1854    // Should have sent a single RequestComplete message.
1855    int index = kMaxRequests + i;
1856    CheckFailedRequest(msgs[index], net::URLRequestTestJob::test_data_2(),
1857                       net::ERR_INSUFFICIENT_RESOURCES);
1858  }
1859
1860  // The final 2 requests should have succeeded.
1861  CheckSuccessfulRequest(msgs[kMaxRequests + 2],
1862                         net::URLRequestTestJob::test_data_2());
1863  CheckSuccessfulRequest(msgs[kMaxRequests + 3],
1864                         net::URLRequestTestJob::test_data_2());
1865}
1866
1867// Test that when too many requests are outstanding for a particular
1868// render_process_host_id, any subsequent request from it fails. Also verify
1869// that the global limit is honored.
1870TEST_F(ResourceDispatcherHostTest, TooManyOutstandingRequests) {
1871  // Tighten the bound on the ResourceDispatcherHost, to speed things up.
1872  const size_t kMaxRequestsPerProcess = 2;
1873  host_.set_max_num_in_flight_requests_per_process(kMaxRequestsPerProcess);
1874  const size_t kMaxRequests = 3;
1875  host_.set_max_num_in_flight_requests(kMaxRequests);
1876
1877  // Needed to emulate additional processes.
1878  scoped_refptr<ForwardingFilter> second_filter = MakeForwardingFilter();
1879  scoped_refptr<ForwardingFilter> third_filter = MakeForwardingFilter();
1880
1881  // Saturate the number of outstanding requests for our process.
1882  for (size_t i = 0; i < kMaxRequestsPerProcess; ++i) {
1883    MakeTestRequestWithResourceType(filter_.get(), 0, i + 1,
1884                                    net::URLRequestTestJob::test_url_2(),
1885                                    RESOURCE_TYPE_SUB_RESOURCE);
1886  }
1887
1888  // Issue another request for our process -- this should fail immediately.
1889  MakeTestRequestWithResourceType(filter_.get(), 0, kMaxRequestsPerProcess + 1,
1890                                  net::URLRequestTestJob::test_url_2(),
1891                                  RESOURCE_TYPE_SUB_RESOURCE);
1892
1893  // Issue a request for the second process -- this should succeed, because it
1894  // is just process 0 that is saturated.
1895  MakeTestRequestWithResourceType(
1896      second_filter.get(), 0, kMaxRequestsPerProcess + 2,
1897      net::URLRequestTestJob::test_url_2(), RESOURCE_TYPE_SUB_RESOURCE);
1898
1899  // Issue a request for the third process -- this should fail, because the
1900  // global limit has been reached.
1901  MakeTestRequestWithResourceType(
1902      third_filter.get(), 0, kMaxRequestsPerProcess + 3,
1903      net::URLRequestTestJob::test_url_2(), RESOURCE_TYPE_SUB_RESOURCE);
1904
1905  // Flush all the pending requests.
1906  while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1907  base::MessageLoop::current()->RunUntilIdle();
1908
1909  // Sorts out all the messages we saw by request.
1910  ResourceIPCAccumulator::ClassifiedMessages msgs;
1911  accum_.GetClassifiedMessages(&msgs);
1912
1913  // The processes issued the following requests:
1914  // #1 issued kMaxRequestsPerProcess that passed + 1 that failed
1915  // #2 issued 1 request that passed
1916  // #3 issued 1 request that failed
1917  ASSERT_EQ((kMaxRequestsPerProcess + 1) + 1 + 1, msgs.size());
1918
1919  for (size_t i = 0; i < kMaxRequestsPerProcess; ++i)
1920    CheckSuccessfulRequest(msgs[i], net::URLRequestTestJob::test_data_2());
1921
1922  CheckFailedRequest(msgs[kMaxRequestsPerProcess + 0],
1923                     net::URLRequestTestJob::test_data_2(),
1924                     net::ERR_INSUFFICIENT_RESOURCES);
1925  CheckSuccessfulRequest(msgs[kMaxRequestsPerProcess + 1],
1926                         net::URLRequestTestJob::test_data_2());
1927  CheckFailedRequest(msgs[kMaxRequestsPerProcess + 2],
1928                     net::URLRequestTestJob::test_data_2(),
1929                     net::ERR_INSUFFICIENT_RESOURCES);
1930}
1931
1932// Tests that we sniff the mime type for a simple request.
1933TEST_F(ResourceDispatcherHostTest, MimeSniffed) {
1934  std::string raw_headers("HTTP/1.1 200 OK\n\n");
1935  std::string response_data("<html><title>Test One</title></html>");
1936  SetResponse(raw_headers, response_data);
1937
1938  HandleScheme("http");
1939  MakeTestRequest(0, 1, GURL("http:bla"));
1940
1941  // Flush all pending requests.
1942  while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1943
1944  // Sorts out all the messages we saw by request.
1945  ResourceIPCAccumulator::ClassifiedMessages msgs;
1946  accum_.GetClassifiedMessages(&msgs);
1947  ASSERT_EQ(1U, msgs.size());
1948
1949  ResourceResponseHead response_head;
1950  GetResponseHead(msgs[0], &response_head);
1951  ASSERT_EQ("text/html", response_head.mime_type);
1952}
1953
1954// Tests that we don't sniff the mime type when the server provides one.
1955TEST_F(ResourceDispatcherHostTest, MimeNotSniffed) {
1956  std::string raw_headers("HTTP/1.1 200 OK\n"
1957                          "Content-type: image/jpeg\n\n");
1958  std::string response_data("<html><title>Test One</title></html>");
1959  SetResponse(raw_headers, response_data);
1960
1961  HandleScheme("http");
1962  MakeTestRequest(0, 1, GURL("http:bla"));
1963
1964  // Flush all pending requests.
1965  while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1966
1967  // Sorts out all the messages we saw by request.
1968  ResourceIPCAccumulator::ClassifiedMessages msgs;
1969  accum_.GetClassifiedMessages(&msgs);
1970  ASSERT_EQ(1U, msgs.size());
1971
1972  ResourceResponseHead response_head;
1973  GetResponseHead(msgs[0], &response_head);
1974  ASSERT_EQ("image/jpeg", response_head.mime_type);
1975}
1976
1977// Tests that we don't sniff the mime type when there is no message body.
1978TEST_F(ResourceDispatcherHostTest, MimeNotSniffed2) {
1979  SetResponse("HTTP/1.1 304 Not Modified\n\n");
1980
1981  HandleScheme("http");
1982  MakeTestRequest(0, 1, GURL("http:bla"));
1983
1984  // Flush all pending requests.
1985  while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1986
1987  // Sorts out all the messages we saw by request.
1988  ResourceIPCAccumulator::ClassifiedMessages msgs;
1989  accum_.GetClassifiedMessages(&msgs);
1990  ASSERT_EQ(1U, msgs.size());
1991
1992  ResourceResponseHead response_head;
1993  GetResponseHead(msgs[0], &response_head);
1994  ASSERT_EQ("", response_head.mime_type);
1995}
1996
1997TEST_F(ResourceDispatcherHostTest, MimeSniff204) {
1998  SetResponse("HTTP/1.1 204 No Content\n\n");
1999
2000  HandleScheme("http");
2001  MakeTestRequest(0, 1, GURL("http:bla"));
2002
2003  // Flush all pending requests.
2004  while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2005
2006  // Sorts out all the messages we saw by request.
2007  ResourceIPCAccumulator::ClassifiedMessages msgs;
2008  accum_.GetClassifiedMessages(&msgs);
2009  ASSERT_EQ(1U, msgs.size());
2010
2011  ResourceResponseHead response_head;
2012  GetResponseHead(msgs[0], &response_head);
2013  ASSERT_EQ("text/plain", response_head.mime_type);
2014}
2015
2016TEST_F(ResourceDispatcherHostTest, MimeSniffEmpty) {
2017  SetResponse("HTTP/1.1 200 OK\n\n");
2018
2019  HandleScheme("http");
2020  MakeTestRequest(0, 1, GURL("http:bla"));
2021
2022  // Flush all pending requests.
2023  while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2024
2025  // Sorts out all the messages we saw by request.
2026  ResourceIPCAccumulator::ClassifiedMessages msgs;
2027  accum_.GetClassifiedMessages(&msgs);
2028  ASSERT_EQ(1U, msgs.size());
2029
2030  ResourceResponseHead response_head;
2031  GetResponseHead(msgs[0], &response_head);
2032  ASSERT_EQ("text/plain", response_head.mime_type);
2033}
2034
2035// Tests for crbug.com/31266 (Non-2xx + application/octet-stream).
2036TEST_F(ResourceDispatcherHostTest, ForbiddenDownload) {
2037  std::string raw_headers("HTTP/1.1 403 Forbidden\n"
2038                          "Content-disposition: attachment; filename=blah\n"
2039                          "Content-type: application/octet-stream\n\n");
2040  std::string response_data("<html><title>Test One</title></html>");
2041  SetResponse(raw_headers, response_data);
2042
2043  HandleScheme("http");
2044
2045  // Only MAIN_FRAMEs can trigger a download.
2046  MakeTestRequestWithResourceType(filter_.get(), 0, 1, GURL("http:bla"),
2047                                  RESOURCE_TYPE_MAIN_FRAME);
2048
2049  // Flush all pending requests.
2050  while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2051  base::MessageLoop::current()->RunUntilIdle();
2052
2053  // Sorts out all the messages we saw by request.
2054  ResourceIPCAccumulator::ClassifiedMessages msgs;
2055  accum_.GetClassifiedMessages(&msgs);
2056
2057  // We should have gotten one RequestComplete message.
2058  ASSERT_EQ(1U, msgs.size());
2059  ASSERT_EQ(1U, msgs[0].size());
2060  EXPECT_EQ(ResourceMsg_RequestComplete::ID, msgs[0][0].type());
2061
2062  // The RequestComplete message should have had the error code of
2063  // ERR_INVALID_RESPONSE.
2064  CheckRequestCompleteErrorCode(msgs[0][0], net::ERR_INVALID_RESPONSE);
2065}
2066
2067// Test for http://crbug.com/76202 .  We don't want to destroy a
2068// download request prematurely when processing a cancellation from
2069// the renderer.
2070TEST_F(ResourceDispatcherHostTest, IgnoreCancelForDownloads) {
2071  EXPECT_EQ(0, host_.pending_requests());
2072
2073  int render_view_id = 0;
2074  int request_id = 1;
2075
2076  std::string raw_headers("HTTP\n"
2077                          "Content-disposition: attachment; filename=foo\n\n");
2078  std::string response_data("01234567890123456789\x01foobar");
2079
2080  // Get past sniffing metrics in the BufferedResourceHandler.  Note that
2081  // if we don't get past the sniffing metrics, the result will be that
2082  // the BufferedResourceHandler won't have figured out that it's a download,
2083  // won't have constructed a DownloadResourceHandler, and and the request
2084  // will be successfully canceled below, failing the test.
2085  response_data.resize(1025, ' ');
2086
2087  SetResponse(raw_headers, response_data);
2088  job_factory_->SetDelayedCompleteJobGeneration(true);
2089  HandleScheme("http");
2090
2091  MakeTestRequestWithResourceType(filter_.get(), render_view_id, request_id,
2092                                  GURL("http://example.com/blah"),
2093                                  RESOURCE_TYPE_MAIN_FRAME);
2094  // Return some data so that the request is identified as a download
2095  // and the proper resource handlers are created.
2096  EXPECT_TRUE(net::URLRequestTestJob::ProcessOnePendingMessage());
2097
2098  // And now simulate a cancellation coming from the renderer.
2099  ResourceHostMsg_CancelRequest msg(request_id);
2100  host_.OnMessageReceived(msg, filter_.get());
2101
2102  // Since the request had already started processing as a download,
2103  // the cancellation above should have been ignored and the request
2104  // should still be alive.
2105  EXPECT_EQ(1, host_.pending_requests());
2106
2107  while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2108}
2109
2110TEST_F(ResourceDispatcherHostTest, CancelRequestsForContext) {
2111  EXPECT_EQ(0, host_.pending_requests());
2112
2113  int render_view_id = 0;
2114  int request_id = 1;
2115
2116  std::string raw_headers("HTTP\n"
2117                          "Content-disposition: attachment; filename=foo\n\n");
2118  std::string response_data("01234567890123456789\x01foobar");
2119  // Get past sniffing metrics.
2120  response_data.resize(1025, ' ');
2121
2122  SetResponse(raw_headers, response_data);
2123  job_factory_->SetDelayedCompleteJobGeneration(true);
2124  HandleScheme("http");
2125
2126  MakeTestRequestWithResourceType(filter_.get(), render_view_id, request_id,
2127                                  GURL("http://example.com/blah"),
2128                                  RESOURCE_TYPE_MAIN_FRAME);
2129  // Return some data so that the request is identified as a download
2130  // and the proper resource handlers are created.
2131  EXPECT_TRUE(net::URLRequestTestJob::ProcessOnePendingMessage());
2132
2133  // And now simulate a cancellation coming from the renderer.
2134  ResourceHostMsg_CancelRequest msg(request_id);
2135  host_.OnMessageReceived(msg, filter_.get());
2136
2137  // Since the request had already started processing as a download,
2138  // the cancellation above should have been ignored and the request
2139  // should still be alive.
2140  EXPECT_EQ(1, host_.pending_requests());
2141
2142  // Cancelling by other methods shouldn't work either.
2143  host_.CancelRequestsForProcess(render_view_id);
2144  EXPECT_EQ(1, host_.pending_requests());
2145
2146  // Cancelling by context should work.
2147  host_.CancelRequestsForContext(filter_->resource_context());
2148  EXPECT_EQ(0, host_.pending_requests());
2149}
2150
2151TEST_F(ResourceDispatcherHostTest, CancelRequestsForContextDetached) {
2152  EXPECT_EQ(0, host_.pending_requests());
2153
2154  int render_view_id = 0;
2155  int request_id = 1;
2156
2157  MakeTestRequestWithResourceType(filter_.get(), render_view_id, request_id,
2158                                  net::URLRequestTestJob::test_url_4(),
2159                                  RESOURCE_TYPE_PREFETCH);  // detachable type
2160
2161  // Simulate a cancel coming from the renderer.
2162  RendererCancelRequest(request_id);
2163
2164  // Since the request had already started processing as detachable,
2165  // the cancellation above should have been ignored and the request
2166  // should have been detached.
2167  EXPECT_EQ(1, host_.pending_requests());
2168
2169  // Cancelling by other methods should also leave it detached.
2170  host_.CancelRequestsForProcess(render_view_id);
2171  EXPECT_EQ(1, host_.pending_requests());
2172
2173  // Cancelling by context should work.
2174  host_.CancelRequestsForContext(filter_->resource_context());
2175  EXPECT_EQ(0, host_.pending_requests());
2176}
2177
2178// Test the cancelling of requests that are being transferred to a new renderer
2179// due to a redirection.
2180TEST_F(ResourceDispatcherHostTest, CancelRequestsForContextTransferred) {
2181  EXPECT_EQ(0, host_.pending_requests());
2182
2183  int render_view_id = 0;
2184  int request_id = 1;
2185
2186  std::string raw_headers("HTTP/1.1 200 OK\n"
2187                          "Content-Type: text/html; charset=utf-8\n\n");
2188  std::string response_data("<html>foobar</html>");
2189
2190  SetResponse(raw_headers, response_data);
2191  HandleScheme("http");
2192
2193  MakeTestRequestWithResourceType(filter_.get(), render_view_id, request_id,
2194                                  GURL("http://example.com/blah"),
2195                                  RESOURCE_TYPE_MAIN_FRAME);
2196
2197
2198  GlobalRequestID global_request_id(filter_->child_id(), request_id);
2199  host_.MarkAsTransferredNavigation(global_request_id);
2200
2201  // And now simulate a cancellation coming from the renderer.
2202  ResourceHostMsg_CancelRequest msg(request_id);
2203  host_.OnMessageReceived(msg, filter_.get());
2204
2205  // Since the request is marked as being transferred,
2206  // the cancellation above should have been ignored and the request
2207  // should still be alive.
2208  EXPECT_EQ(1, host_.pending_requests());
2209
2210  // Cancelling by other methods shouldn't work either.
2211  host_.CancelRequestsForProcess(render_view_id);
2212  EXPECT_EQ(1, host_.pending_requests());
2213
2214  // Cancelling by context should work.
2215  host_.CancelRequestsForContext(filter_->resource_context());
2216  EXPECT_EQ(0, host_.pending_requests());
2217}
2218
2219// Test transferred navigations with text/html, which doesn't trigger any
2220// content sniffing.
2221TEST_F(ResourceDispatcherHostTest, TransferNavigationHtml) {
2222  // This test expects the cross site request to be leaked, so it can transfer
2223  // the request directly.
2224  CrossSiteResourceHandler::SetLeakRequestsForTesting(true);
2225
2226  EXPECT_EQ(0, host_.pending_requests());
2227
2228  int render_view_id = 0;
2229  int request_id = 1;
2230
2231  // Configure initial request.
2232  SetResponse("HTTP/1.1 302 Found\n"
2233              "Location: http://other.com/blech\n\n");
2234
2235  HandleScheme("http");
2236
2237  // Temporarily replace ContentBrowserClient with one that will trigger the
2238  // transfer navigation code paths.
2239  TransfersAllNavigationsContentBrowserClient new_client;
2240  ContentBrowserClient* old_client = SetBrowserClientForTesting(&new_client);
2241
2242  MakeTestRequestWithResourceType(filter_.get(), render_view_id, request_id,
2243                                  GURL("http://example.com/blah"),
2244                                  RESOURCE_TYPE_MAIN_FRAME);
2245
2246  // Now that we're blocked on the redirect, update the response and unblock by
2247  // telling the AsyncResourceHandler to follow the redirect.
2248  const std::string kResponseBody = "hello world";
2249  SetResponse("HTTP/1.1 200 OK\n"
2250              "Content-Type: text/html\n\n",
2251              kResponseBody);
2252  ResourceHostMsg_FollowRedirect redirect_msg(request_id);
2253  host_.OnMessageReceived(redirect_msg, filter_.get());
2254  base::MessageLoop::current()->RunUntilIdle();
2255
2256  // Flush all the pending requests to get the response through the
2257  // BufferedResourceHandler.
2258  while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2259
2260  // Restore, now that we've set up a transfer.
2261  SetBrowserClientForTesting(old_client);
2262
2263  // This second filter is used to emulate a second process.
2264  scoped_refptr<ForwardingFilter> second_filter = MakeForwardingFilter();
2265
2266  int new_render_view_id = 1;
2267  int new_request_id = 2;
2268
2269  ResourceHostMsg_Request request =
2270      CreateResourceRequest("GET", RESOURCE_TYPE_MAIN_FRAME,
2271                            GURL("http://other.com/blech"));
2272  request.transferred_request_child_id = filter_->child_id();
2273  request.transferred_request_request_id = request_id;
2274
2275  ResourceHostMsg_RequestResource transfer_request_msg(
2276      new_render_view_id, new_request_id, request);
2277  host_.OnMessageReceived(transfer_request_msg, second_filter.get());
2278  base::MessageLoop::current()->RunUntilIdle();
2279
2280  // Check generated messages.
2281  ResourceIPCAccumulator::ClassifiedMessages msgs;
2282  accum_.GetClassifiedMessages(&msgs);
2283
2284  ASSERT_EQ(2U, msgs.size());
2285  EXPECT_EQ(ResourceMsg_ReceivedRedirect::ID, msgs[0][0].type());
2286  CheckSuccessfulRequest(msgs[1], kResponseBody);
2287}
2288
2289// Test transferred navigations with text/plain, which causes
2290// BufferedResourceHandler to buffer the response to sniff the content
2291// before the transfer occurs.
2292TEST_F(ResourceDispatcherHostTest, TransferNavigationText) {
2293  // This test expects the cross site request to be leaked, so it can transfer
2294  // the request directly.
2295  CrossSiteResourceHandler::SetLeakRequestsForTesting(true);
2296
2297  EXPECT_EQ(0, host_.pending_requests());
2298
2299  int render_view_id = 0;
2300  int request_id = 1;
2301
2302  // Configure initial request.
2303  SetResponse("HTTP/1.1 302 Found\n"
2304              "Location: http://other.com/blech\n\n");
2305
2306  HandleScheme("http");
2307
2308  // Temporarily replace ContentBrowserClient with one that will trigger the
2309  // transfer navigation code paths.
2310  TransfersAllNavigationsContentBrowserClient new_client;
2311  ContentBrowserClient* old_client = SetBrowserClientForTesting(&new_client);
2312
2313  MakeTestRequestWithResourceType(filter_.get(), render_view_id, request_id,
2314                                  GURL("http://example.com/blah"),
2315                                  RESOURCE_TYPE_MAIN_FRAME);
2316
2317  // Now that we're blocked on the redirect, update the response and unblock by
2318  // telling the AsyncResourceHandler to follow the redirect.  Use a text/plain
2319  // MIME type, which causes BufferedResourceHandler to buffer it before the
2320  // transfer occurs.
2321  const std::string kResponseBody = "hello world";
2322  SetResponse("HTTP/1.1 200 OK\n"
2323              "Content-Type: text/plain\n\n",
2324              kResponseBody);
2325  ResourceHostMsg_FollowRedirect redirect_msg(request_id);
2326  host_.OnMessageReceived(redirect_msg, filter_.get());
2327  base::MessageLoop::current()->RunUntilIdle();
2328
2329  // Flush all the pending requests to get the response through the
2330  // BufferedResourceHandler.
2331  while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2332
2333  // Restore, now that we've set up a transfer.
2334  SetBrowserClientForTesting(old_client);
2335
2336  // This second filter is used to emulate a second process.
2337  scoped_refptr<ForwardingFilter> second_filter = MakeForwardingFilter();
2338
2339  int new_render_view_id = 1;
2340  int new_request_id = 2;
2341
2342  ResourceHostMsg_Request request =
2343      CreateResourceRequest("GET", RESOURCE_TYPE_MAIN_FRAME,
2344                            GURL("http://other.com/blech"));
2345  request.transferred_request_child_id = filter_->child_id();
2346  request.transferred_request_request_id = request_id;
2347
2348  ResourceHostMsg_RequestResource transfer_request_msg(
2349      new_render_view_id, new_request_id, request);
2350  host_.OnMessageReceived(transfer_request_msg, second_filter.get());
2351  base::MessageLoop::current()->RunUntilIdle();
2352
2353  // Check generated messages.
2354  ResourceIPCAccumulator::ClassifiedMessages msgs;
2355  accum_.GetClassifiedMessages(&msgs);
2356
2357  ASSERT_EQ(2U, msgs.size());
2358  EXPECT_EQ(ResourceMsg_ReceivedRedirect::ID, msgs[0][0].type());
2359  CheckSuccessfulRequest(msgs[1], kResponseBody);
2360}
2361
2362TEST_F(ResourceDispatcherHostTest, TransferNavigationWithProcessCrash) {
2363  // This test expects the cross site request to be leaked, so it can transfer
2364  // the request directly.
2365  CrossSiteResourceHandler::SetLeakRequestsForTesting(true);
2366
2367  EXPECT_EQ(0, host_.pending_requests());
2368
2369  int render_view_id = 0;
2370  int request_id = 1;
2371  int first_child_id = -1;
2372
2373  // Configure initial request.
2374  SetResponse("HTTP/1.1 302 Found\n"
2375              "Location: http://other.com/blech\n\n");
2376  const std::string kResponseBody = "hello world";
2377
2378  HandleScheme("http");
2379
2380  // Temporarily replace ContentBrowserClient with one that will trigger the
2381  // transfer navigation code paths.
2382  TransfersAllNavigationsContentBrowserClient new_client;
2383  ContentBrowserClient* old_client = SetBrowserClientForTesting(&new_client);
2384
2385  // Create a first filter that can be deleted before the second one starts.
2386  {
2387    scoped_refptr<ForwardingFilter> first_filter = MakeForwardingFilter();
2388    first_child_id = first_filter->child_id();
2389
2390    ResourceHostMsg_Request first_request =
2391        CreateResourceRequest("GET", RESOURCE_TYPE_MAIN_FRAME,
2392                              GURL("http://example.com/blah"));
2393
2394    ResourceHostMsg_RequestResource first_request_msg(
2395        render_view_id, request_id, first_request);
2396    host_.OnMessageReceived(first_request_msg, first_filter.get());
2397    base::MessageLoop::current()->RunUntilIdle();
2398
2399    // Now that we're blocked on the redirect, update the response and unblock
2400    // by telling the AsyncResourceHandler to follow the redirect.
2401    SetResponse("HTTP/1.1 200 OK\n"
2402                "Content-Type: text/html\n\n",
2403                kResponseBody);
2404    ResourceHostMsg_FollowRedirect redirect_msg(request_id);
2405    host_.OnMessageReceived(redirect_msg, first_filter.get());
2406    base::MessageLoop::current()->RunUntilIdle();
2407
2408    // Flush all the pending requests to get the response through the
2409    // BufferedResourceHandler.
2410    while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2411  }
2412  // The first filter is now deleted, as if the child process died.
2413
2414  // Restore.
2415  SetBrowserClientForTesting(old_client);
2416
2417  // Make sure we don't hold onto the ResourceMessageFilter after it is deleted.
2418  GlobalRequestID first_global_request_id(first_child_id, request_id);
2419
2420  // This second filter is used to emulate a second process.
2421  scoped_refptr<ForwardingFilter> second_filter = MakeForwardingFilter();
2422
2423  int new_render_view_id = 1;
2424  int new_request_id = 2;
2425
2426  ResourceHostMsg_Request request =
2427      CreateResourceRequest("GET", RESOURCE_TYPE_MAIN_FRAME,
2428                            GURL("http://other.com/blech"));
2429  request.transferred_request_child_id = first_child_id;
2430  request.transferred_request_request_id = request_id;
2431
2432  // For cleanup.
2433  child_ids_.insert(second_filter->child_id());
2434  ResourceHostMsg_RequestResource transfer_request_msg(
2435      new_render_view_id, new_request_id, request);
2436  host_.OnMessageReceived(transfer_request_msg, second_filter.get());
2437  base::MessageLoop::current()->RunUntilIdle();
2438
2439  // Check generated messages.
2440  ResourceIPCAccumulator::ClassifiedMessages msgs;
2441  accum_.GetClassifiedMessages(&msgs);
2442
2443  ASSERT_EQ(2U, msgs.size());
2444  EXPECT_EQ(ResourceMsg_ReceivedRedirect::ID, msgs[0][0].type());
2445  CheckSuccessfulRequest(msgs[1], kResponseBody);
2446}
2447
2448TEST_F(ResourceDispatcherHostTest, TransferNavigationWithTwoRedirects) {
2449  // This test expects the cross site request to be leaked, so it can transfer
2450  // the request directly.
2451  CrossSiteResourceHandler::SetLeakRequestsForTesting(true);
2452
2453  EXPECT_EQ(0, host_.pending_requests());
2454
2455  int render_view_id = 0;
2456  int request_id = 1;
2457
2458  // Configure initial request.
2459  SetResponse("HTTP/1.1 302 Found\n"
2460              "Location: http://other.com/blech\n\n");
2461
2462  HandleScheme("http");
2463
2464  // Temporarily replace ContentBrowserClient with one that will trigger the
2465  // transfer navigation code paths.
2466  TransfersAllNavigationsContentBrowserClient new_client;
2467  ContentBrowserClient* old_client = SetBrowserClientForTesting(&new_client);
2468
2469  MakeTestRequestWithResourceType(filter_.get(), render_view_id, request_id,
2470                                  GURL("http://example.com/blah"),
2471                                  RESOURCE_TYPE_MAIN_FRAME);
2472
2473  // Now that we're blocked on the redirect, simulate hitting another redirect.
2474  SetResponse("HTTP/1.1 302 Found\n"
2475              "Location: http://other.com/blerg\n\n");
2476  ResourceHostMsg_FollowRedirect redirect_msg(request_id);
2477  host_.OnMessageReceived(redirect_msg, filter_.get());
2478  base::MessageLoop::current()->RunUntilIdle();
2479
2480  // Now that we're blocked on the second redirect, update the response and
2481  // unblock by telling the AsyncResourceHandler to follow the redirect.
2482  // Again, use text/plain to force BufferedResourceHandler to buffer before
2483  // the transfer.
2484  const std::string kResponseBody = "hello world";
2485  SetResponse("HTTP/1.1 200 OK\n"
2486              "Content-Type: text/plain\n\n",
2487              kResponseBody);
2488  ResourceHostMsg_FollowRedirect redirect_msg2(request_id);
2489  host_.OnMessageReceived(redirect_msg2, filter_.get());
2490  base::MessageLoop::current()->RunUntilIdle();
2491
2492  // Flush all the pending requests to get the response through the
2493  // BufferedResourceHandler.
2494  while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2495
2496  // Restore.
2497  SetBrowserClientForTesting(old_client);
2498
2499  // This second filter is used to emulate a second process.
2500  scoped_refptr<ForwardingFilter> second_filter = MakeForwardingFilter();
2501
2502  int new_render_view_id = 1;
2503  int new_request_id = 2;
2504
2505  ResourceHostMsg_Request request =
2506      CreateResourceRequest("GET", RESOURCE_TYPE_MAIN_FRAME,
2507                            GURL("http://other.com/blech"));
2508  request.transferred_request_child_id = filter_->child_id();
2509  request.transferred_request_request_id = request_id;
2510
2511  // For cleanup.
2512  child_ids_.insert(second_filter->child_id());
2513  ResourceHostMsg_RequestResource transfer_request_msg(
2514      new_render_view_id, new_request_id, request);
2515  host_.OnMessageReceived(transfer_request_msg, second_filter.get());
2516
2517  // Verify that we update the ResourceRequestInfo.
2518  GlobalRequestID global_request_id(second_filter->child_id(), new_request_id);
2519  const ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest(
2520      host_.GetURLRequest(global_request_id));
2521  EXPECT_EQ(second_filter->child_id(), info->GetChildID());
2522  EXPECT_EQ(new_render_view_id, info->GetRouteID());
2523  EXPECT_EQ(new_request_id, info->GetRequestID());
2524  EXPECT_EQ(second_filter.get(), info->filter());
2525
2526  // Let request complete.
2527  base::MessageLoop::current()->RunUntilIdle();
2528
2529  // Check generated messages.
2530  ResourceIPCAccumulator::ClassifiedMessages msgs;
2531  accum_.GetClassifiedMessages(&msgs);
2532
2533  ASSERT_EQ(2U, msgs.size());
2534  EXPECT_EQ(ResourceMsg_ReceivedRedirect::ID, msgs[0][0].type());
2535  CheckSuccessfulRequest(msgs[1], kResponseBody);
2536}
2537
2538TEST_F(ResourceDispatcherHostTest, UnknownURLScheme) {
2539  EXPECT_EQ(0, host_.pending_requests());
2540
2541  HandleScheme("http");
2542
2543  MakeTestRequestWithResourceType(filter_.get(), 0, 1, GURL("foo://bar"),
2544                                  RESOURCE_TYPE_MAIN_FRAME);
2545
2546  // Flush all pending requests.
2547  while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2548
2549  // Sort all the messages we saw by request.
2550  ResourceIPCAccumulator::ClassifiedMessages msgs;
2551  accum_.GetClassifiedMessages(&msgs);
2552
2553  // We should have gotten one RequestComplete message.
2554  ASSERT_EQ(1U, msgs[0].size());
2555  EXPECT_EQ(ResourceMsg_RequestComplete::ID, msgs[0][0].type());
2556
2557  // The RequestComplete message should have the error code of
2558  // ERR_UNKNOWN_URL_SCHEME.
2559  CheckRequestCompleteErrorCode(msgs[0][0], net::ERR_UNKNOWN_URL_SCHEME);
2560}
2561
2562TEST_F(ResourceDispatcherHostTest, DataReceivedACKs) {
2563  EXPECT_EQ(0, host_.pending_requests());
2564
2565  SendDataReceivedACKs(true);
2566
2567  HandleScheme("big-job");
2568  MakeTestRequest(0, 1, GURL("big-job:0123456789,1000000"));
2569
2570  // Sort all the messages we saw by request.
2571  ResourceIPCAccumulator::ClassifiedMessages msgs;
2572  accum_.GetClassifiedMessages(&msgs);
2573
2574  size_t size = msgs[0].size();
2575
2576  EXPECT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[0][0].type());
2577  EXPECT_EQ(ResourceMsg_SetDataBuffer::ID, msgs[0][1].type());
2578  for (size_t i = 2; i < size - 1; ++i)
2579    EXPECT_EQ(ResourceMsg_DataReceived::ID, msgs[0][i].type());
2580  EXPECT_EQ(ResourceMsg_RequestComplete::ID, msgs[0][size - 1].type());
2581}
2582
2583// Request a very large detachable resource and cancel part way. Some of the
2584// data should have been sent to the renderer, but not all.
2585TEST_F(ResourceDispatcherHostTest, DataSentBeforeDetach) {
2586  EXPECT_EQ(0, host_.pending_requests());
2587
2588  int render_view_id = 0;
2589  int request_id = 1;
2590
2591  std::string raw_headers("HTTP\n"
2592                          "Content-type: image/jpeg\n\n");
2593  std::string response_data("01234567890123456789\x01foobar");
2594
2595  // Create a response larger than kMaxAllocationSize (currently 32K). Note
2596  // that if this increase beyond 512K we'll need to make the response longer.
2597  const int kAllocSize = 1024*512;
2598  response_data.resize(kAllocSize, ' ');
2599
2600  SetResponse(raw_headers, response_data);
2601  job_factory_->SetDelayedCompleteJobGeneration(true);
2602  HandleScheme("http");
2603
2604  MakeTestRequestWithResourceType(filter_.get(), render_view_id, request_id,
2605                                  GURL("http://example.com/blah"),
2606                                  RESOURCE_TYPE_PREFETCH);
2607
2608  // Get a bit of data before cancelling.
2609  EXPECT_TRUE(net::URLRequestTestJob::ProcessOnePendingMessage());
2610
2611  // Simulate a cancellation coming from the renderer.
2612  ResourceHostMsg_CancelRequest msg(request_id);
2613  host_.OnMessageReceived(msg, filter_.get());
2614
2615  EXPECT_EQ(1, host_.pending_requests());
2616
2617  while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
2618
2619  // Sort all the messages we saw by request.
2620  ResourceIPCAccumulator::ClassifiedMessages msgs;
2621  accum_.GetClassifiedMessages(&msgs);
2622
2623  EXPECT_EQ(4U, msgs[0].size());
2624
2625  // Figure out how many bytes were received by the renderer.
2626  int data_offset;
2627  int data_length;
2628  ASSERT_TRUE(
2629      ExtractDataOffsetAndLength(msgs[0][2], &data_offset, &data_length));
2630  EXPECT_LT(0, data_length);
2631  EXPECT_GT(kAllocSize, data_length);
2632
2633  // Verify the data that was received before cancellation. The request should
2634  // have appeared to cancel, however.
2635  CheckSuccessfulRequestWithErrorCode(
2636      msgs[0],
2637      std::string(response_data.begin(), response_data.begin() + data_length),
2638      net::ERR_ABORTED);
2639}
2640
2641TEST_F(ResourceDispatcherHostTest, DelayedDataReceivedACKs) {
2642  EXPECT_EQ(0, host_.pending_requests());
2643
2644  HandleScheme("big-job");
2645  MakeTestRequest(0, 1, GURL("big-job:0123456789,1000000"));
2646
2647  // Sort all the messages we saw by request.
2648  ResourceIPCAccumulator::ClassifiedMessages msgs;
2649  accum_.GetClassifiedMessages(&msgs);
2650
2651  // We expect 1x ReceivedResponse, 1x SetDataBuffer, Nx ReceivedData messages.
2652  EXPECT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[0][0].type());
2653  EXPECT_EQ(ResourceMsg_SetDataBuffer::ID, msgs[0][1].type());
2654  for (size_t i = 2; i < msgs[0].size(); ++i)
2655    EXPECT_EQ(ResourceMsg_DataReceived::ID, msgs[0][i].type());
2656
2657  // NOTE: If we fail the above checks then it means that we probably didn't
2658  // load a big enough response to trigger the delay mechanism we are trying to
2659  // test!
2660
2661  msgs[0].erase(msgs[0].begin());
2662  msgs[0].erase(msgs[0].begin());
2663
2664  // ACK all DataReceived messages until we find a RequestComplete message.
2665  bool complete = false;
2666  while (!complete) {
2667    for (size_t i = 0; i < msgs[0].size(); ++i) {
2668      if (msgs[0][i].type() == ResourceMsg_RequestComplete::ID) {
2669        complete = true;
2670        break;
2671      }
2672
2673      EXPECT_EQ(ResourceMsg_DataReceived::ID, msgs[0][i].type());
2674
2675      ResourceHostMsg_DataReceived_ACK msg(1);
2676      host_.OnMessageReceived(msg, filter_.get());
2677    }
2678
2679    base::MessageLoop::current()->RunUntilIdle();
2680
2681    msgs.clear();
2682    accum_.GetClassifiedMessages(&msgs);
2683  }
2684}
2685
2686// Flakyness of this test might indicate memory corruption issues with
2687// for example the ResourceBuffer of AsyncResourceHandler.
2688TEST_F(ResourceDispatcherHostTest, DataReceivedUnexpectedACKs) {
2689  EXPECT_EQ(0, host_.pending_requests());
2690
2691  HandleScheme("big-job");
2692  MakeTestRequest(0, 1, GURL("big-job:0123456789,1000000"));
2693
2694  // Sort all the messages we saw by request.
2695  ResourceIPCAccumulator::ClassifiedMessages msgs;
2696  accum_.GetClassifiedMessages(&msgs);
2697
2698  // We expect 1x ReceivedResponse, 1x SetDataBuffer, Nx ReceivedData messages.
2699  EXPECT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[0][0].type());
2700  EXPECT_EQ(ResourceMsg_SetDataBuffer::ID, msgs[0][1].type());
2701  for (size_t i = 2; i < msgs[0].size(); ++i)
2702    EXPECT_EQ(ResourceMsg_DataReceived::ID, msgs[0][i].type());
2703
2704  // NOTE: If we fail the above checks then it means that we probably didn't
2705  // load a big enough response to trigger the delay mechanism.
2706
2707  // Send some unexpected ACKs.
2708  for (size_t i = 0; i < 128; ++i) {
2709    ResourceHostMsg_DataReceived_ACK msg(1);
2710    host_.OnMessageReceived(msg, filter_.get());
2711  }
2712
2713  msgs[0].erase(msgs[0].begin());
2714  msgs[0].erase(msgs[0].begin());
2715
2716  // ACK all DataReceived messages until we find a RequestComplete message.
2717  bool complete = false;
2718  while (!complete) {
2719    for (size_t i = 0; i < msgs[0].size(); ++i) {
2720      if (msgs[0][i].type() == ResourceMsg_RequestComplete::ID) {
2721        complete = true;
2722        break;
2723      }
2724
2725      EXPECT_EQ(ResourceMsg_DataReceived::ID, msgs[0][i].type());
2726
2727      ResourceHostMsg_DataReceived_ACK msg(1);
2728      host_.OnMessageReceived(msg, filter_.get());
2729    }
2730
2731    base::MessageLoop::current()->RunUntilIdle();
2732
2733    msgs.clear();
2734    accum_.GetClassifiedMessages(&msgs);
2735  }
2736}
2737
2738// Tests the dispatcher host's temporary file management.
2739TEST_F(ResourceDispatcherHostTest, RegisterDownloadedTempFile) {
2740  const int kRequestID = 1;
2741
2742  // Create a temporary file.
2743  base::FilePath file_path;
2744  ASSERT_TRUE(base::CreateTemporaryFile(&file_path));
2745  scoped_refptr<ShareableFileReference> deletable_file =
2746      ShareableFileReference::GetOrCreate(
2747          file_path,
2748          ShareableFileReference::DELETE_ON_FINAL_RELEASE,
2749          BrowserThread::GetMessageLoopProxyForThread(
2750              BrowserThread::FILE).get());
2751
2752  // Not readable.
2753  EXPECT_FALSE(ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
2754      filter_->child_id(), file_path));
2755
2756  // Register it for a resource request.
2757  host_.RegisterDownloadedTempFile(filter_->child_id(), kRequestID, file_path);
2758
2759  // Should be readable now.
2760  EXPECT_TRUE(ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
2761      filter_->child_id(), file_path));
2762
2763  // The child releases from the request.
2764  ResourceHostMsg_ReleaseDownloadedFile release_msg(kRequestID);
2765  host_.OnMessageReceived(release_msg, filter_.get());
2766
2767  // Still readable because there is another reference to the file. (The child
2768  // may take additional blob references.)
2769  EXPECT_TRUE(ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
2770      filter_->child_id(), file_path));
2771
2772  // Release extra references and wait for the file to be deleted. (This relies
2773  // on the delete happening on the FILE thread which is mapped to main thread
2774  // in this test.)
2775  deletable_file = NULL;
2776  base::RunLoop().RunUntilIdle();
2777
2778  // The file is no longer readable to the child and has been deleted.
2779  EXPECT_FALSE(ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
2780      filter_->child_id(), file_path));
2781  EXPECT_FALSE(base::PathExists(file_path));
2782}
2783
2784// Tests that temporary files held on behalf of child processes are released
2785// when the child process dies.
2786TEST_F(ResourceDispatcherHostTest, ReleaseTemporiesOnProcessExit) {
2787  const int kRequestID = 1;
2788
2789  // Create a temporary file.
2790  base::FilePath file_path;
2791  ASSERT_TRUE(base::CreateTemporaryFile(&file_path));
2792  scoped_refptr<ShareableFileReference> deletable_file =
2793      ShareableFileReference::GetOrCreate(
2794          file_path,
2795          ShareableFileReference::DELETE_ON_FINAL_RELEASE,
2796          BrowserThread::GetMessageLoopProxyForThread(
2797              BrowserThread::FILE).get());
2798
2799  // Register it for a resource request.
2800  host_.RegisterDownloadedTempFile(filter_->child_id(), kRequestID, file_path);
2801  deletable_file = NULL;
2802
2803  // Should be readable now.
2804  EXPECT_TRUE(ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
2805      filter_->child_id(), file_path));
2806
2807  // Let the process die.
2808  filter_->OnChannelClosing();
2809  base::RunLoop().RunUntilIdle();
2810
2811  // The file is no longer readable to the child and has been deleted.
2812  EXPECT_FALSE(ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
2813      filter_->child_id(), file_path));
2814  EXPECT_FALSE(base::PathExists(file_path));
2815}
2816
2817TEST_F(ResourceDispatcherHostTest, DownloadToFile) {
2818  // Make a request which downloads to file.
2819  ResourceHostMsg_Request request = CreateResourceRequest(
2820      "GET", RESOURCE_TYPE_SUB_RESOURCE, net::URLRequestTestJob::test_url_1());
2821  request.download_to_file = true;
2822  ResourceHostMsg_RequestResource request_msg(0, 1, request);
2823  host_.OnMessageReceived(request_msg, filter_.get());
2824
2825  // Running the message loop until idle does not work because
2826  // RedirectToFileResourceHandler posts things to base::WorkerPool. Instead,
2827  // wait for the ResourceMsg_RequestComplete to go out. Then run the event loop
2828  // until idle so the loader is gone.
2829  WaitForRequestComplete();
2830  base::RunLoop().RunUntilIdle();
2831  EXPECT_EQ(0, host_.pending_requests());
2832
2833  ResourceIPCAccumulator::ClassifiedMessages msgs;
2834  accum_.GetClassifiedMessages(&msgs);
2835
2836  ASSERT_EQ(1U, msgs.size());
2837  const std::vector<IPC::Message>& messages = msgs[0];
2838
2839  // The request should contain the following messages:
2840  //     ReceivedResponse    (indicates headers received and filename)
2841  //     DataDownloaded*     (bytes downloaded and total length)
2842  //     RequestComplete     (request is done)
2843
2844  // ReceivedResponse
2845  ResourceResponseHead response_head;
2846  GetResponseHead(messages, &response_head);
2847  ASSERT_FALSE(response_head.download_file_path.empty());
2848
2849  // DataDownloaded
2850  size_t total_len = 0;
2851  for (size_t i = 1; i < messages.size() - 1; i++) {
2852    ASSERT_EQ(ResourceMsg_DataDownloaded::ID, messages[i].type());
2853    PickleIterator iter(messages[i]);
2854    int request_id, data_len;
2855    ASSERT_TRUE(IPC::ReadParam(&messages[i], &iter, &request_id));
2856    ASSERT_TRUE(IPC::ReadParam(&messages[i], &iter, &data_len));
2857    total_len += data_len;
2858  }
2859  EXPECT_EQ(net::URLRequestTestJob::test_data_1().size(), total_len);
2860
2861  // RequestComplete
2862  CheckRequestCompleteErrorCode(messages.back(), net::OK);
2863
2864  // Verify that the data ended up in the temporary file.
2865  std::string contents;
2866  ASSERT_TRUE(base::ReadFileToString(response_head.download_file_path,
2867                                     &contents));
2868  EXPECT_EQ(net::URLRequestTestJob::test_data_1(), contents);
2869
2870  // The file should be readable by the child.
2871  EXPECT_TRUE(ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
2872      filter_->child_id(), response_head.download_file_path));
2873
2874  // When the renderer releases the file, it should be deleted. Again,
2875  // RunUntilIdle doesn't work because base::WorkerPool is involved.
2876  ShareableFileReleaseWaiter waiter(response_head.download_file_path);
2877  ResourceHostMsg_ReleaseDownloadedFile release_msg(1);
2878  host_.OnMessageReceived(release_msg, filter_.get());
2879  waiter.Wait();
2880  // The release callback runs before the delete is scheduled, so pump the
2881  // message loop for the delete itself. (This relies on the delete happening on
2882  // the FILE thread which is mapped to main thread in this test.)
2883  base::RunLoop().RunUntilIdle();
2884
2885  EXPECT_FALSE(base::PathExists(response_head.download_file_path));
2886  EXPECT_FALSE(ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
2887      filter_->child_id(), response_head.download_file_path));
2888}
2889
2890net::URLRequestJob* TestURLRequestJobFactory::MaybeCreateJobWithProtocolHandler(
2891      const std::string& scheme,
2892      net::URLRequest* request,
2893      net::NetworkDelegate* network_delegate) const {
2894  url_request_jobs_created_count_++;
2895  if (test_fixture_->response_headers_.empty()) {
2896    if (delay_start_) {
2897      return new URLRequestTestDelayedStartJob(request, network_delegate);
2898    } else if (delay_complete_) {
2899      return new URLRequestTestDelayedCompletionJob(request,
2900                                                    network_delegate);
2901    } else if (network_start_notification_) {
2902      return new URLRequestTestDelayedNetworkJob(request, network_delegate);
2903    } else if (scheme == "big-job") {
2904      return new URLRequestBigJob(request, network_delegate);
2905    } else {
2906      return new net::URLRequestTestJob(request, network_delegate);
2907    }
2908  } else {
2909    if (delay_start_) {
2910      return new URLRequestTestDelayedStartJob(
2911          request, network_delegate,
2912          test_fixture_->response_headers_, test_fixture_->response_data_,
2913          false);
2914    } else if (delay_complete_) {
2915      return new URLRequestTestDelayedCompletionJob(
2916          request, network_delegate,
2917          test_fixture_->response_headers_, test_fixture_->response_data_,
2918          false);
2919    } else {
2920      return new net::URLRequestTestJob(
2921          request, network_delegate,
2922          test_fixture_->response_headers_, test_fixture_->response_data_,
2923          false);
2924    }
2925  }
2926}
2927
2928}  // namespace content
2929