- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / safe_browsing / ping_manager.cc
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/safe_browsing/ping_manager.h"
6
7 #include "base/logging.h"
8 #include "base/stl_util.h"
9 #include "base/strings/string_util.h"
10 #include "base/strings/stringprintf.h"
11 #include "chrome/common/env_vars.h"
12 #include "content/public/browser/browser_thread.h"
13 #include "google_apis/google_api_keys.h"
14 #include "net/base/escape.h"
15 #include "net/base/load_flags.h"
16 #include "net/url_request/url_fetcher.h"
17 #include "net/url_request/url_request_context_getter.h"
18 #include "net/url_request/url_request_status.h"
19
20 using content::BrowserThread;
21
22 // SafeBrowsingPingManager implementation ----------------------------------
23
24 // static
25 SafeBrowsingPingManager* SafeBrowsingPingManager::Create(
26     net::URLRequestContextGetter* request_context_getter,
27     const SafeBrowsingProtocolConfig& config) {
28   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
29   return new SafeBrowsingPingManager(request_context_getter, config);
30 }
31
32 SafeBrowsingPingManager::SafeBrowsingPingManager(
33     net::URLRequestContextGetter* request_context_getter,
34     const SafeBrowsingProtocolConfig& config)
35     : client_name_(config.client_name),
36       request_context_getter_(request_context_getter),
37       url_prefix_(config.url_prefix) {
38   DCHECK(!url_prefix_.empty());
39
40   version_ = SafeBrowsingProtocolManagerHelper::Version();
41 }
42
43 SafeBrowsingPingManager::~SafeBrowsingPingManager() {
44   // Delete in-progress safebrowsing reports (hits and details).
45   STLDeleteContainerPointers(safebrowsing_reports_.begin(),
46                              safebrowsing_reports_.end());
47 }
48
49 // net::URLFetcherDelegate implementation ----------------------------------
50
51 // All SafeBrowsing request responses are handled here.
52 void SafeBrowsingPingManager::OnURLFetchComplete(
53     const net::URLFetcher* source) {
54   Reports::iterator sit = safebrowsing_reports_.find(source);
55   DCHECK(sit != safebrowsing_reports_.end());
56   delete *sit;
57   safebrowsing_reports_.erase(sit);
58 }
59
60 // Sends a SafeBrowsing "hit" for UMA users.
61 void SafeBrowsingPingManager::ReportSafeBrowsingHit(
62     const GURL& malicious_url,
63     const GURL& page_url,
64     const GURL& referrer_url,
65     bool is_subresource,
66     SBThreatType threat_type,
67     const std::string& post_data) {
68   GURL report_url = SafeBrowsingHitUrl(malicious_url, page_url,
69                                        referrer_url, is_subresource,
70                                        threat_type);
71   net::URLFetcher* report = net::URLFetcher::Create(
72       report_url,
73       post_data.empty() ? net::URLFetcher::GET : net::URLFetcher::POST,
74       this);
75   report->SetLoadFlags(net::LOAD_DISABLE_CACHE);
76   report->SetRequestContext(request_context_getter_.get());
77   if (!post_data.empty())
78     report->SetUploadData("text/plain", post_data);
79   safebrowsing_reports_.insert(report);
80   report->Start();
81 }
82
83 // Sends malware details for users who opt-in.
84 void SafeBrowsingPingManager::ReportMalwareDetails(
85     const std::string& report) {
86   GURL report_url = MalwareDetailsUrl();
87   net::URLFetcher* fetcher = net::URLFetcher::Create(
88       report_url, net::URLFetcher::POST, this);
89   fetcher->SetLoadFlags(net::LOAD_DISABLE_CACHE);
90   fetcher->SetRequestContext(request_context_getter_.get());
91   fetcher->SetUploadData("application/octet-stream", report);
92   // Don't try too hard to send reports on failures.
93   fetcher->SetAutomaticallyRetryOn5xx(false);
94   fetcher->Start();
95   safebrowsing_reports_.insert(fetcher);
96 }
97
98 GURL SafeBrowsingPingManager::SafeBrowsingHitUrl(
99     const GURL& malicious_url, const GURL& page_url,
100     const GURL& referrer_url, bool is_subresource,
101     SBThreatType threat_type) const {
102   DCHECK(threat_type == SB_THREAT_TYPE_URL_MALWARE ||
103          threat_type == SB_THREAT_TYPE_URL_PHISHING ||
104          threat_type == SB_THREAT_TYPE_BINARY_MALWARE_URL ||
105          threat_type == SB_THREAT_TYPE_BINARY_MALWARE_HASH ||
106          threat_type == SB_THREAT_TYPE_CLIENT_SIDE_PHISHING_URL ||
107          threat_type == SB_THREAT_TYPE_CLIENT_SIDE_MALWARE_URL);
108   std::string url = SafeBrowsingProtocolManagerHelper::ComposeUrl(
109       url_prefix_, "report", client_name_, version_, std::string());
110   std::string threat_list = "none";
111   switch (threat_type) {
112     case SB_THREAT_TYPE_URL_MALWARE:
113       threat_list = "malblhit";
114       break;
115     case SB_THREAT_TYPE_URL_PHISHING:
116       threat_list = "phishblhit";
117       break;
118     case SB_THREAT_TYPE_BINARY_MALWARE_URL:
119       threat_list = "binurlhit";
120       break;
121     case SB_THREAT_TYPE_BINARY_MALWARE_HASH:
122       threat_list = "binhashhit";
123       break;
124     case SB_THREAT_TYPE_CLIENT_SIDE_PHISHING_URL:
125       threat_list = "phishcsdhit";
126       break;
127     case SB_THREAT_TYPE_CLIENT_SIDE_MALWARE_URL:
128       threat_list = "malcsdhit";
129       break;
130     default:
131       NOTREACHED();
132   }
133   return GURL(base::StringPrintf("%s&evts=%s&evtd=%s&evtr=%s&evhr=%s&evtb=%d",
134       url.c_str(), threat_list.c_str(),
135       net::EscapeQueryParamValue(malicious_url.spec(), true).c_str(),
136       net::EscapeQueryParamValue(page_url.spec(), true).c_str(),
137       net::EscapeQueryParamValue(referrer_url.spec(), true).c_str(),
138       is_subresource));
139 }
140
141 GURL SafeBrowsingPingManager::MalwareDetailsUrl() const {
142   std::string url = base::StringPrintf(
143           "%s/clientreport/malware?client=%s&appver=%s&pver=1.0",
144           url_prefix_.c_str(),
145           client_name_.c_str(),
146           version_.c_str());
147   std::string api_key = google_apis::GetAPIKey();
148   if (!api_key.empty()) {
149     base::StringAppendF(&url, "&key=%s",
150                         net::EscapeQueryParamValue(api_key, true).c_str());
151   }
152   return GURL(url);
153 }