15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// found in the LICENSE file.
45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/extensions/blacklist_state_fetcher.h"
65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/stl_util.h"
85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/strings/stringprintf.h"
95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/browser_process.h"
105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/safe_browsing/protocol_manager_helper.h"
115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/safe_browsing/safe_browsing_service.h"
125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/common/safe_browsing/crx_info.pb.h"
135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "google_apis/google_api_keys.h"
145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/base/escape.h"
155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/url_request/url_request_context.h"
165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/url_request/url_request_context_getter.h"
175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/url_request/url_request_status.h"
185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "url/gurl.h"
195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using content::BrowserThread;
215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace {
235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class BlacklistRequestContextGetter : public net::URLRequestContextGetter {
255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public:
265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  explicit BlacklistRequestContextGetter(
275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      net::URLRequestContextGetter* parent_context_getter) :
285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          network_task_runner_(
295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)              BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO)) {
30effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    DCHECK_CURRENTLY_ON(BrowserThread::IO);
315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    url_request_context_.reset(new net::URLRequestContext());
325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    url_request_context_->CopyFrom(
335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        parent_context_getter->GetURLRequestContext());
345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  static void Create(
375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      scoped_refptr<net::URLRequestContextGetter> parent_context_getter,
385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Callback<void(scoped_refptr<net::URLRequestContextGetter>)>
395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          callback) {
40effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    DCHECK_CURRENTLY_ON(BrowserThread::IO);
415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    scoped_refptr<net::URLRequestContextGetter> context_getter =
431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        new BlacklistRequestContextGetter(parent_context_getter.get());
445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    BrowserThread::PostTask(BrowserThread::UI,
455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                            FROM_HERE,
465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                            base::Bind(callback, context_getter));
475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual net::URLRequestContext* GetURLRequestContext() OVERRIDE {
50effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    DCHECK_CURRENTLY_ON(BrowserThread::IO);
515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return url_request_context_.get();
525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual scoped_refptr<base::SingleThreadTaskRunner> GetNetworkTaskRunner()
555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      const OVERRIDE {
565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return network_task_runner_;
575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) protected:
605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual ~BlacklistRequestContextGetter() {
615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    url_request_context_->AssertNoURLRequests();
625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private:
655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<net::URLRequestContext> url_request_context_;
665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_refptr<base::SingleThreadTaskRunner> network_task_runner_;
675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace
705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace extensions {
725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)BlacklistStateFetcher::BlacklistStateFetcher()
745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    : url_fetcher_id_(0),
755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      weak_ptr_factory_(this) {}
765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)BlacklistStateFetcher::~BlacklistStateFetcher() {
78effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  DCHECK_CURRENTLY_ON(BrowserThread::UI);
795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  STLDeleteContainerPairFirstPointers(requests_.begin(), requests_.end());
805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  requests_.clear();
815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void BlacklistStateFetcher::Request(const std::string& id,
845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                    const RequestCallback& callback) {
85effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  DCHECK_CURRENTLY_ON(BrowserThread::UI);
865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!safe_browsing_config_) {
875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (g_browser_process && g_browser_process->safe_browsing_service()) {
885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      SetSafeBrowsingConfig(
895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          g_browser_process->safe_browsing_service()->GetProtocolConfig());
905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    } else {
915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::MessageLoopProxy::current()->PostTask(
925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          FROM_HERE, base::Bind(callback, BLACKLISTED_UNKNOWN));
935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return;
945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool request_already_sent = ContainsKey(callbacks_, id);
985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  callbacks_.insert(std::make_pair(id, callback));
995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (request_already_sent)
1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (url_request_context_getter_.get() || !g_browser_process ||
1031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      !g_browser_process->safe_browsing_service()) {
1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    SendRequest(id);
1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  } else {
1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    scoped_refptr<net::URLRequestContextGetter> parent_request_context;
1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (g_browser_process && g_browser_process->safe_browsing_service()) {
1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      parent_request_context = g_browser_process->safe_browsing_service()
1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                                ->url_request_context();
1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    } else {
1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      parent_request_context = parent_request_context_for_test_;
1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    BrowserThread::PostTask(
1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        BrowserThread::IO, FROM_HERE,
1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        base::Bind(&BlacklistRequestContextGetter::Create,
1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                   parent_request_context,
1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                   base::Bind(&BlacklistStateFetcher::SaveRequestContext,
1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                              weak_ptr_factory_.GetWeakPtr(),
1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                              id)));
1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void BlacklistStateFetcher::SaveRequestContext(
1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const std::string& id,
1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    scoped_refptr<net::URLRequestContextGetter> request_context_getter) {
127effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  DCHECK_CURRENTLY_ON(BrowserThread::UI);
1281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!url_request_context_getter_.get())
1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    url_request_context_getter_ = request_context_getter;
1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SendRequest(id);
1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void BlacklistStateFetcher::SendRequest(const std::string& id) {
134effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  DCHECK_CURRENTLY_ON(BrowserThread::UI);
1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ClientCRXListInfoRequest request;
1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  request.set_id(id);
1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string request_str;
1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  request.SerializeToString(&request_str);
1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  GURL request_url = RequestUrl();
1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  net::URLFetcher* fetcher = net::URLFetcher::Create(url_fetcher_id_++,
1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                                     request_url,
1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                                     net::URLFetcher::POST,
1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                                     this);
1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  requests_[fetcher] = id;
1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  fetcher->SetAutomaticallyRetryOn5xx(false);  // Don't retry on error.
1481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  fetcher->SetRequestContext(url_request_context_getter_.get());
1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  fetcher->SetUploadData("application/octet-stream", request_str);
1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  fetcher->Start();
1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void BlacklistStateFetcher::SetSafeBrowsingConfig(
1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const SafeBrowsingProtocolConfig& config) {
1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  safe_browsing_config_.reset(new SafeBrowsingProtocolConfig(config));
1565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void BlacklistStateFetcher::SetURLRequestContextForTest(
1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      net::URLRequestContextGetter* parent_request_context) {
1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  parent_request_context_for_test_ = parent_request_context;
1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)GURL BlacklistStateFetcher::RequestUrl() const {
1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string url = base::StringPrintf(
1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      "%s/%s?client=%s&appver=%s&pver=2.2",
1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      safe_browsing_config_->url_prefix.c_str(),
1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      "clientreport/crx-list-info",
1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      safe_browsing_config_->client_name.c_str(),
1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      safe_browsing_config_->version.c_str());
1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string api_key = google_apis::GetAPIKey();
1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!api_key.empty()) {
1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::StringAppendF(&url, "&key=%s",
1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                        net::EscapeQueryParamValue(api_key, true).c_str());
1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return GURL(url);
1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void BlacklistStateFetcher::OnURLFetchComplete(const net::URLFetcher* source) {
179effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  DCHECK_CURRENTLY_ON(BrowserThread::UI);
1805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::map<const net::URLFetcher*, std::string>::iterator it =
1825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)     requests_.find(source);
1835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (it == requests_.end()) {
1845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    NOTREACHED();
1855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
1865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<const net::URLFetcher> fetcher;
1895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  fetcher.reset(it->first);
1915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string id = it->second;
1925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  requests_.erase(it);
1935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  BlacklistState state;
1955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (source->GetStatus().is_success() && source->GetResponseCode() == 200) {
1975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    std::string data;
1985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    source->GetResponseAsString(&data);
1995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ClientCRXListInfoResponse response;
2005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (response.ParseFromString(data)) {
2015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      state = static_cast<BlacklistState>(response.verdict());
2025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    } else {
2035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      state = BLACKLISTED_UNKNOWN;
2045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
2055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  } else {
2065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (source->GetStatus().status() == net::URLRequestStatus::FAILED) {
2075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      VLOG(1) << "Blacklist request for: " << id
2085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)              << " failed with error: " << source->GetStatus().error();
2095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    } else {
2105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      VLOG(1) << "Blacklist request for: " << id
2115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)              << " failed with error: " << source->GetResponseCode();
2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
2135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    state = BLACKLISTED_UNKNOWN;
2155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
2165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::pair<CallbackMultiMap::iterator, CallbackMultiMap::iterator> range =
2185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      callbacks_.equal_range(id);
2195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (CallbackMultiMap::const_iterator callback_it = range.first;
2205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)       callback_it != range.second;
2215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)       ++callback_it) {
2225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    callback_it->second.Run(state);
2235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
2245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  callbacks_.erase(range.first, range.second);
2265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace extensions
2295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
230