• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
SdchDictionaryFetcher(SdchManager * manager,URLRequestContextGetter * context)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 
~SdchDictionaryFetcher()28 SdchDictionaryFetcher::~SdchDictionaryFetcher() {
29   DCHECK(CalledOnValidThread());
30 }
31 
Schedule(const GURL & dictionary_url)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 
Cancel()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 
ScheduleDelayedRun()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 
StartFetching()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 
OnURLFetchComplete(const URLFetcher * source)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