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