Roll src/third_party/WebKit f298044:aa8346d (svn 202628:202629)
[chromium-blink-merge.git] / chrome / browser / extensions / blacklist_state_fetcher.cc
blob4f881ef0a7dac2f49ea66234e786cfea5788f919
1 // Copyright 2013 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.
5 #include "chrome/browser/extensions/blacklist_state_fetcher.h"
7 #include "base/stl_util.h"
8 #include "base/strings/stringprintf.h"
9 #include "base/thread_task_runner_handle.h"
10 #include "chrome/browser/browser_process.h"
11 #include "chrome/browser/safe_browsing/protocol_manager_helper.h"
12 #include "chrome/browser/safe_browsing/safe_browsing_service.h"
13 #include "chrome/common/safe_browsing/crx_info.pb.h"
14 #include "google_apis/google_api_keys.h"
15 #include "net/base/escape.h"
16 #include "net/url_request/url_request_context.h"
17 #include "net/url_request/url_request_context_getter.h"
18 #include "net/url_request/url_request_status.h"
19 #include "url/gurl.h"
21 using content::BrowserThread;
23 namespace extensions {
25 BlacklistStateFetcher::BlacklistStateFetcher()
26 : url_fetcher_id_(0),
27 weak_ptr_factory_(this) {}
29 BlacklistStateFetcher::~BlacklistStateFetcher() {
30 DCHECK_CURRENTLY_ON(BrowserThread::UI);
31 STLDeleteContainerPairFirstPointers(requests_.begin(), requests_.end());
32 requests_.clear();
35 void BlacklistStateFetcher::Request(const std::string& id,
36 const RequestCallback& callback) {
37 DCHECK_CURRENTLY_ON(BrowserThread::UI);
38 if (!safe_browsing_config_) {
39 if (g_browser_process && g_browser_process->safe_browsing_service()) {
40 SetSafeBrowsingConfig(
41 g_browser_process->safe_browsing_service()->GetProtocolConfig());
42 } else {
43 base::ThreadTaskRunnerHandle::Get()->PostTask(
44 FROM_HERE, base::Bind(callback, BLACKLISTED_UNKNOWN));
45 return;
49 bool request_already_sent = ContainsKey(callbacks_, id);
50 callbacks_.insert(std::make_pair(id, callback));
51 if (request_already_sent)
52 return;
54 if (!url_request_context_getter_ && g_browser_process &&
55 g_browser_process->safe_browsing_service()) {
56 url_request_context_getter_ =
57 g_browser_process->safe_browsing_service()->url_request_context();
60 SendRequest(id);
63 void BlacklistStateFetcher::SendRequest(const std::string& id) {
64 DCHECK_CURRENTLY_ON(BrowserThread::UI);
66 ClientCRXListInfoRequest request;
67 request.set_id(id);
68 std::string request_str;
69 request.SerializeToString(&request_str);
71 GURL request_url = RequestUrl();
72 net::URLFetcher* fetcher =
73 net::URLFetcher::Create(url_fetcher_id_++, request_url,
74 net::URLFetcher::POST, this).release();
75 requests_[fetcher] = id;
76 fetcher->SetAutomaticallyRetryOn5xx(false); // Don't retry on error.
77 fetcher->SetRequestContext(url_request_context_getter_.get());
78 fetcher->SetUploadData("application/octet-stream", request_str);
79 fetcher->Start();
82 void BlacklistStateFetcher::SetSafeBrowsingConfig(
83 const SafeBrowsingProtocolConfig& config) {
84 safe_browsing_config_.reset(new SafeBrowsingProtocolConfig(config));
87 void BlacklistStateFetcher::SetURLRequestContextForTest(
88 net::URLRequestContextGetter* request_context) {
89 url_request_context_getter_ = request_context;
92 GURL BlacklistStateFetcher::RequestUrl() const {
93 std::string url = base::StringPrintf(
94 "%s/%s?client=%s&appver=%s&pver=2.2",
95 safe_browsing_config_->url_prefix.c_str(),
96 "clientreport/crx-list-info",
97 safe_browsing_config_->client_name.c_str(),
98 safe_browsing_config_->version.c_str());
99 std::string api_key = google_apis::GetAPIKey();
100 if (!api_key.empty()) {
101 base::StringAppendF(&url, "&key=%s",
102 net::EscapeQueryParamValue(api_key, true).c_str());
104 return GURL(url);
107 void BlacklistStateFetcher::OnURLFetchComplete(const net::URLFetcher* source) {
108 DCHECK_CURRENTLY_ON(BrowserThread::UI);
110 std::map<const net::URLFetcher*, std::string>::iterator it =
111 requests_.find(source);
112 if (it == requests_.end()) {
113 NOTREACHED();
114 return;
117 scoped_ptr<const net::URLFetcher> fetcher;
119 fetcher.reset(it->first);
120 std::string id = it->second;
121 requests_.erase(it);
123 BlacklistState state;
125 if (source->GetStatus().is_success() && source->GetResponseCode() == 200) {
126 std::string data;
127 source->GetResponseAsString(&data);
128 ClientCRXListInfoResponse response;
129 if (response.ParseFromString(data)) {
130 state = static_cast<BlacklistState>(response.verdict());
131 } else {
132 state = BLACKLISTED_UNKNOWN;
134 } else {
135 if (source->GetStatus().status() == net::URLRequestStatus::FAILED) {
136 VLOG(1) << "Blacklist request for: " << id
137 << " failed with error: " << source->GetStatus().error();
138 } else {
139 VLOG(1) << "Blacklist request for: " << id
140 << " failed with error: " << source->GetResponseCode();
143 state = BLACKLISTED_UNKNOWN;
146 std::pair<CallbackMultiMap::iterator, CallbackMultiMap::iterator> range =
147 callbacks_.equal_range(id);
148 for (CallbackMultiMap::const_iterator callback_it = range.first;
149 callback_it != range.second;
150 ++callback_it) {
151 callback_it->second.Run(state);
154 callbacks_.erase(range.first, range.second);
157 } // namespace extensions