OLD | NEW |
---|---|
(Empty) | |
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. | |
4 | |
5 #include "chrome/browser/extensions/blacklist_state_fetcher.h" | |
6 | |
7 #include "base/stl_util.h" | |
8 #include "base/strings/stringprintf.h" | |
9 #include "chrome/browser/browser_process.h" | |
10 #include "chrome/browser/safe_browsing/protocol_manager_helper.h" | |
11 #include "chrome/browser/safe_browsing/safe_browsing_service.h" | |
12 #include "chrome/common/safe_browsing/crx_info.pb.h" | |
13 #include "google_apis/google_api_keys.h" | |
14 #include "net/base/escape.h" | |
15 #include "net/url_request/url_request_context_getter.h" | |
16 #include "net/url_request/url_request_status.h" | |
17 | |
18 using content::BrowserThread; | |
19 | |
20 namespace extensions { | |
21 | |
22 BlacklistStateFetcher::BlacklistStateFetcher() | |
23 : safe_browsing_config_initialized_(false), | |
24 url_fetcher_id_(0) { | |
25 } | |
26 | |
27 BlacklistStateFetcher::~BlacklistStateFetcher() { | |
28 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
29 STLDeleteContainerPairFirstPointers(requests_.begin(), requests_.end()); | |
30 requests_.clear(); | |
31 } | |
32 | |
33 void BlacklistStateFetcher::Request(const std::string& id, | |
34 const RequestCallback& callback) { | |
35 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
36 if (!safe_browsing_config_initialized_) { | |
37 if (g_browser_process && g_browser_process->safe_browsing_service()) { | |
38 SetSafeBrowsingConfig( | |
39 g_browser_process->safe_browsing_service()->GetProtocolConfig()); | |
40 } else { | |
41 // If safe browsing is not initialized, then it is probably turned off | |
42 // completely. | |
43 NOTREACHED(); | |
44 base::MessageLoopProxy::current()->PostTask( | |
45 FROM_HERE, base::Bind(callback, Blacklist::BLACKLISTED_UNKNOWN)); | |
46 return; | |
47 } | |
48 } | |
49 | |
50 bool request_already_sent = ContainsKey(callbacks_, id); | |
51 callbacks_.insert(std::make_pair(id, callback)); | |
52 if (request_already_sent) | |
53 return; | |
54 | |
55 ClientCRXListInfoRequest request; | |
56 | |
57 request.set_id(id); | |
58 std::string request_str; | |
59 request.SerializeToString(&request_str); | |
60 | |
61 GURL request_url = RequestUrl(); | |
62 net::URLFetcher* fetcher = net::URLFetcher::Create(url_fetcher_id_++, | |
63 request_url, | |
64 net::URLFetcher::POST, | |
65 this); | |
66 requests_[fetcher] = id; | |
67 fetcher->SetAutomaticallyRetryOn5xx(false); // Don't retry on error. | |
68 if (g_browser_process && g_browser_process->safe_browsing_service()) { | |
69 // Unless we are in unit test. | |
70 scoped_refptr<net::URLRequestContextGetter> request_context( | |
mattm
2013/12/10 11:09:41
I don't think the intermediate storing in a scoped
Oleg Eterevsky
2013/12/10 17:10:44
Done.
| |
71 g_browser_process->safe_browsing_service()->url_request_context()); | |
72 fetcher->SetRequestContext(request_context.get()); | |
73 } | |
74 fetcher->SetUploadData("application/octet-stream", request_str); | |
75 fetcher->Start(); | |
76 } | |
77 | |
78 void BlacklistStateFetcher::SetSafeBrowsingConfig( | |
79 const SafeBrowsingProtocolConfig& config) { | |
80 safe_browsing_config_ = config; | |
81 safe_browsing_config_initialized_ = true; | |
82 } | |
83 | |
84 GURL BlacklistStateFetcher::RequestUrl() const { | |
85 std::string url = base::StringPrintf( | |
86 "%s/%s?client=%s&appver=%s&pver=2.2", | |
87 safe_browsing_config_.url_prefix.c_str(), | |
88 "clientreport/crx-list-info", | |
89 safe_browsing_config_.client_name.c_str(), | |
90 safe_browsing_config_.version.c_str()); | |
91 std::string api_key = google_apis::GetAPIKey(); | |
92 if (!api_key.empty()) { | |
93 base::StringAppendF(&url, "&key=%s", | |
94 net::EscapeQueryParamValue(api_key, true).c_str()); | |
95 } | |
96 return GURL(url); | |
97 } | |
98 | |
99 void BlacklistStateFetcher::OnURLFetchComplete(const net::URLFetcher* source) { | |
100 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
101 | |
102 std::map<const net::URLFetcher*, std::string>::iterator it = | |
103 requests_.find(source); | |
104 if (it == requests_.end()) { | |
105 NOTREACHED(); | |
106 return; | |
107 } | |
108 | |
109 scoped_ptr<const net::URLFetcher> fetcher; | |
110 | |
111 fetcher.reset(it->first); | |
112 std::string id = it->second; | |
113 requests_.erase(it); | |
114 | |
115 Blacklist::BlacklistState state; | |
116 | |
117 if (source->GetStatus().is_success() && source->GetResponseCode() == 200) { | |
118 std::string data; | |
119 source->GetResponseAsString(&data); | |
120 ClientCRXListInfoResponse response; | |
121 if (response.ParseFromString(data)) { | |
122 state = static_cast<Blacklist::BlacklistState>(response.verdict()); | |
123 } else { | |
124 state = Blacklist::BLACKLISTED_UNKNOWN; | |
125 } | |
126 } else { | |
127 if (source->GetStatus().status() == net::URLRequestStatus::FAILED) { | |
128 VLOG(1) << "Blacklist request for: " << id | |
129 << " failed with error: " << source->GetStatus().error(); | |
130 } else { | |
131 VLOG(1) << "Blacklist request for: " << id | |
132 << " failed with error: " << source->GetResponseCode(); | |
133 } | |
134 | |
135 state = Blacklist::BLACKLISTED_UNKNOWN; | |
136 } | |
137 | |
138 std::pair<CallbackMultiMap::iterator, CallbackMultiMap::iterator> range = | |
139 callbacks_.equal_range(id); | |
140 for (CallbackMultiMap::const_iterator callback_it = range.first; | |
141 callback_it != range.second; | |
142 ++callback_it) { | |
143 callback_it->second.Run(state); | |
144 } | |
145 | |
146 callbacks_.erase(range.first, range.second); | |
147 } | |
148 | |
149 } // namespace extensions | |
150 | |
OLD | NEW |