• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "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 
SdchDictionaryFetcher(net::URLRequestContextGetter * context)16 SdchDictionaryFetcher::SdchDictionaryFetcher(
17     net::URLRequestContextGetter* context)
18     : weak_factory_(this),
19       task_is_pending_(false),
20       context_(context) {
21   DCHECK(CalledOnValidThread());
22 }
23 
~SdchDictionaryFetcher()24 SdchDictionaryFetcher::~SdchDictionaryFetcher() {
25   DCHECK(CalledOnValidThread());
26 }
27 
28 // static
Shutdown()29 void SdchDictionaryFetcher::Shutdown() {
30   net::SdchManager::Shutdown();
31 }
32 
Schedule(const GURL & dictionary_url)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 
ScheduleDelayedRun()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 
StartFetching()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 
OnURLFetchComplete(const net::URLFetcher * source)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