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