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