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