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