resource_dispatcher_host_unittest.cc revision 868fa2fe829687343ffae624259930155e16dbd8
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/bind.h"
8#include "base/files/file_path.h"
9#include "base/memory/scoped_vector.h"
10#include "base/message_loop.h"
11#include "base/pickle.h"
12#include "base/process_util.h"
13#include "base/strings/string_number_conversions.h"
14#include "base/strings/string_split.h"
15#include "content/browser/browser_thread_impl.h"
16#include "content/browser/child_process_security_policy_impl.h"
17#include "content/browser/loader/resource_dispatcher_host_impl.h"
18#include "content/browser/loader/resource_message_filter.h"
19#include "content/browser/worker_host/worker_service_impl.h"
20#include "content/common/child_process_host_impl.h"
21#include "content/common/resource_messages.h"
22#include "content/common/view_messages.h"
23#include "content/public/browser/global_request_id.h"
24#include "content/public/browser/resource_context.h"
25#include "content/public/browser/resource_dispatcher_host_delegate.h"
26#include "content/public/browser/resource_throttle.h"
27#include "content/public/common/process_type.h"
28#include "content/public/common/resource_response.h"
29#include "content/public/test/test_browser_context.h"
30#include "content/test/test_content_browser_client.h"
31#include "net/base/net_errors.h"
32#include "net/base/upload_bytes_element_reader.h"
33#include "net/base/upload_data_stream.h"
34#include "net/http/http_util.h"
35#include "net/url_request/url_request.h"
36#include "net/url_request/url_request_context.h"
37#include "net/url_request/url_request_job.h"
38#include "net/url_request/url_request_simple_job.h"
39#include "net/url_request/url_request_test_job.h"
40#include "testing/gtest/include/gtest/gtest.h"
41#include "webkit/common/appcache/appcache_interfaces.h"
42
43// TODO(eroman): Write unit tests for SafeBrowsing that exercise
44//               SafeBrowsingResourceHandler.
45
46namespace content {
47
48namespace {
49
50// Returns the resource response header structure for this request.
51void GetResponseHead(const std::vector<IPC::Message>& messages,
52                     ResourceResponseHead* response_head) {
53  ASSERT_GE(messages.size(), 2U);
54
55  // The first messages should be received response.
56  ASSERT_EQ(ResourceMsg_ReceivedResponse::ID, messages[0].type());
57
58  PickleIterator iter(messages[0]);
59  int request_id;
60  ASSERT_TRUE(IPC::ReadParam(&messages[0], &iter, &request_id));
61  ASSERT_TRUE(IPC::ReadParam(&messages[0], &iter, response_head));
62}
63
64void GenerateIPCMessage(
65    scoped_refptr<ResourceMessageFilter> filter,
66    scoped_ptr<IPC::Message> message) {
67  bool msg_is_ok;
68  ResourceDispatcherHostImpl::Get()->OnMessageReceived(
69      *message, filter.get(), &msg_is_ok);
70}
71
72}  // namespace
73
74static int RequestIDForMessage(const IPC::Message& msg) {
75  int request_id = -1;
76  switch (msg.type()) {
77    case ResourceMsg_UploadProgress::ID:
78    case ResourceMsg_ReceivedResponse::ID:
79    case ResourceMsg_ReceivedRedirect::ID:
80    case ResourceMsg_SetDataBuffer::ID:
81    case ResourceMsg_DataReceived::ID:
82    case ResourceMsg_RequestComplete::ID: {
83      bool result = PickleIterator(msg).ReadInt(&request_id);
84      DCHECK(result);
85      break;
86    }
87  }
88  return request_id;
89}
90
91static ResourceHostMsg_Request CreateResourceRequest(
92    const char* method,
93    ResourceType::Type type,
94    const GURL& url) {
95  ResourceHostMsg_Request request;
96  request.method = std::string(method);
97  request.url = url;
98  request.first_party_for_cookies = url;  // bypass third-party cookie blocking
99  request.referrer_policy = WebKit::WebReferrerPolicyDefault;
100  request.load_flags = 0;
101  request.origin_pid = 0;
102  request.resource_type = type;
103  request.request_context = 0;
104  request.appcache_host_id = appcache::kNoHostId;
105  request.download_to_file = false;
106  request.is_main_frame = true;
107  request.frame_id = 0;
108  request.parent_is_main_frame = false;
109  request.parent_frame_id = -1;
110  request.transition_type = PAGE_TRANSITION_LINK;
111  request.allow_download = true;
112  return request;
113}
114
115// Spin up the message loop to kick off the request.
116static void KickOffRequest() {
117  base::MessageLoop::current()->RunUntilIdle();
118}
119
120// We may want to move this to a shared space if it is useful for something else
121class ResourceIPCAccumulator {
122 public:
123  void AddMessage(const IPC::Message& msg) {
124    messages_.push_back(msg);
125  }
126
127  // This groups the messages by their request ID. The groups will be in order
128  // that the first message for each request ID was received, and the messages
129  // within the groups will be in the order that they appeared.
130  // Note that this clears messages_.
131  typedef std::vector< std::vector<IPC::Message> > ClassifiedMessages;
132  void GetClassifiedMessages(ClassifiedMessages* msgs);
133
134 private:
135  std::vector<IPC::Message> messages_;
136};
137
138// This is very inefficient as a result of repeatedly extracting the ID, use
139// only for tests!
140void ResourceIPCAccumulator::GetClassifiedMessages(ClassifiedMessages* msgs) {
141  while (!messages_.empty()) {
142    // Ignore unknown message types as it is valid for code to generated other
143    // IPCs as side-effects that we are not testing here.
144    int cur_id = RequestIDForMessage(messages_[0]);
145    if (cur_id != -1) {
146      std::vector<IPC::Message> cur_requests;
147      cur_requests.push_back(messages_[0]);
148      // find all other messages with this ID
149      for (int i = 1; i < static_cast<int>(messages_.size()); i++) {
150        int id = RequestIDForMessage(messages_[i]);
151        if (id == cur_id) {
152          cur_requests.push_back(messages_[i]);
153          messages_.erase(messages_.begin() + i);
154          i--;
155        }
156      }
157      msgs->push_back(cur_requests);
158    }
159    messages_.erase(messages_.begin());
160  }
161}
162
163class MockURLRequestContextSelector
164    : public ResourceMessageFilter::URLRequestContextSelector {
165 public:
166  explicit MockURLRequestContextSelector(
167      net::URLRequestContext* request_context)
168      : request_context_(request_context) {}
169
170  virtual net::URLRequestContext* GetRequestContext(
171      ResourceType::Type request_type) OVERRIDE {
172    return request_context_;
173  }
174
175 private:
176  net::URLRequestContext* const request_context_;
177};
178
179// This class forwards the incoming messages to the ResourceDispatcherHostTest.
180// This is used to emulate different sub-processes, since this filter will
181// have a different ID than the original. For the test, we want all the incoming
182// messages to go to the same place, which is why this forwards.
183class ForwardingFilter : public ResourceMessageFilter {
184 public:
185  explicit ForwardingFilter(IPC::Sender* dest,
186                            ResourceContext* resource_context)
187    : ResourceMessageFilter(
188        ChildProcessHostImpl::GenerateChildProcessUniqueId(),
189        PROCESS_TYPE_RENDERER,
190        resource_context, NULL, NULL, NULL,
191        new MockURLRequestContextSelector(
192            resource_context->GetRequestContext())),
193      dest_(dest) {
194    OnChannelConnected(base::GetCurrentProcId());
195  }
196
197  // ResourceMessageFilter override
198  virtual bool Send(IPC::Message* msg) OVERRIDE {
199    if (!dest_)
200      return false;
201    return dest_->Send(msg);
202  }
203
204 protected:
205  virtual ~ForwardingFilter() {}
206
207 private:
208  IPC::Sender* dest_;
209
210  DISALLOW_COPY_AND_ASSIGN(ForwardingFilter);
211};
212
213// This class is a variation on URLRequestTestJob in that it does
214// not complete start upon entry, only when specifically told to.
215class URLRequestTestDelayedStartJob : public net::URLRequestTestJob {
216 public:
217  URLRequestTestDelayedStartJob(net::URLRequest* request,
218                                net::NetworkDelegate* network_delegate)
219      : net::URLRequestTestJob(request, network_delegate) {
220    Init();
221  }
222  URLRequestTestDelayedStartJob(net::URLRequest* request,
223                                net::NetworkDelegate* network_delegate,
224                                bool auto_advance)
225      : net::URLRequestTestJob(request, network_delegate, auto_advance) {
226    Init();
227  }
228  URLRequestTestDelayedStartJob(net::URLRequest* request,
229                                net::NetworkDelegate* network_delegate,
230                                const std::string& response_headers,
231                                const std::string& response_data,
232                                bool auto_advance)
233      : net::URLRequestTestJob(request,
234                               network_delegate,
235                               response_headers,
236                               response_data,
237                               auto_advance) {
238    Init();
239  }
240
241  // Do nothing until you're told to.
242  virtual void Start() OVERRIDE {}
243
244  // Finish starting a URL request whose job is an instance of
245  // URLRequestTestDelayedStartJob.  It is illegal to call this routine
246  // with a URLRequest that does not use URLRequestTestDelayedStartJob.
247  static void CompleteStart(net::URLRequest* request) {
248    for (URLRequestTestDelayedStartJob* job = list_head_;
249         job;
250         job = job->next_) {
251      if (job->request() == request) {
252        job->net::URLRequestTestJob::Start();
253        return;
254      }
255    }
256    NOTREACHED();
257  }
258
259  static bool DelayedStartQueueEmpty() {
260    return !list_head_;
261  }
262
263  static void ClearQueue() {
264    if (list_head_) {
265      LOG(ERROR)
266          << "Unreleased entries on URLRequestTestDelayedStartJob delay queue"
267          << "; may result in leaks.";
268      list_head_ = NULL;
269    }
270  }
271
272 protected:
273  virtual ~URLRequestTestDelayedStartJob() {
274    for (URLRequestTestDelayedStartJob** job = &list_head_; *job;
275         job = &(*job)->next_) {
276      if (*job == this) {
277        *job = (*job)->next_;
278        return;
279      }
280    }
281    NOTREACHED();
282  }
283
284 private:
285  void Init() {
286    next_ = list_head_;
287    list_head_ = this;
288  }
289
290  static URLRequestTestDelayedStartJob* list_head_;
291  URLRequestTestDelayedStartJob* next_;
292};
293
294URLRequestTestDelayedStartJob*
295URLRequestTestDelayedStartJob::list_head_ = NULL;
296
297// This class is a variation on URLRequestTestJob in that it
298// returns IO_pending errors before every read, not just the first one.
299class URLRequestTestDelayedCompletionJob : public net::URLRequestTestJob {
300 public:
301  URLRequestTestDelayedCompletionJob(net::URLRequest* request,
302                                     net::NetworkDelegate* network_delegate)
303      : net::URLRequestTestJob(request, network_delegate) {}
304  URLRequestTestDelayedCompletionJob(net::URLRequest* request,
305                                     net::NetworkDelegate* network_delegate,
306                                     bool auto_advance)
307      : net::URLRequestTestJob(request, network_delegate, auto_advance) {}
308  URLRequestTestDelayedCompletionJob(net::URLRequest* request,
309                                     net::NetworkDelegate* network_delegate,
310                                     const std::string& response_headers,
311                                     const std::string& response_data,
312                                     bool auto_advance)
313      : net::URLRequestTestJob(request,
314                               network_delegate,
315                               response_headers,
316                               response_data,
317                               auto_advance) {}
318
319 protected:
320  virtual ~URLRequestTestDelayedCompletionJob() {}
321
322 private:
323  virtual bool NextReadAsync() OVERRIDE { return true; }
324};
325
326class URLRequestBigJob : public net::URLRequestSimpleJob {
327 public:
328  URLRequestBigJob(net::URLRequest* request,
329                   net::NetworkDelegate* network_delegate)
330      : net::URLRequestSimpleJob(request, network_delegate) {
331  }
332
333  virtual int GetData(std::string* mime_type,
334                      std::string* charset,
335                      std::string* data,
336                      const net::CompletionCallback& callback) const OVERRIDE {
337    *mime_type = "text/plain";
338    *charset = "UTF-8";
339
340    std::string text;
341    int count;
342    if (!ParseURL(request_->url(), &text, &count))
343      return net::ERR_INVALID_URL;
344
345    data->reserve(text.size() * count);
346    for (int i = 0; i < count; ++i)
347      data->append(text);
348
349    return net::OK;
350  }
351
352 private:
353  virtual ~URLRequestBigJob() {}
354
355  // big-job:substring,N
356  static bool ParseURL(const GURL& url, std::string* text, int* count) {
357    std::vector<std::string> parts;
358    base::SplitString(url.path(), ',', &parts);
359
360    if (parts.size() != 2)
361      return false;
362
363    *text = parts[0];
364    return base::StringToInt(parts[1], count);
365  }
366};
367
368// Associated with an URLRequest to determine if the URLRequest gets deleted.
369class TestUserData : public base::SupportsUserData::Data {
370 public:
371  explicit TestUserData(bool* was_deleted)
372      : was_deleted_(was_deleted) {
373  }
374
375  virtual ~TestUserData() {
376    *was_deleted_ = true;
377  }
378
379 private:
380  bool* was_deleted_;
381};
382
383class TransfersAllNavigationsContentBrowserClient
384    : public TestContentBrowserClient {
385 public:
386  virtual bool ShouldSwapProcessesForRedirect(ResourceContext* resource_context,
387                                              const GURL& current_url,
388                                              const GURL& new_url) OVERRIDE {
389    return true;
390  }
391};
392
393enum GenericResourceThrottleFlags {
394  NONE                      = 0,
395  DEFER_STARTING_REQUEST    = 1 << 0,
396  DEFER_PROCESSING_RESPONSE = 1 << 1,
397  CANCEL_BEFORE_START       = 1 << 2
398};
399
400// Throttle that tracks the current throttle blocking a request.  Only one
401// can throttle any request at a time.
402class GenericResourceThrottle : public ResourceThrottle {
403 public:
404  // The value is used to indicate that the throttle should not provide
405  // a error code when cancelling a request. net::OK is used, because this
406  // is not an error code.
407  static const int USE_DEFAULT_CANCEL_ERROR_CODE = net::OK;
408
409  GenericResourceThrottle(int flags, int code)
410      : flags_(flags),
411        error_code_for_cancellation_(code) {
412  }
413
414  virtual ~GenericResourceThrottle() {
415    if (active_throttle_ == this)
416      active_throttle_ = NULL;
417  }
418
419  // ResourceThrottle implementation:
420  virtual void WillStartRequest(bool* defer) OVERRIDE {
421    ASSERT_EQ(NULL, active_throttle_);
422    if (flags_ & DEFER_STARTING_REQUEST) {
423      active_throttle_ = this;
424      *defer = true;
425    }
426
427    if (flags_ & CANCEL_BEFORE_START) {
428      if (error_code_for_cancellation_ == USE_DEFAULT_CANCEL_ERROR_CODE) {
429        controller()->Cancel();
430      } else {
431        controller()->CancelWithError(error_code_for_cancellation_);
432      }
433    }
434  }
435
436  virtual void WillProcessResponse(bool* defer) OVERRIDE {
437    ASSERT_EQ(NULL, active_throttle_);
438    if (flags_ & DEFER_PROCESSING_RESPONSE) {
439      active_throttle_ = this;
440      *defer = true;
441    }
442  }
443
444  void Resume() {
445    ASSERT_TRUE(this == active_throttle_);
446    active_throttle_ = NULL;
447    controller()->Resume();
448  }
449
450  static GenericResourceThrottle* active_throttle() {
451    return active_throttle_;
452  }
453
454 private:
455  int flags_;  // bit-wise union of GenericResourceThrottleFlags.
456  int error_code_for_cancellation_;
457
458  // The currently active throttle, if any.
459  static GenericResourceThrottle* active_throttle_;
460};
461// static
462GenericResourceThrottle* GenericResourceThrottle::active_throttle_ = NULL;
463
464class TestResourceDispatcherHostDelegate
465    : public ResourceDispatcherHostDelegate {
466 public:
467  TestResourceDispatcherHostDelegate()
468      : create_two_throttles_(false),
469        flags_(NONE),
470        error_code_for_cancellation_(
471            GenericResourceThrottle::USE_DEFAULT_CANCEL_ERROR_CODE) {
472  }
473
474  void set_url_request_user_data(base::SupportsUserData::Data* user_data) {
475    user_data_.reset(user_data);
476  }
477
478  void set_flags(int value) {
479    flags_ = value;
480  }
481
482  void set_error_code_for_cancellation(int code) {
483    error_code_for_cancellation_ = code;
484  }
485
486  void set_create_two_throttles(bool create_two_throttles) {
487    create_two_throttles_ = create_two_throttles;
488  }
489
490  // ResourceDispatcherHostDelegate implementation:
491
492  virtual void RequestBeginning(
493      net::URLRequest* request,
494      ResourceContext* resource_context,
495      appcache::AppCacheService* appcache_service,
496      ResourceType::Type resource_type,
497      int child_id,
498      int route_id,
499      bool is_continuation_of_transferred_request,
500      ScopedVector<ResourceThrottle>* throttles) OVERRIDE {
501    if (user_data_) {
502      const void* key = user_data_.get();
503      request->SetUserData(key, user_data_.release());
504    }
505
506    if (flags_ != NONE) {
507      throttles->push_back(new GenericResourceThrottle(
508          flags_, error_code_for_cancellation_));
509      if (create_two_throttles_)
510        throttles->push_back(new GenericResourceThrottle(
511            flags_, error_code_for_cancellation_));
512    }
513  }
514
515 private:
516  bool create_two_throttles_;
517  int flags_;
518  int error_code_for_cancellation_;
519  scoped_ptr<base::SupportsUserData::Data> user_data_;
520};
521
522class ResourceDispatcherHostTest : public testing::Test,
523                                   public IPC::Sender {
524 public:
525  ResourceDispatcherHostTest()
526      : ui_thread_(BrowserThread::UI, &message_loop_),
527        file_thread_(BrowserThread::FILE_USER_BLOCKING, &message_loop_),
528        cache_thread_(BrowserThread::CACHE, &message_loop_),
529        io_thread_(BrowserThread::IO, &message_loop_),
530        old_factory_(NULL),
531        resource_type_(ResourceType::SUB_RESOURCE),
532        send_data_received_acks_(false) {
533    browser_context_.reset(new TestBrowserContext());
534    BrowserContext::EnsureResourceContextInitialized(browser_context_.get());
535    message_loop_.RunUntilIdle();
536    filter_ = new ForwardingFilter(
537        this, browser_context_->GetResourceContext());
538  }
539
540  virtual ~ResourceDispatcherHostTest() {
541    for (std::set<int>::iterator it = child_ids_.begin();
542         it != child_ids_.end(); ++it) {
543      host_.CancelRequestsForProcess(*it);
544    }
545  }
546
547  // IPC::Sender implementation
548  virtual bool Send(IPC::Message* msg) OVERRIDE {
549    accum_.AddMessage(*msg);
550
551    if (send_data_received_acks_ &&
552        msg->type() == ResourceMsg_DataReceived::ID) {
553      GenerateDataReceivedACK(*msg);
554    }
555
556    delete msg;
557    return true;
558  }
559
560 protected:
561  // testing::Test
562  virtual void SetUp() {
563    DCHECK(!test_fixture_);
564    test_fixture_ = this;
565    ChildProcessSecurityPolicyImpl::GetInstance()->Add(0);
566    net::URLRequest::Deprecated::RegisterProtocolFactory(
567        "test",
568        &ResourceDispatcherHostTest::Factory);
569    EnsureTestSchemeIsAllowed();
570    delay_start_ = false;
571    delay_complete_ = false;
572    url_request_jobs_created_count_ = 0;
573  }
574
575  virtual void TearDown() {
576    net::URLRequest::Deprecated::RegisterProtocolFactory("test", NULL);
577    if (!scheme_.empty())
578      net::URLRequest::Deprecated::RegisterProtocolFactory(
579          scheme_, old_factory_);
580
581    EXPECT_TRUE(URLRequestTestDelayedStartJob::DelayedStartQueueEmpty());
582    URLRequestTestDelayedStartJob::ClearQueue();
583
584    DCHECK(test_fixture_ == this);
585    test_fixture_ = NULL;
586
587    host_.Shutdown();
588
589    ChildProcessSecurityPolicyImpl::GetInstance()->Remove(0);
590
591    // Flush the message loop to make application verifiers happy.
592    if (ResourceDispatcherHostImpl::Get())
593      ResourceDispatcherHostImpl::Get()->CancelRequestsForContext(
594          browser_context_->GetResourceContext());
595
596    WorkerServiceImpl::GetInstance()->PerformTeardownForTesting();
597
598    browser_context_.reset();
599    message_loop_.RunUntilIdle();
600  }
601
602  // Creates a request using the current test object as the filter.
603  void MakeTestRequest(int render_view_id,
604                       int request_id,
605                       const GURL& url);
606
607  // Generates a request using the given filter. This will probably be a
608  // ForwardingFilter.
609  void MakeTestRequest(ResourceMessageFilter* filter,
610                       int render_view_id,
611                       int request_id,
612                       const GURL& url);
613
614  void CancelRequest(int request_id);
615
616  void CompleteStartRequest(int request_id);
617  void CompleteStartRequest(ResourceMessageFilter* filter, int request_id);
618
619  void EnsureSchemeIsAllowed(const std::string& scheme) {
620    ChildProcessSecurityPolicyImpl* policy =
621        ChildProcessSecurityPolicyImpl::GetInstance();
622    if (!policy->IsWebSafeScheme(scheme))
623      policy->RegisterWebSafeScheme(scheme);
624  }
625
626  void EnsureTestSchemeIsAllowed() {
627    EnsureSchemeIsAllowed("test");
628  }
629
630  // Sets a particular response for any request from now on. To switch back to
631  // the default bahavior, pass an empty |headers|. |headers| should be raw-
632  // formatted (NULLs instead of EOLs).
633  void SetResponse(const std::string& headers, const std::string& data) {
634    response_headers_ = net::HttpUtil::AssembleRawHeaders(headers.data(),
635                                                          headers.size());
636    response_data_ = data;
637  }
638  void SetResponse(const std::string& headers) {
639    SetResponse(headers, std::string());
640  }
641
642  // Sets a particular resource type for any request from now on.
643  void SetResourceType(ResourceType::Type type) {
644    resource_type_ = type;
645  }
646
647  void SendDataReceivedACKs(bool send_acks) {
648    send_data_received_acks_ = send_acks;
649  }
650
651  // Intercepts requests for the given protocol.
652  void HandleScheme(const std::string& scheme) {
653    DCHECK(scheme_.empty());
654    DCHECK(!old_factory_);
655    scheme_ = scheme;
656    old_factory_ = net::URLRequest::Deprecated::RegisterProtocolFactory(
657        scheme_, &ResourceDispatcherHostTest::Factory);
658    EnsureSchemeIsAllowed(scheme);
659  }
660
661  // Our own net::URLRequestJob factory.
662  static net::URLRequestJob* Factory(net::URLRequest* request,
663                                     net::NetworkDelegate* network_delegate,
664                                     const std::string& scheme) {
665    url_request_jobs_created_count_++;
666    if (test_fixture_->response_headers_.empty()) {
667      if (delay_start_) {
668        return new URLRequestTestDelayedStartJob(request, network_delegate);
669      } else if (delay_complete_) {
670        return new URLRequestTestDelayedCompletionJob(request,
671                                                      network_delegate);
672      } else if (scheme == "big-job") {
673        return new URLRequestBigJob(request, network_delegate);
674      } else {
675        return new net::URLRequestTestJob(request, network_delegate);
676      }
677    } else {
678      if (delay_start_) {
679        return new URLRequestTestDelayedStartJob(
680            request, network_delegate,
681            test_fixture_->response_headers_, test_fixture_->response_data_,
682            false);
683      } else if (delay_complete_) {
684        return new URLRequestTestDelayedCompletionJob(
685            request, network_delegate,
686            test_fixture_->response_headers_, test_fixture_->response_data_,
687            false);
688      } else {
689        return new net::URLRequestTestJob(
690            request, network_delegate,
691            test_fixture_->response_headers_, test_fixture_->response_data_,
692            false);
693      }
694    }
695  }
696
697  void SetDelayedStartJobGeneration(bool delay_job_start) {
698    delay_start_ = delay_job_start;
699  }
700
701  void SetDelayedCompleteJobGeneration(bool delay_job_complete) {
702    delay_complete_ = delay_job_complete;
703  }
704
705  void GenerateDataReceivedACK(const IPC::Message& msg) {
706    EXPECT_EQ(ResourceMsg_DataReceived::ID, msg.type());
707
708    int request_id = -1;
709    bool result = PickleIterator(msg).ReadInt(&request_id);
710    DCHECK(result);
711    scoped_ptr<IPC::Message> ack(
712        new ResourceHostMsg_DataReceived_ACK(msg.routing_id(), request_id));
713
714    base::MessageLoop::current()->PostTask(
715        FROM_HERE,
716        base::Bind(&GenerateIPCMessage, filter_, base::Passed(&ack)));
717  }
718
719  base::MessageLoopForIO message_loop_;
720  BrowserThreadImpl ui_thread_;
721  BrowserThreadImpl file_thread_;
722  BrowserThreadImpl cache_thread_;
723  BrowserThreadImpl io_thread_;
724  scoped_ptr<TestBrowserContext> browser_context_;
725  scoped_refptr<ForwardingFilter> filter_;
726  ResourceDispatcherHostImpl host_;
727  ResourceIPCAccumulator accum_;
728  std::string response_headers_;
729  std::string response_data_;
730  std::string scheme_;
731  net::URLRequest::ProtocolFactory* old_factory_;
732  ResourceType::Type resource_type_;
733  bool send_data_received_acks_;
734  std::set<int> child_ids_;
735  static ResourceDispatcherHostTest* test_fixture_;
736  static bool delay_start_;
737  static bool delay_complete_;
738  static int url_request_jobs_created_count_;
739};
740// Static.
741ResourceDispatcherHostTest* ResourceDispatcherHostTest::test_fixture_ = NULL;
742bool ResourceDispatcherHostTest::delay_start_ = false;
743bool ResourceDispatcherHostTest::delay_complete_ = false;
744int ResourceDispatcherHostTest::url_request_jobs_created_count_ = 0;
745
746void ResourceDispatcherHostTest::MakeTestRequest(int render_view_id,
747                                                 int request_id,
748                                                 const GURL& url) {
749  MakeTestRequest(filter_.get(), render_view_id, request_id, url);
750}
751
752void ResourceDispatcherHostTest::MakeTestRequest(
753    ResourceMessageFilter* filter,
754    int render_view_id,
755    int request_id,
756    const GURL& url) {
757  // If it's already there, this'll be dropped on the floor, which is fine.
758  child_ids_.insert(filter->child_id());
759
760  ResourceHostMsg_Request request =
761      CreateResourceRequest("GET", resource_type_, url);
762  ResourceHostMsg_RequestResource msg(render_view_id, request_id, request);
763  bool msg_was_ok;
764  host_.OnMessageReceived(msg, filter, &msg_was_ok);
765  KickOffRequest();
766}
767
768void ResourceDispatcherHostTest::CancelRequest(int request_id) {
769  host_.CancelRequest(filter_->child_id(), request_id, false);
770}
771
772void ResourceDispatcherHostTest::CompleteStartRequest(int request_id) {
773  CompleteStartRequest(filter_.get(), request_id);
774}
775
776void ResourceDispatcherHostTest::CompleteStartRequest(
777    ResourceMessageFilter* filter,
778    int request_id) {
779  GlobalRequestID gid(filter->child_id(), request_id);
780  net::URLRequest* req = host_.GetURLRequest(gid);
781  EXPECT_TRUE(req);
782  if (req)
783    URLRequestTestDelayedStartJob::CompleteStart(req);
784}
785
786void CheckSuccessfulRequest(const std::vector<IPC::Message>& messages,
787                            const std::string& reference_data) {
788  // A successful request will have received 4 messages:
789  //     ReceivedResponse    (indicates headers received)
790  //     SetDataBuffer       (contains shared memory handle)
791  //     DataReceived        (data offset and length into shared memory)
792  //     RequestComplete     (request is done)
793  //
794  // This function verifies that we received 4 messages and that they
795  // are appropriate.
796  ASSERT_EQ(4U, messages.size());
797
798  // The first messages should be received response
799  ASSERT_EQ(ResourceMsg_ReceivedResponse::ID, messages[0].type());
800
801  ASSERT_EQ(ResourceMsg_SetDataBuffer::ID, messages[1].type());
802
803  PickleIterator iter(messages[1]);
804  int request_id;
805  ASSERT_TRUE(IPC::ReadParam(&messages[1], &iter, &request_id));
806  base::SharedMemoryHandle shm_handle;
807  ASSERT_TRUE(IPC::ReadParam(&messages[1], &iter, &shm_handle));
808  int shm_size;
809  ASSERT_TRUE(IPC::ReadParam(&messages[1], &iter, &shm_size));
810
811  // Followed by the data, currently we only do the data in one chunk, but
812  // should probably test multiple chunks later
813  ASSERT_EQ(ResourceMsg_DataReceived::ID, messages[2].type());
814
815  PickleIterator iter2(messages[2]);
816  ASSERT_TRUE(IPC::ReadParam(&messages[2], &iter2, &request_id));
817  int data_offset;
818  ASSERT_TRUE(IPC::ReadParam(&messages[2], &iter2, &data_offset));
819  int data_length;
820  ASSERT_TRUE(IPC::ReadParam(&messages[2], &iter2, &data_length));
821
822  ASSERT_EQ(reference_data.size(), static_cast<size_t>(data_length));
823  ASSERT_GE(shm_size, data_length);
824
825  base::SharedMemory shared_mem(shm_handle, true);  // read only
826  shared_mem.Map(data_length);
827  const char* data = static_cast<char*>(shared_mem.memory()) + data_offset;
828  ASSERT_EQ(0, memcmp(reference_data.c_str(), data, data_length));
829
830  // The last message should be all data received.
831  ASSERT_EQ(ResourceMsg_RequestComplete::ID, messages[3].type());
832}
833
834void CheckFailedRequest(const std::vector<IPC::Message>& messages,
835                        const std::string& reference_data,
836                        int expected_error) {
837  ASSERT_LT(0U, messages.size());
838  ASSERT_GE(2U, messages.size());
839  size_t failure_index = messages.size() - 1;
840
841  if (messages.size() == 2) {
842    EXPECT_EQ(ResourceMsg_ReceivedResponse::ID, messages[0].type());
843  }
844  EXPECT_EQ(ResourceMsg_RequestComplete::ID, messages[failure_index].type());
845
846  int request_id;
847  int error_code;
848
849  PickleIterator iter(messages[failure_index]);
850  EXPECT_TRUE(IPC::ReadParam(&messages[failure_index], &iter, &request_id));
851  EXPECT_TRUE(IPC::ReadParam(&messages[failure_index], &iter, &error_code));
852  EXPECT_EQ(expected_error, error_code);
853}
854
855// Tests whether many messages get dispatched properly.
856TEST_F(ResourceDispatcherHostTest, TestMany) {
857  MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
858  MakeTestRequest(0, 2, net::URLRequestTestJob::test_url_2());
859  MakeTestRequest(0, 3, net::URLRequestTestJob::test_url_3());
860
861  // flush all the pending requests
862  while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
863
864  // sorts out all the messages we saw by request
865  ResourceIPCAccumulator::ClassifiedMessages msgs;
866  accum_.GetClassifiedMessages(&msgs);
867
868  // there are three requests, so we should have gotten them classified as such
869  ASSERT_EQ(3U, msgs.size());
870
871  CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_1());
872  CheckSuccessfulRequest(msgs[1], net::URLRequestTestJob::test_data_2());
873  CheckSuccessfulRequest(msgs[2], net::URLRequestTestJob::test_data_3());
874}
875
876void CheckCancelledRequestCompleteMessage(const IPC::Message& message) {
877  ASSERT_EQ(ResourceMsg_RequestComplete::ID, message.type());
878
879  int request_id;
880  int error_code;
881
882  PickleIterator iter(message);
883  ASSERT_TRUE(IPC::ReadParam(&message, &iter, &request_id));
884  ASSERT_TRUE(IPC::ReadParam(&message, &iter, &error_code));
885
886  EXPECT_EQ(net::ERR_ABORTED, error_code);
887}
888
889// Tests whether messages get canceled properly. We issue three requests,
890// cancel one of them, and make sure that each sent the proper notifications.
891TEST_F(ResourceDispatcherHostTest, Cancel) {
892  MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
893  MakeTestRequest(0, 2, net::URLRequestTestJob::test_url_2());
894  MakeTestRequest(0, 3, net::URLRequestTestJob::test_url_3());
895  CancelRequest(2);
896
897  // flush all the pending requests
898  while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
899  base::MessageLoop::current()->RunUntilIdle();
900
901  ResourceIPCAccumulator::ClassifiedMessages msgs;
902  accum_.GetClassifiedMessages(&msgs);
903
904  // there are three requests, so we should have gotten them classified as such
905  ASSERT_EQ(3U, msgs.size());
906
907  CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_1());
908  CheckSuccessfulRequest(msgs[2], net::URLRequestTestJob::test_data_3());
909
910  // Check that request 2 got canceled.
911  ASSERT_EQ(2U, msgs[1].size());
912  ASSERT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[1][0].type());
913  CheckCancelledRequestCompleteMessage(msgs[1][1]);
914}
915
916TEST_F(ResourceDispatcherHostTest, CancelWhileStartIsDeferred) {
917  bool was_deleted = false;
918
919  // Arrange to have requests deferred before starting.
920  TestResourceDispatcherHostDelegate delegate;
921  delegate.set_flags(DEFER_STARTING_REQUEST);
922  delegate.set_url_request_user_data(new TestUserData(&was_deleted));
923  host_.SetDelegate(&delegate);
924
925  MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
926  CancelRequest(1);
927
928  // Our TestResourceThrottle should not have been deleted yet.  This is to
929  // ensure that destruction of the URLRequest happens asynchronously to
930  // calling CancelRequest.
931  EXPECT_FALSE(was_deleted);
932
933  // flush all the pending requests
934  while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
935  base::MessageLoop::current()->RunUntilIdle();
936
937  EXPECT_TRUE(was_deleted);
938}
939
940// Tests if cancel is called in ResourceThrottle::WillStartRequest, then the
941// URLRequest will not be started.
942TEST_F(ResourceDispatcherHostTest, CancelInResourceThrottleWillStartRequest) {
943  TestResourceDispatcherHostDelegate delegate;
944  delegate.set_flags(CANCEL_BEFORE_START);
945  host_.SetDelegate(&delegate);
946
947  MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
948
949  // flush all the pending requests
950  while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
951  base::MessageLoop::current()->RunUntilIdle();
952
953  ResourceIPCAccumulator::ClassifiedMessages msgs;
954  accum_.GetClassifiedMessages(&msgs);
955
956  // Check that request got canceled.
957  ASSERT_EQ(1U, msgs[0].size());
958  CheckCancelledRequestCompleteMessage(msgs[0][0]);
959
960  // Make sure URLRequest is never started.
961  EXPECT_EQ(0, url_request_jobs_created_count_);
962}
963
964TEST_F(ResourceDispatcherHostTest, PausedStartError) {
965  // Arrange to have requests deferred before processing response headers.
966  TestResourceDispatcherHostDelegate delegate;
967  delegate.set_flags(DEFER_PROCESSING_RESPONSE);
968  host_.SetDelegate(&delegate);
969
970  SetDelayedStartJobGeneration(true);
971  MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_error());
972  CompleteStartRequest(1);
973
974  // flush all the pending requests
975  while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
976  base::MessageLoop::current()->RunUntilIdle();
977
978  EXPECT_EQ(0, host_.pending_requests());
979}
980
981TEST_F(ResourceDispatcherHostTest, ThrottleAndResumeTwice) {
982  // Arrange to have requests deferred before starting.
983  TestResourceDispatcherHostDelegate delegate;
984  delegate.set_flags(DEFER_STARTING_REQUEST);
985  delegate.set_create_two_throttles(true);
986  host_.SetDelegate(&delegate);
987
988  // Make sure the first throttle blocked the request, and then resume.
989  MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
990  GenericResourceThrottle* first_throttle =
991      GenericResourceThrottle::active_throttle();
992  ASSERT_TRUE(first_throttle);
993  first_throttle->Resume();
994
995  // Make sure the second throttle blocked the request, and then resume.
996  ASSERT_TRUE(GenericResourceThrottle::active_throttle());
997  ASSERT_NE(first_throttle, GenericResourceThrottle::active_throttle());
998  GenericResourceThrottle::active_throttle()->Resume();
999
1000  ASSERT_FALSE(GenericResourceThrottle::active_throttle());
1001
1002  // The request is started asynchronously.
1003  base::MessageLoop::current()->RunUntilIdle();
1004
1005  // Flush all the pending requests.
1006  while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1007
1008  EXPECT_EQ(0, host_.pending_requests());
1009
1010  // Make sure the request completed successfully.
1011  ResourceIPCAccumulator::ClassifiedMessages msgs;
1012  accum_.GetClassifiedMessages(&msgs);
1013  ASSERT_EQ(1U, msgs.size());
1014  CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_1());
1015}
1016
1017
1018// Tests that the delegate can cancel a request and provide a error code.
1019TEST_F(ResourceDispatcherHostTest, CancelInDelegate) {
1020  TestResourceDispatcherHostDelegate delegate;
1021  delegate.set_flags(CANCEL_BEFORE_START);
1022  delegate.set_error_code_for_cancellation(net::ERR_ACCESS_DENIED);
1023  host_.SetDelegate(&delegate);
1024
1025  MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
1026  // The request will get cancelled by the throttle.
1027
1028  // flush all the pending requests
1029  while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1030  base::MessageLoop::current()->RunUntilIdle();
1031
1032  ResourceIPCAccumulator::ClassifiedMessages msgs;
1033  accum_.GetClassifiedMessages(&msgs);
1034
1035  // Check the cancellation
1036  ASSERT_EQ(1U, msgs.size());
1037  ASSERT_EQ(1U, msgs[0].size());
1038  ASSERT_EQ(ResourceMsg_RequestComplete::ID, msgs[0][0].type());
1039
1040  int request_id;
1041  int error_code;
1042
1043  PickleIterator iter(msgs[0][0]);
1044  ASSERT_TRUE(IPC::ReadParam(&msgs[0][0], &iter, &request_id));
1045  ASSERT_TRUE(IPC::ReadParam(&msgs[0][0], &iter, &error_code));
1046
1047  EXPECT_EQ(net::ERR_ACCESS_DENIED, error_code);
1048}
1049
1050// The host delegate acts as a second one so we can have some requests
1051// pending and some canceled.
1052class TestFilter : public ForwardingFilter {
1053 public:
1054  explicit TestFilter(ResourceContext* resource_context)
1055      : ForwardingFilter(NULL, resource_context),
1056        has_canceled_(false),
1057        received_after_canceled_(0) {
1058  }
1059
1060  // ForwardingFilter override
1061  virtual bool Send(IPC::Message* msg) OVERRIDE {
1062    // no messages should be received when the process has been canceled
1063    if (has_canceled_)
1064      received_after_canceled_++;
1065    delete msg;
1066    return true;
1067  }
1068
1069  bool has_canceled_;
1070  int received_after_canceled_;
1071
1072 private:
1073  virtual ~TestFilter() {}
1074};
1075
1076// Tests CancelRequestsForProcess
1077TEST_F(ResourceDispatcherHostTest, TestProcessCancel) {
1078  scoped_refptr<TestFilter> test_filter = new TestFilter(
1079      browser_context_->GetResourceContext());
1080
1081  // request 1 goes to the test delegate
1082  ResourceHostMsg_Request request = CreateResourceRequest(
1083      "GET", ResourceType::SUB_RESOURCE, net::URLRequestTestJob::test_url_1());
1084
1085  MakeTestRequest(test_filter.get(), 0, 1,
1086                  net::URLRequestTestJob::test_url_1());
1087
1088  // request 2 goes to us
1089  MakeTestRequest(0, 2, net::URLRequestTestJob::test_url_2());
1090
1091  // request 3 goes to the test delegate
1092  MakeTestRequest(test_filter.get(), 0, 3,
1093                  net::URLRequestTestJob::test_url_3());
1094
1095  // Make sure all requests have finished stage one. test_url_1 will have
1096  // finished.
1097  base::MessageLoop::current()->RunUntilIdle();
1098
1099  // TODO(mbelshe):
1100  // Now that the async IO path is in place, the IO always completes on the
1101  // initial call; so the requests have already completed.  This basically
1102  // breaks the whole test.
1103  //EXPECT_EQ(3, host_.pending_requests());
1104
1105  // Process each request for one level so one callback is called.
1106  for (int i = 0; i < 2; i++)
1107    EXPECT_TRUE(net::URLRequestTestJob::ProcessOnePendingMessage());
1108
1109  // Cancel the requests to the test process.
1110  host_.CancelRequestsForProcess(filter_->child_id());
1111  test_filter->has_canceled_ = true;
1112
1113  // Flush all the pending requests.
1114  while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1115
1116  EXPECT_EQ(0, host_.pending_requests());
1117
1118  // The test delegate should not have gotten any messages after being canceled.
1119  ASSERT_EQ(0, test_filter->received_after_canceled_);
1120
1121  // We should have gotten exactly one result.
1122  ResourceIPCAccumulator::ClassifiedMessages msgs;
1123  accum_.GetClassifiedMessages(&msgs);
1124  ASSERT_EQ(1U, msgs.size());
1125  CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_2());
1126}
1127
1128// Tests blocking and resuming requests.
1129TEST_F(ResourceDispatcherHostTest, TestBlockingResumingRequests) {
1130  host_.BlockRequestsForRoute(filter_->child_id(), 1);
1131  host_.BlockRequestsForRoute(filter_->child_id(), 2);
1132  host_.BlockRequestsForRoute(filter_->child_id(), 3);
1133
1134  MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
1135  MakeTestRequest(1, 2, net::URLRequestTestJob::test_url_2());
1136  MakeTestRequest(0, 3, net::URLRequestTestJob::test_url_3());
1137  MakeTestRequest(1, 4, net::URLRequestTestJob::test_url_1());
1138  MakeTestRequest(2, 5, net::URLRequestTestJob::test_url_2());
1139  MakeTestRequest(3, 6, net::URLRequestTestJob::test_url_3());
1140
1141  // Flush all the pending requests
1142  while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1143
1144  // Sort out all the messages we saw by request
1145  ResourceIPCAccumulator::ClassifiedMessages msgs;
1146  accum_.GetClassifiedMessages(&msgs);
1147
1148  // All requests but the 2 for the RVH 0 should have been blocked.
1149  ASSERT_EQ(2U, msgs.size());
1150
1151  CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_1());
1152  CheckSuccessfulRequest(msgs[1], net::URLRequestTestJob::test_data_3());
1153
1154  // Resume requests for RVH 1 and flush pending requests.
1155  host_.ResumeBlockedRequestsForRoute(filter_->child_id(), 1);
1156  KickOffRequest();
1157  while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1158
1159  msgs.clear();
1160  accum_.GetClassifiedMessages(&msgs);
1161  ASSERT_EQ(2U, msgs.size());
1162  CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_2());
1163  CheckSuccessfulRequest(msgs[1], net::URLRequestTestJob::test_data_1());
1164
1165  // Test that new requests are not blocked for RVH 1.
1166  MakeTestRequest(1, 7, net::URLRequestTestJob::test_url_1());
1167  while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1168  msgs.clear();
1169  accum_.GetClassifiedMessages(&msgs);
1170  ASSERT_EQ(1U, msgs.size());
1171  CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_1());
1172
1173  // Now resumes requests for all RVH (2 and 3).
1174  host_.ResumeBlockedRequestsForRoute(filter_->child_id(), 2);
1175  host_.ResumeBlockedRequestsForRoute(filter_->child_id(), 3);
1176  KickOffRequest();
1177  while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1178
1179  msgs.clear();
1180  accum_.GetClassifiedMessages(&msgs);
1181  ASSERT_EQ(2U, msgs.size());
1182  CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_2());
1183  CheckSuccessfulRequest(msgs[1], net::URLRequestTestJob::test_data_3());
1184}
1185
1186// Tests blocking and canceling requests.
1187TEST_F(ResourceDispatcherHostTest, TestBlockingCancelingRequests) {
1188  host_.BlockRequestsForRoute(filter_->child_id(), 1);
1189
1190  MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
1191  MakeTestRequest(1, 2, net::URLRequestTestJob::test_url_2());
1192  MakeTestRequest(0, 3, net::URLRequestTestJob::test_url_3());
1193  MakeTestRequest(1, 4, net::URLRequestTestJob::test_url_1());
1194
1195  // Flush all the pending requests.
1196  while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1197
1198  // Sort out all the messages we saw by request.
1199  ResourceIPCAccumulator::ClassifiedMessages msgs;
1200  accum_.GetClassifiedMessages(&msgs);
1201
1202  // The 2 requests for the RVH 0 should have been processed.
1203  ASSERT_EQ(2U, msgs.size());
1204
1205  CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_1());
1206  CheckSuccessfulRequest(msgs[1], net::URLRequestTestJob::test_data_3());
1207
1208  // Cancel requests for RVH 1.
1209  host_.CancelBlockedRequestsForRoute(filter_->child_id(), 1);
1210  KickOffRequest();
1211  while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1212
1213  msgs.clear();
1214  accum_.GetClassifiedMessages(&msgs);
1215  ASSERT_EQ(0U, msgs.size());
1216}
1217
1218// Tests that blocked requests are canceled if their associated process dies.
1219TEST_F(ResourceDispatcherHostTest, TestBlockedRequestsProcessDies) {
1220  // This second filter is used to emulate a second process.
1221  scoped_refptr<ForwardingFilter> second_filter = new ForwardingFilter(
1222      this, browser_context_->GetResourceContext());
1223
1224  host_.BlockRequestsForRoute(second_filter->child_id(), 0);
1225
1226  MakeTestRequest(filter_.get(), 0, 1, net::URLRequestTestJob::test_url_1());
1227  MakeTestRequest(second_filter.get(), 0, 2,
1228                  net::URLRequestTestJob::test_url_2());
1229  MakeTestRequest(filter_.get(), 0, 3, net::URLRequestTestJob::test_url_3());
1230  MakeTestRequest(second_filter.get(), 0, 4,
1231                  net::URLRequestTestJob::test_url_1());
1232
1233  // Simulate process death.
1234  host_.CancelRequestsForProcess(second_filter->child_id());
1235
1236  // Flush all the pending requests.
1237  while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1238
1239  // Sort out all the messages we saw by request.
1240  ResourceIPCAccumulator::ClassifiedMessages msgs;
1241  accum_.GetClassifiedMessages(&msgs);
1242
1243  // The 2 requests for the RVH 0 should have been processed.
1244  ASSERT_EQ(2U, msgs.size());
1245
1246  CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_1());
1247  CheckSuccessfulRequest(msgs[1], net::URLRequestTestJob::test_data_3());
1248
1249  EXPECT_TRUE(host_.blocked_loaders_map_.empty());
1250}
1251
1252// Tests that blocked requests don't leak when the ResourceDispatcherHost goes
1253// away.  Note that we rely on Purify for finding the leaks if any.
1254// If this test turns the Purify bot red, check the ResourceDispatcherHost
1255// destructor to make sure the blocked requests are deleted.
1256TEST_F(ResourceDispatcherHostTest, TestBlockedRequestsDontLeak) {
1257  // This second filter is used to emulate a second process.
1258  scoped_refptr<ForwardingFilter> second_filter = new ForwardingFilter(
1259      this, browser_context_->GetResourceContext());
1260
1261  host_.BlockRequestsForRoute(filter_->child_id(), 1);
1262  host_.BlockRequestsForRoute(filter_->child_id(), 2);
1263  host_.BlockRequestsForRoute(second_filter->child_id(), 1);
1264
1265  MakeTestRequest(filter_.get(), 0, 1, net::URLRequestTestJob::test_url_1());
1266  MakeTestRequest(filter_.get(), 1, 2, net::URLRequestTestJob::test_url_2());
1267  MakeTestRequest(filter_.get(), 0, 3, net::URLRequestTestJob::test_url_3());
1268  MakeTestRequest(second_filter.get(), 1, 4,
1269                  net::URLRequestTestJob::test_url_1());
1270  MakeTestRequest(filter_.get(), 2, 5, net::URLRequestTestJob::test_url_2());
1271  MakeTestRequest(filter_.get(), 2, 6, net::URLRequestTestJob::test_url_3());
1272
1273  host_.CancelRequestsForProcess(filter_->child_id());
1274  host_.CancelRequestsForProcess(second_filter->child_id());
1275
1276  // Flush all the pending requests.
1277  while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1278}
1279
1280// Test the private helper method "CalculateApproximateMemoryCost()".
1281TEST_F(ResourceDispatcherHostTest, CalculateApproximateMemoryCost) {
1282  net::URLRequestContext context;
1283  net::URLRequest req(GURL("http://www.google.com"), NULL, &context);
1284  EXPECT_EQ(4427,
1285            ResourceDispatcherHostImpl::CalculateApproximateMemoryCost(&req));
1286
1287  // Add 9 bytes of referrer.
1288  req.SetReferrer("123456789");
1289  EXPECT_EQ(4436,
1290            ResourceDispatcherHostImpl::CalculateApproximateMemoryCost(&req));
1291
1292  // Add 33 bytes of upload content.
1293  std::string upload_content;
1294  upload_content.resize(33);
1295  std::fill(upload_content.begin(), upload_content.end(), 'x');
1296  scoped_ptr<net::UploadElementReader> reader(new net::UploadBytesElementReader(
1297      upload_content.data(), upload_content.size()));
1298  req.set_upload(make_scoped_ptr(
1299      net::UploadDataStream::CreateWithReader(reader.Pass(), 0)));
1300
1301  // Since the upload throttling is disabled, this has no effect on the cost.
1302  EXPECT_EQ(4436,
1303            ResourceDispatcherHostImpl::CalculateApproximateMemoryCost(&req));
1304}
1305
1306// Test that too much memory for outstanding requests for a particular
1307// render_process_host_id causes requests to fail.
1308TEST_F(ResourceDispatcherHostTest, TooMuchOutstandingRequestsMemory) {
1309  // Expected cost of each request as measured by
1310  // ResourceDispatcherHost::CalculateApproximateMemoryCost().
1311  int kMemoryCostOfTest2Req =
1312      ResourceDispatcherHostImpl::kAvgBytesPerOutstandingRequest +
1313      std::string("GET").size() +
1314      net::URLRequestTestJob::test_url_2().spec().size();
1315
1316  // Tighten the bound on the ResourceDispatcherHost, to speed things up.
1317  int kMaxCostPerProcess = 440000;
1318  host_.set_max_outstanding_requests_cost_per_process(kMaxCostPerProcess);
1319
1320  // Determine how many instance of test_url_2() we can request before
1321  // throttling kicks in.
1322  size_t kMaxRequests = kMaxCostPerProcess / kMemoryCostOfTest2Req;
1323
1324  // This second filter is used to emulate a second process.
1325  scoped_refptr<ForwardingFilter> second_filter = new ForwardingFilter(
1326      this, browser_context_->GetResourceContext());
1327
1328  // Saturate the number of outstanding requests for our process.
1329  for (size_t i = 0; i < kMaxRequests; ++i) {
1330    MakeTestRequest(filter_.get(), 0, i + 1,
1331                    net::URLRequestTestJob::test_url_2());
1332  }
1333
1334  // Issue two more requests for our process -- these should fail immediately.
1335  MakeTestRequest(filter_.get(), 0, kMaxRequests + 1,
1336                  net::URLRequestTestJob::test_url_2());
1337  MakeTestRequest(filter_.get(), 0, kMaxRequests + 2,
1338                  net::URLRequestTestJob::test_url_2());
1339
1340  // Issue two requests for the second process -- these should succeed since
1341  // it is just process 0 that is saturated.
1342  MakeTestRequest(second_filter.get(), 0, kMaxRequests + 3,
1343                  net::URLRequestTestJob::test_url_2());
1344  MakeTestRequest(second_filter.get(), 0, kMaxRequests + 4,
1345                  net::URLRequestTestJob::test_url_2());
1346
1347  // Flush all the pending requests.
1348  while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1349  base::MessageLoop::current()->RunUntilIdle();
1350
1351  // Sorts out all the messages we saw by request.
1352  ResourceIPCAccumulator::ClassifiedMessages msgs;
1353  accum_.GetClassifiedMessages(&msgs);
1354
1355  // We issued (kMaxRequests + 4) total requests.
1356  ASSERT_EQ(kMaxRequests + 4, msgs.size());
1357
1358  // Check that the first kMaxRequests succeeded.
1359  for (size_t i = 0; i < kMaxRequests; ++i)
1360    CheckSuccessfulRequest(msgs[i], net::URLRequestTestJob::test_data_2());
1361
1362  // Check that the subsequent two requests (kMaxRequests + 1) and
1363  // (kMaxRequests + 2) were failed, since the per-process bound was reached.
1364  for (int i = 0; i < 2; ++i) {
1365    // Should have sent a single RequestComplete message.
1366    int index = kMaxRequests + i;
1367    CheckFailedRequest(msgs[index], net::URLRequestTestJob::test_data_2(),
1368                       net::ERR_INSUFFICIENT_RESOURCES);
1369  }
1370
1371  // The final 2 requests should have succeeded.
1372  CheckSuccessfulRequest(msgs[kMaxRequests + 2],
1373                         net::URLRequestTestJob::test_data_2());
1374  CheckSuccessfulRequest(msgs[kMaxRequests + 3],
1375                         net::URLRequestTestJob::test_data_2());
1376}
1377
1378// Test that when too many requests are outstanding for a particular
1379// render_process_host_id, any subsequent request from it fails. Also verify
1380// that the global limit is honored.
1381TEST_F(ResourceDispatcherHostTest, TooManyOutstandingRequests) {
1382  // Tighten the bound on the ResourceDispatcherHost, to speed things up.
1383  const size_t kMaxRequestsPerProcess = 2;
1384  host_.set_max_num_in_flight_requests_per_process(kMaxRequestsPerProcess);
1385  const size_t kMaxRequests = 3;
1386  host_.set_max_num_in_flight_requests(kMaxRequests);
1387
1388  // Needed to emulate additional processes.
1389  scoped_refptr<ForwardingFilter> second_filter = new ForwardingFilter(
1390      this, browser_context_->GetResourceContext());
1391  scoped_refptr<ForwardingFilter> third_filter = new ForwardingFilter(
1392      this, browser_context_->GetResourceContext());
1393
1394  // Saturate the number of outstanding requests for our process.
1395  for (size_t i = 0; i < kMaxRequestsPerProcess; ++i) {
1396    MakeTestRequest(filter_.get(), 0, i + 1,
1397                    net::URLRequestTestJob::test_url_2());
1398  }
1399
1400  // Issue another request for our process -- this should fail immediately.
1401  MakeTestRequest(filter_.get(), 0, kMaxRequestsPerProcess + 1,
1402                  net::URLRequestTestJob::test_url_2());
1403
1404  // Issue a request for the second process -- this should succeed, because it
1405  // is just process 0 that is saturated.
1406  MakeTestRequest(second_filter.get(), 0, kMaxRequestsPerProcess + 2,
1407                  net::URLRequestTestJob::test_url_2());
1408
1409  // Issue a request for the third process -- this should fail, because the
1410  // global limit has been reached.
1411  MakeTestRequest(third_filter.get(), 0, kMaxRequestsPerProcess + 3,
1412                  net::URLRequestTestJob::test_url_2());
1413
1414  // Flush all the pending requests.
1415  while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1416  base::MessageLoop::current()->RunUntilIdle();
1417
1418  // Sorts out all the messages we saw by request.
1419  ResourceIPCAccumulator::ClassifiedMessages msgs;
1420  accum_.GetClassifiedMessages(&msgs);
1421
1422  // The processes issued the following requests:
1423  // #1 issued kMaxRequestsPerProcess that passed + 1 that failed
1424  // #2 issued 1 request that passed
1425  // #3 issued 1 request that failed
1426  ASSERT_EQ((kMaxRequestsPerProcess + 1) + 1 + 1, msgs.size());
1427
1428  for (size_t i = 0; i < kMaxRequestsPerProcess; ++i)
1429    CheckSuccessfulRequest(msgs[i], net::URLRequestTestJob::test_data_2());
1430
1431  CheckFailedRequest(msgs[kMaxRequestsPerProcess + 0],
1432                     net::URLRequestTestJob::test_data_2(),
1433                     net::ERR_INSUFFICIENT_RESOURCES);
1434  CheckSuccessfulRequest(msgs[kMaxRequestsPerProcess + 1],
1435                         net::URLRequestTestJob::test_data_2());
1436  CheckFailedRequest(msgs[kMaxRequestsPerProcess + 2],
1437                     net::URLRequestTestJob::test_data_2(),
1438                     net::ERR_INSUFFICIENT_RESOURCES);
1439}
1440
1441// Tests that we sniff the mime type for a simple request.
1442TEST_F(ResourceDispatcherHostTest, MimeSniffed) {
1443  std::string raw_headers("HTTP/1.1 200 OK\n\n");
1444  std::string response_data("<html><title>Test One</title></html>");
1445  SetResponse(raw_headers, response_data);
1446
1447  HandleScheme("http");
1448  MakeTestRequest(0, 1, GURL("http:bla"));
1449
1450  // Flush all pending requests.
1451  while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1452
1453  // Sorts out all the messages we saw by request.
1454  ResourceIPCAccumulator::ClassifiedMessages msgs;
1455  accum_.GetClassifiedMessages(&msgs);
1456  ASSERT_EQ(1U, msgs.size());
1457
1458  ResourceResponseHead response_head;
1459  GetResponseHead(msgs[0], &response_head);
1460  ASSERT_EQ("text/html", response_head.mime_type);
1461}
1462
1463// Tests that we don't sniff the mime type when the server provides one.
1464TEST_F(ResourceDispatcherHostTest, MimeNotSniffed) {
1465  std::string raw_headers("HTTP/1.1 200 OK\n"
1466                          "Content-type: image/jpeg\n\n");
1467  std::string response_data("<html><title>Test One</title></html>");
1468  SetResponse(raw_headers, response_data);
1469
1470  HandleScheme("http");
1471  MakeTestRequest(0, 1, GURL("http:bla"));
1472
1473  // Flush all pending requests.
1474  while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1475
1476  // Sorts out all the messages we saw by request.
1477  ResourceIPCAccumulator::ClassifiedMessages msgs;
1478  accum_.GetClassifiedMessages(&msgs);
1479  ASSERT_EQ(1U, msgs.size());
1480
1481  ResourceResponseHead response_head;
1482  GetResponseHead(msgs[0], &response_head);
1483  ASSERT_EQ("image/jpeg", response_head.mime_type);
1484}
1485
1486// Tests that we don't sniff the mime type when there is no message body.
1487TEST_F(ResourceDispatcherHostTest, MimeNotSniffed2) {
1488  SetResponse("HTTP/1.1 304 Not Modified\n\n");
1489
1490  HandleScheme("http");
1491  MakeTestRequest(0, 1, GURL("http:bla"));
1492
1493  // Flush all pending requests.
1494  while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1495
1496  // Sorts out all the messages we saw by request.
1497  ResourceIPCAccumulator::ClassifiedMessages msgs;
1498  accum_.GetClassifiedMessages(&msgs);
1499  ASSERT_EQ(1U, msgs.size());
1500
1501  ResourceResponseHead response_head;
1502  GetResponseHead(msgs[0], &response_head);
1503  ASSERT_EQ("", response_head.mime_type);
1504}
1505
1506TEST_F(ResourceDispatcherHostTest, MimeSniff204) {
1507  SetResponse("HTTP/1.1 204 No Content\n\n");
1508
1509  HandleScheme("http");
1510  MakeTestRequest(0, 1, GURL("http:bla"));
1511
1512  // Flush all pending requests.
1513  while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1514
1515  // Sorts out all the messages we saw by request.
1516  ResourceIPCAccumulator::ClassifiedMessages msgs;
1517  accum_.GetClassifiedMessages(&msgs);
1518  ASSERT_EQ(1U, msgs.size());
1519
1520  ResourceResponseHead response_head;
1521  GetResponseHead(msgs[0], &response_head);
1522  ASSERT_EQ("text/plain", response_head.mime_type);
1523}
1524
1525TEST_F(ResourceDispatcherHostTest, MimeSniffEmpty) {
1526  SetResponse("HTTP/1.1 200 OK\n\n");
1527
1528  HandleScheme("http");
1529  MakeTestRequest(0, 1, GURL("http:bla"));
1530
1531  // Flush all pending requests.
1532  while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1533
1534  // Sorts out all the messages we saw by request.
1535  ResourceIPCAccumulator::ClassifiedMessages msgs;
1536  accum_.GetClassifiedMessages(&msgs);
1537  ASSERT_EQ(1U, msgs.size());
1538
1539  ResourceResponseHead response_head;
1540  GetResponseHead(msgs[0], &response_head);
1541  ASSERT_EQ("text/plain", response_head.mime_type);
1542}
1543
1544// Tests for crbug.com/31266 (Non-2xx + application/octet-stream).
1545TEST_F(ResourceDispatcherHostTest, ForbiddenDownload) {
1546  std::string raw_headers("HTTP/1.1 403 Forbidden\n"
1547                          "Content-disposition: attachment; filename=blah\n"
1548                          "Content-type: application/octet-stream\n\n");
1549  std::string response_data("<html><title>Test One</title></html>");
1550  SetResponse(raw_headers, response_data);
1551
1552  // Only MAIN_FRAMEs can trigger a download.
1553  SetResourceType(ResourceType::MAIN_FRAME);
1554
1555  HandleScheme("http");
1556  MakeTestRequest(0, 1, GURL("http:bla"));
1557
1558  // Flush all pending requests.
1559  while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1560
1561  // Sorts out all the messages we saw by request.
1562  ResourceIPCAccumulator::ClassifiedMessages msgs;
1563  accum_.GetClassifiedMessages(&msgs);
1564
1565  // We should have gotten one RequestComplete message.
1566  ASSERT_EQ(1U, msgs[0].size());
1567  EXPECT_EQ(ResourceMsg_RequestComplete::ID, msgs[0][0].type());
1568
1569  // The RequestComplete message should have had the error code of
1570  // ERR_FILE_NOT_FOUND.
1571  int request_id;
1572  int error_code;
1573
1574  PickleIterator iter(msgs[0][0]);
1575  EXPECT_TRUE(IPC::ReadParam(&msgs[0][0], &iter, &request_id));
1576  EXPECT_TRUE(IPC::ReadParam(&msgs[0][0], &iter, &error_code));
1577
1578  EXPECT_EQ(1, request_id);
1579  EXPECT_EQ(net::ERR_FILE_NOT_FOUND, error_code);
1580}
1581
1582// Test for http://crbug.com/76202 .  We don't want to destroy a
1583// download request prematurely when processing a cancellation from
1584// the renderer.
1585TEST_F(ResourceDispatcherHostTest, IgnoreCancelForDownloads) {
1586  EXPECT_EQ(0, host_.pending_requests());
1587
1588  int render_view_id = 0;
1589  int request_id = 1;
1590
1591  std::string raw_headers("HTTP\n"
1592                          "Content-disposition: attachment; filename=foo\n\n");
1593  std::string response_data("01234567890123456789\x01foobar");
1594
1595  // Get past sniffing metrics in the BufferedResourceHandler.  Note that
1596  // if we don't get past the sniffing metrics, the result will be that
1597  // the BufferedResourceHandler won't have figured out that it's a download,
1598  // won't have constructed a DownloadResourceHandler, and and the request
1599  // will be successfully canceled below, failing the test.
1600  response_data.resize(1025, ' ');
1601
1602  SetResponse(raw_headers, response_data);
1603  SetResourceType(ResourceType::MAIN_FRAME);
1604  SetDelayedCompleteJobGeneration(true);
1605  HandleScheme("http");
1606
1607  MakeTestRequest(render_view_id, request_id, GURL("http://example.com/blah"));
1608  // Return some data so that the request is identified as a download
1609  // and the proper resource handlers are created.
1610  EXPECT_TRUE(net::URLRequestTestJob::ProcessOnePendingMessage());
1611
1612  // And now simulate a cancellation coming from the renderer.
1613  ResourceHostMsg_CancelRequest msg(filter_->child_id(), request_id);
1614  bool msg_was_ok;
1615  host_.OnMessageReceived(msg, filter_.get(), &msg_was_ok);
1616
1617  // Since the request had already started processing as a download,
1618  // the cancellation above should have been ignored and the request
1619  // should still be alive.
1620  EXPECT_EQ(1, host_.pending_requests());
1621
1622  while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1623}
1624
1625TEST_F(ResourceDispatcherHostTest, CancelRequestsForContext) {
1626  EXPECT_EQ(0, host_.pending_requests());
1627
1628  int render_view_id = 0;
1629  int request_id = 1;
1630
1631  std::string raw_headers("HTTP\n"
1632                          "Content-disposition: attachment; filename=foo\n\n");
1633  std::string response_data("01234567890123456789\x01foobar");
1634  // Get past sniffing metrics.
1635  response_data.resize(1025, ' ');
1636
1637  SetResponse(raw_headers, response_data);
1638  SetResourceType(ResourceType::MAIN_FRAME);
1639  SetDelayedCompleteJobGeneration(true);
1640  HandleScheme("http");
1641
1642  MakeTestRequest(render_view_id, request_id, GURL("http://example.com/blah"));
1643  // Return some data so that the request is identified as a download
1644  // and the proper resource handlers are created.
1645  EXPECT_TRUE(net::URLRequestTestJob::ProcessOnePendingMessage());
1646
1647  // And now simulate a cancellation coming from the renderer.
1648  ResourceHostMsg_CancelRequest msg(filter_->child_id(), request_id);
1649  bool msg_was_ok;
1650  host_.OnMessageReceived(msg, filter_.get(), &msg_was_ok);
1651
1652  // Since the request had already started processing as a download,
1653  // the cancellation above should have been ignored and the request
1654  // should still be alive.
1655  EXPECT_EQ(1, host_.pending_requests());
1656
1657  // Cancelling by other methods shouldn't work either.
1658  host_.CancelRequestsForProcess(render_view_id);
1659  EXPECT_EQ(1, host_.pending_requests());
1660
1661  // Cancelling by context should work.
1662  host_.CancelRequestsForContext(filter_->resource_context());
1663  EXPECT_EQ(0, host_.pending_requests());
1664}
1665
1666// Test the cancelling of requests that are being transferred to a new renderer
1667// due to a redirection.
1668TEST_F(ResourceDispatcherHostTest, CancelRequestsForContextTransferred) {
1669  EXPECT_EQ(0, host_.pending_requests());
1670
1671  int render_view_id = 0;
1672  int request_id = 1;
1673
1674  std::string raw_headers("HTTP/1.1 200 OK\n"
1675                          "Content-Type: text/html; charset=utf-8\n\n");
1676  std::string response_data("<html>foobar</html>");
1677
1678  SetResponse(raw_headers, response_data);
1679  SetResourceType(ResourceType::MAIN_FRAME);
1680  HandleScheme("http");
1681
1682  MakeTestRequest(render_view_id, request_id, GURL("http://example.com/blah"));
1683
1684  GlobalRequestID global_request_id(filter_->child_id(), request_id);
1685  host_.MarkAsTransferredNavigation(global_request_id);
1686
1687  // And now simulate a cancellation coming from the renderer.
1688  ResourceHostMsg_CancelRequest msg(filter_->child_id(), request_id);
1689  bool msg_was_ok;
1690  host_.OnMessageReceived(msg, filter_.get(), &msg_was_ok);
1691
1692  // Since the request is marked as being transferred,
1693  // the cancellation above should have been ignored and the request
1694  // should still be alive.
1695  EXPECT_EQ(1, host_.pending_requests());
1696
1697  // Cancelling by other methods shouldn't work either.
1698  host_.CancelRequestsForProcess(render_view_id);
1699  EXPECT_EQ(1, host_.pending_requests());
1700
1701  // Cancelling by context should work.
1702  host_.CancelRequestsForContext(filter_->resource_context());
1703  EXPECT_EQ(0, host_.pending_requests());
1704}
1705
1706TEST_F(ResourceDispatcherHostTest, TransferNavigation) {
1707  EXPECT_EQ(0, host_.pending_requests());
1708
1709  int render_view_id = 0;
1710  int request_id = 1;
1711
1712  // Configure initial request.
1713  SetResponse("HTTP/1.1 302 Found\n"
1714              "Location: http://other.com/blech\n\n");
1715
1716  SetResourceType(ResourceType::MAIN_FRAME);
1717  HandleScheme("http");
1718
1719  // Temporarily replace ContentBrowserClient with one that will trigger the
1720  // transfer navigation code paths.
1721  TransfersAllNavigationsContentBrowserClient new_client;
1722  ContentBrowserClient* old_client = SetBrowserClientForTesting(&new_client);
1723
1724  MakeTestRequest(render_view_id, request_id, GURL("http://example.com/blah"));
1725
1726  // Restore.
1727  SetBrowserClientForTesting(old_client);
1728
1729  // This second filter is used to emulate a second process.
1730  scoped_refptr<ForwardingFilter> second_filter = new ForwardingFilter(
1731      this, browser_context_->GetResourceContext());
1732
1733  int new_render_view_id = 1;
1734  int new_request_id = 2;
1735
1736  const std::string kResponseBody = "hello world";
1737  SetResponse("HTTP/1.1 200 OK\n"
1738              "Content-Type: text/plain\n\n",
1739              kResponseBody);
1740
1741  ResourceHostMsg_Request request =
1742      CreateResourceRequest("GET", ResourceType::MAIN_FRAME,
1743                            GURL("http://other.com/blech"));
1744  request.transferred_request_child_id = filter_->child_id();
1745  request.transferred_request_request_id = request_id;
1746
1747  // For cleanup.
1748  child_ids_.insert(second_filter->child_id());
1749  ResourceHostMsg_RequestResource transfer_request_msg(
1750      new_render_view_id, new_request_id, request);
1751  bool msg_was_ok;
1752  host_.OnMessageReceived(
1753      transfer_request_msg, second_filter.get(), &msg_was_ok);
1754  base::MessageLoop::current()->RunUntilIdle();
1755
1756  // Flush all the pending requests.
1757  while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1758
1759  // Check generated messages.
1760  ResourceIPCAccumulator::ClassifiedMessages msgs;
1761  accum_.GetClassifiedMessages(&msgs);
1762
1763  ASSERT_EQ(1U, msgs.size());
1764  CheckSuccessfulRequest(msgs[0], kResponseBody);
1765}
1766
1767TEST_F(ResourceDispatcherHostTest, TransferNavigationAndThenRedirect) {
1768  EXPECT_EQ(0, host_.pending_requests());
1769
1770  int render_view_id = 0;
1771  int request_id = 1;
1772
1773  // Configure initial request.
1774  SetResponse("HTTP/1.1 302 Found\n"
1775              "Location: http://other.com/blech\n\n");
1776
1777  SetResourceType(ResourceType::MAIN_FRAME);
1778  HandleScheme("http");
1779
1780  // Temporarily replace ContentBrowserClient with one that will trigger the
1781  // transfer navigation code paths.
1782  TransfersAllNavigationsContentBrowserClient new_client;
1783  ContentBrowserClient* old_client = SetBrowserClientForTesting(&new_client);
1784
1785  MakeTestRequest(render_view_id, request_id, GURL("http://example.com/blah"));
1786
1787  // Restore.
1788  SetBrowserClientForTesting(old_client);
1789
1790  // This second filter is used to emulate a second process.
1791  scoped_refptr<ForwardingFilter> second_filter = new ForwardingFilter(
1792      this, browser_context_->GetResourceContext());
1793
1794  int new_render_view_id = 1;
1795  int new_request_id = 2;
1796
1797  // Delay the start of the next request so that we can setup the response for
1798  // the next URL.
1799  SetDelayedStartJobGeneration(true);
1800
1801  SetResponse("HTTP/1.1 302 Found\n"
1802              "Location: http://other.com/blerg\n\n");
1803
1804  ResourceHostMsg_Request request =
1805      CreateResourceRequest("GET", ResourceType::MAIN_FRAME,
1806                            GURL("http://other.com/blech"));
1807  request.transferred_request_child_id = filter_->child_id();
1808  request.transferred_request_request_id = request_id;
1809
1810  // For cleanup.
1811  child_ids_.insert(second_filter->child_id());
1812  ResourceHostMsg_RequestResource transfer_request_msg(
1813      new_render_view_id, new_request_id, request);
1814  bool msg_was_ok;
1815  host_.OnMessageReceived(
1816      transfer_request_msg, second_filter.get(), &msg_was_ok);
1817  base::MessageLoop::current()->RunUntilIdle();
1818
1819  // Response data for "http://other.com/blerg":
1820  const std::string kResponseBody = "hello world";
1821  SetResponse("HTTP/1.1 200 OK\n"
1822              "Content-Type: text/plain\n\n",
1823              kResponseBody);
1824
1825  // OK, let the redirect happen.
1826  SetDelayedStartJobGeneration(false);
1827  CompleteStartRequest(second_filter.get(), new_request_id);
1828  base::MessageLoop::current()->RunUntilIdle();
1829
1830  // Flush all the pending requests.
1831  while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1832
1833  // Now, simulate the renderer choosing to follow the redirect.
1834  ResourceHostMsg_FollowRedirect redirect_msg(
1835      new_render_view_id, new_request_id, false, GURL());
1836  host_.OnMessageReceived(redirect_msg, second_filter.get(), &msg_was_ok);
1837  base::MessageLoop::current()->RunUntilIdle();
1838
1839  // Flush all the pending requests.
1840  while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1841
1842  // Check generated messages.
1843  ResourceIPCAccumulator::ClassifiedMessages msgs;
1844  accum_.GetClassifiedMessages(&msgs);
1845
1846  ASSERT_EQ(1U, msgs.size());
1847
1848  // We should have received a redirect followed by a "normal" payload.
1849  EXPECT_EQ(ResourceMsg_ReceivedRedirect::ID, msgs[0][0].type());
1850  msgs[0].erase(msgs[0].begin());
1851  CheckSuccessfulRequest(msgs[0], kResponseBody);
1852}
1853
1854TEST_F(ResourceDispatcherHostTest, UnknownURLScheme) {
1855  EXPECT_EQ(0, host_.pending_requests());
1856
1857  SetResourceType(ResourceType::MAIN_FRAME);
1858  HandleScheme("http");
1859
1860  MakeTestRequest(0, 1, GURL("foo://bar"));
1861
1862  // Flush all pending requests.
1863  while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
1864
1865  // Sort all the messages we saw by request.
1866  ResourceIPCAccumulator::ClassifiedMessages msgs;
1867  accum_.GetClassifiedMessages(&msgs);
1868
1869  // We should have gotten one RequestComplete message.
1870  ASSERT_EQ(1U, msgs[0].size());
1871  EXPECT_EQ(ResourceMsg_RequestComplete::ID, msgs[0][0].type());
1872
1873  // The RequestComplete message should have the error code of
1874  // ERR_UNKNOWN_URL_SCHEME.
1875  int request_id;
1876  int error_code;
1877
1878  PickleIterator iter(msgs[0][0]);
1879  EXPECT_TRUE(IPC::ReadParam(&msgs[0][0], &iter, &request_id));
1880  EXPECT_TRUE(IPC::ReadParam(&msgs[0][0], &iter, &error_code));
1881
1882  EXPECT_EQ(1, request_id);
1883  EXPECT_EQ(net::ERR_UNKNOWN_URL_SCHEME, error_code);
1884}
1885
1886TEST_F(ResourceDispatcherHostTest, DataReceivedACKs) {
1887  EXPECT_EQ(0, host_.pending_requests());
1888
1889  SendDataReceivedACKs(true);
1890
1891  HandleScheme("big-job");
1892  MakeTestRequest(0, 1, GURL("big-job:0123456789,1000000"));
1893
1894  // Sort all the messages we saw by request.
1895  ResourceIPCAccumulator::ClassifiedMessages msgs;
1896  accum_.GetClassifiedMessages(&msgs);
1897
1898  size_t size = msgs[0].size();
1899
1900  EXPECT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[0][0].type());
1901  EXPECT_EQ(ResourceMsg_SetDataBuffer::ID, msgs[0][1].type());
1902  for (size_t i = 2; i < size - 1; ++i)
1903    EXPECT_EQ(ResourceMsg_DataReceived::ID, msgs[0][i].type());
1904  EXPECT_EQ(ResourceMsg_RequestComplete::ID, msgs[0][size - 1].type());
1905}
1906
1907TEST_F(ResourceDispatcherHostTest, DelayedDataReceivedACKs) {
1908  EXPECT_EQ(0, host_.pending_requests());
1909
1910  HandleScheme("big-job");
1911  MakeTestRequest(0, 1, GURL("big-job:0123456789,1000000"));
1912
1913  // Sort all the messages we saw by request.
1914  ResourceIPCAccumulator::ClassifiedMessages msgs;
1915  accum_.GetClassifiedMessages(&msgs);
1916
1917  // We expect 1x ReceivedResponse, 1x SetDataBuffer, Nx ReceivedData messages.
1918  EXPECT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[0][0].type());
1919  EXPECT_EQ(ResourceMsg_SetDataBuffer::ID, msgs[0][1].type());
1920  for (size_t i = 2; i < msgs[0].size(); ++i)
1921    EXPECT_EQ(ResourceMsg_DataReceived::ID, msgs[0][i].type());
1922
1923  // NOTE: If we fail the above checks then it means that we probably didn't
1924  // load a big enough response to trigger the delay mechanism we are trying to
1925  // test!
1926
1927  msgs[0].erase(msgs[0].begin());
1928  msgs[0].erase(msgs[0].begin());
1929
1930  // ACK all DataReceived messages until we find a RequestComplete message.
1931  bool complete = false;
1932  while (!complete) {
1933    for (size_t i = 0; i < msgs[0].size(); ++i) {
1934      if (msgs[0][i].type() == ResourceMsg_RequestComplete::ID) {
1935        complete = true;
1936        break;
1937      }
1938
1939      EXPECT_EQ(ResourceMsg_DataReceived::ID, msgs[0][i].type());
1940
1941      ResourceHostMsg_DataReceived_ACK msg(0, 1);
1942      bool msg_was_ok;
1943      host_.OnMessageReceived(msg, filter_.get(), &msg_was_ok);
1944    }
1945
1946    base::MessageLoop::current()->RunUntilIdle();
1947
1948    msgs.clear();
1949    accum_.GetClassifiedMessages(&msgs);
1950  }
1951}
1952
1953// Flakyness of this test might indicate memory corruption issues with
1954// for example the ResourceBuffer of AsyncResourceHandler.
1955TEST_F(ResourceDispatcherHostTest, DataReceivedUnexpectedACKs) {
1956  EXPECT_EQ(0, host_.pending_requests());
1957
1958  HandleScheme("big-job");
1959  MakeTestRequest(0, 1, GURL("big-job:0123456789,1000000"));
1960
1961  // Sort all the messages we saw by request.
1962  ResourceIPCAccumulator::ClassifiedMessages msgs;
1963  accum_.GetClassifiedMessages(&msgs);
1964
1965  // We expect 1x ReceivedResponse, 1x SetDataBuffer, Nx ReceivedData messages.
1966  EXPECT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[0][0].type());
1967  EXPECT_EQ(ResourceMsg_SetDataBuffer::ID, msgs[0][1].type());
1968  for (size_t i = 2; i < msgs[0].size(); ++i)
1969    EXPECT_EQ(ResourceMsg_DataReceived::ID, msgs[0][i].type());
1970
1971  // NOTE: If we fail the above checks then it means that we probably didn't
1972  // load a big enough response to trigger the delay mechanism.
1973
1974  // Send some unexpected ACKs.
1975  for (size_t i = 0; i < 128; ++i) {
1976    ResourceHostMsg_DataReceived_ACK msg(0, 1);
1977    bool msg_was_ok;
1978    host_.OnMessageReceived(msg, filter_.get(), &msg_was_ok);
1979  }
1980
1981  msgs[0].erase(msgs[0].begin());
1982  msgs[0].erase(msgs[0].begin());
1983
1984  // ACK all DataReceived messages until we find a RequestComplete message.
1985  bool complete = false;
1986  while (!complete) {
1987    for (size_t i = 0; i < msgs[0].size(); ++i) {
1988      if (msgs[0][i].type() == ResourceMsg_RequestComplete::ID) {
1989        complete = true;
1990        break;
1991      }
1992
1993      EXPECT_EQ(ResourceMsg_DataReceived::ID, msgs[0][i].type());
1994
1995      ResourceHostMsg_DataReceived_ACK msg(0, 1);
1996      bool msg_was_ok;
1997      host_.OnMessageReceived(msg, filter_.get(), &msg_was_ok);
1998    }
1999
2000    base::MessageLoop::current()->RunUntilIdle();
2001
2002    msgs.clear();
2003    accum_.GetClassifiedMessages(&msgs);
2004  }
2005}
2006
2007}  // namespace content
2008