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