Home | History | Annotate | Download | only in base
      1 // Copyright 2014 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 "net/base/sdch_dictionary_fetcher.h"
      6 
      7 #include "base/bind.h"
      8 #include "base/compiler_specific.h"
      9 #include "base/message_loop/message_loop.h"
     10 #include "net/base/load_flags.h"
     11 #include "net/url_request/url_fetcher.h"
     12 #include "net/url_request/url_request_context_getter.h"
     13 #include "net/url_request/url_request_status.h"
     14 
     15 namespace net {
     16 
     17 SdchDictionaryFetcher::SdchDictionaryFetcher(
     18     SdchManager* manager,
     19     URLRequestContextGetter* context)
     20     : manager_(manager),
     21       weak_factory_(this),
     22       task_is_pending_(false),
     23       context_(context) {
     24   DCHECK(CalledOnValidThread());
     25   DCHECK(manager);
     26 }
     27 
     28 SdchDictionaryFetcher::~SdchDictionaryFetcher() {
     29   DCHECK(CalledOnValidThread());
     30 }
     31 
     32 void SdchDictionaryFetcher::Schedule(const GURL& dictionary_url) {
     33   DCHECK(CalledOnValidThread());
     34 
     35   // Avoid pushing duplicate copy onto queue.  We may fetch this url again later
     36   // and get a different dictionary, but there is no reason to have it in the
     37   // queue twice at one time.
     38   if (!fetch_queue_.empty() && fetch_queue_.back() == dictionary_url) {
     39     SdchManager::SdchErrorRecovery(
     40         SdchManager::DICTIONARY_ALREADY_SCHEDULED_TO_DOWNLOAD);
     41     return;
     42   }
     43   if (attempted_load_.find(dictionary_url) != attempted_load_.end()) {
     44     SdchManager::SdchErrorRecovery(
     45         SdchManager::DICTIONARY_ALREADY_TRIED_TO_DOWNLOAD);
     46     return;
     47   }
     48   attempted_load_.insert(dictionary_url);
     49   fetch_queue_.push(dictionary_url);
     50   ScheduleDelayedRun();
     51 }
     52 
     53 void SdchDictionaryFetcher::Cancel() {
     54   DCHECK(CalledOnValidThread());
     55 
     56   while (!fetch_queue_.empty())
     57     fetch_queue_.pop();
     58   attempted_load_.clear();
     59   weak_factory_.InvalidateWeakPtrs();
     60   current_fetch_.reset(NULL);
     61 }
     62 
     63 void SdchDictionaryFetcher::ScheduleDelayedRun() {
     64   if (fetch_queue_.empty() || current_fetch_.get() || task_is_pending_)
     65     return;
     66   base::MessageLoop::current()->PostDelayedTask(FROM_HERE,
     67       base::Bind(&SdchDictionaryFetcher::StartFetching,
     68                  weak_factory_.GetWeakPtr()),
     69       base::TimeDelta::FromMilliseconds(kMsDelayFromRequestTillDownload));
     70   task_is_pending_ = true;
     71 }
     72 
     73 void SdchDictionaryFetcher::StartFetching() {
     74   DCHECK(CalledOnValidThread());
     75   DCHECK(task_is_pending_);
     76   task_is_pending_ = false;
     77 
     78   // Handle losing the race against Cancel().
     79   if (fetch_queue_.empty())
     80     return;
     81 
     82   DCHECK(context_.get());
     83   current_fetch_.reset(URLFetcher::Create(
     84       fetch_queue_.front(), URLFetcher::GET, this));
     85   fetch_queue_.pop();
     86   current_fetch_->SetRequestContext(context_.get());
     87   current_fetch_->SetLoadFlags(LOAD_DO_NOT_SEND_COOKIES |
     88                                LOAD_DO_NOT_SAVE_COOKIES);
     89   current_fetch_->Start();
     90 }
     91 
     92 void SdchDictionaryFetcher::OnURLFetchComplete(
     93     const URLFetcher* source) {
     94   DCHECK(CalledOnValidThread());
     95   if ((200 == source->GetResponseCode()) &&
     96       (source->GetStatus().status() == URLRequestStatus::SUCCESS)) {
     97     std::string data;
     98     source->GetResponseAsString(&data);
     99     manager_->AddSdchDictionary(data, source->GetURL());
    100   }
    101   current_fetch_.reset(NULL);
    102   ScheduleDelayedRun();
    103 }
    104 
    105 }  // namespace net
    106