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 16SdchDictionaryFetcher::SdchDictionaryFetcher( 17 net::URLRequestContextGetter* context) 18 : weak_factory_(this), 19 task_is_pending_(false), 20 context_(context) { 21 DCHECK(CalledOnValidThread()); 22} 23 24SdchDictionaryFetcher::~SdchDictionaryFetcher() { 25 DCHECK(CalledOnValidThread()); 26} 27 28// static 29void SdchDictionaryFetcher::Shutdown() { 30 net::SdchManager::Shutdown(); 31} 32 33void 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 54void 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 64void 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 78void 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