Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(145)

Unified Diff: chrome/browser/safe_browsing/threat_details.cc

Issue 2836103002: Componentize safe_browsing: move threat_details* to component. (Closed)
Patch Set: fix spelling and typos Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/browser/safe_browsing/threat_details.h ('k') | chrome/browser/safe_browsing/threat_details_cache.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/safe_browsing/threat_details.cc
diff --git a/chrome/browser/safe_browsing/threat_details.cc b/chrome/browser/safe_browsing/threat_details.cc
deleted file mode 100644
index 891651613248dd4c6fbdeb9902b93093edb83cfc..0000000000000000000000000000000000000000
--- a/chrome/browser/safe_browsing/threat_details.cc
+++ /dev/null
@@ -1,602 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-// Implementation of the ThreatDetails class.
-
-#include "chrome/browser/safe_browsing/threat_details.h"
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include "base/bind.h"
-#include "base/lazy_instance.h"
-#include "base/metrics/histogram_macros.h"
-#include "base/strings/string_util.h"
-#include "chrome/browser/safe_browsing/threat_details_cache.h"
-#include "chrome/browser/safe_browsing/threat_details_history.h"
-#include "components/history/core/browser/history_service.h"
-#include "components/safe_browsing/base_ui_manager.h"
-#include "components/safe_browsing/common/safebrowsing_messages.h"
-#include "content/public/browser/browser_thread.h"
-#include "content/public/browser/navigation_controller.h"
-#include "content/public/browser/navigation_entry.h"
-#include "content/public/browser/render_frame_host.h"
-#include "content/public/browser/web_contents.h"
-#include "net/url_request/url_request_context_getter.h"
-
-using content::BrowserThread;
-using content::NavigationEntry;
-using content::RenderFrameHost;
-using content::WebContents;
-
-// Keep in sync with KMaxNodes in components/safe_browsing/renderer/
-// threat_dom_details.cc
-static const uint32_t kMaxDomNodes = 500;
-
-namespace safe_browsing {
-
-// static
-ThreatDetailsFactory* ThreatDetails::factory_ = NULL;
-
-namespace {
-
-typedef std::unordered_set<std::string> StringSet;
-// A set of HTTPS headers that are allowed to be collected. Contains both
-// request and response headers. All entries in this list should be lower-case
-// to support case-insensitive comparison.
-struct WhitelistedHttpsHeadersTraits
- : base::internal::DestructorAtExitLazyInstanceTraits<StringSet> {
- static StringSet* New(void* instance) {
- StringSet* headers =
- base::internal::DestructorAtExitLazyInstanceTraits<StringSet>::New(
- instance);
- headers->insert({"google-creative-id", "google-lineitem-id", "referer",
- "content-type", "content-length", "date", "server", "cache-control",
- "pragma", "expires"});
- return headers;
- }
-};
-base::LazyInstance<StringSet, WhitelistedHttpsHeadersTraits>
- g_https_headers_whitelist = LAZY_INSTANCE_INITIALIZER;
-
-// Helper function that converts SBThreatType to
-// ClientSafeBrowsingReportRequest::ReportType.
-ClientSafeBrowsingReportRequest::ReportType GetReportTypeFromSBThreatType(
- SBThreatType threat_type) {
- switch (threat_type) {
- case SB_THREAT_TYPE_URL_PHISHING:
- return ClientSafeBrowsingReportRequest::URL_PHISHING;
- case SB_THREAT_TYPE_URL_MALWARE:
- return ClientSafeBrowsingReportRequest::URL_MALWARE;
- case SB_THREAT_TYPE_URL_UNWANTED:
- return ClientSafeBrowsingReportRequest::URL_UNWANTED;
- case SB_THREAT_TYPE_CLIENT_SIDE_PHISHING_URL:
- return ClientSafeBrowsingReportRequest::CLIENT_SIDE_PHISHING_URL;
- case SB_THREAT_TYPE_CLIENT_SIDE_MALWARE_URL:
- return ClientSafeBrowsingReportRequest::CLIENT_SIDE_MALWARE_URL;
- default: // Gated by SafeBrowsingBlockingPage::ShouldReportThreatDetails.
- NOTREACHED() << "We should not send report for threat type "
- << threat_type;
- return ClientSafeBrowsingReportRequest::UNKNOWN;
- }
-}
-
-// Clears the specified HTTPS resource of any sensitive data, only retaining
-// data that is whitelisted for collection.
-void ClearHttpsResource(ClientSafeBrowsingReportRequest::Resource* resource) {
- // Make a copy of the original resource to retain all data.
- ClientSafeBrowsingReportRequest::Resource orig_resource(*resource);
-
- // Clear the request headers and copy over any whitelisted ones.
- resource->clear_request();
- for (int i = 0; i < orig_resource.request().headers_size(); ++i) {
- ClientSafeBrowsingReportRequest::HTTPHeader* orig_header = orig_resource
- .mutable_request()->mutable_headers(i);
- if (g_https_headers_whitelist.Get().count(
- base::ToLowerASCII(orig_header->name())) > 0) {
- resource->mutable_request()->add_headers()->Swap(orig_header);
- }
- }
- // Also copy some other request fields.
- resource->mutable_request()->mutable_bodydigest()->swap(
- *orig_resource.mutable_request()->mutable_bodydigest());
- resource->mutable_request()->set_bodylength(
- orig_resource.request().bodylength());
-
- // ...repeat for response headers.
- resource->clear_response();
- for (int i = 0; i < orig_resource.response().headers_size(); ++i) {
- ClientSafeBrowsingReportRequest::HTTPHeader* orig_header = orig_resource
- .mutable_response()->mutable_headers(i);
- if (g_https_headers_whitelist.Get().count(
- base::ToLowerASCII(orig_header->name())) > 0) {
- resource->mutable_response()->add_headers()->Swap(orig_header);
- }
- }
- // Also copy some other response fields.
- resource->mutable_response()->mutable_bodydigest()->swap(
- *orig_resource.mutable_response()->mutable_bodydigest());
- resource->mutable_response()->set_bodylength(
- orig_resource.response().bodylength());
- resource->mutable_response()->mutable_remote_ip()->swap(
- *orig_resource.mutable_response()->mutable_remote_ip());
-}
-
-std::string GetElementKey(const int frame_tree_node_id,
- const int element_node_id) {
- return base::StringPrintf("%d-%d", frame_tree_node_id, element_node_id);
-}
-
-} // namespace
-
-// The default ThreatDetailsFactory. Global, made a singleton so we
-// don't leak it.
-class ThreatDetailsFactoryImpl : public ThreatDetailsFactory {
- public:
- ThreatDetails* CreateThreatDetails(
- BaseUIManager* ui_manager,
- WebContents* web_contents,
- const security_interstitials::UnsafeResource& unsafe_resource,
- net::URLRequestContextGetter* request_context_getter,
- history::HistoryService* history_service) override {
- return new ThreatDetails(ui_manager, web_contents, unsafe_resource,
- request_context_getter, history_service);
- }
-
- private:
- friend struct base::LazyInstanceTraitsBase<ThreatDetailsFactoryImpl>;
-
- ThreatDetailsFactoryImpl() {}
-
- DISALLOW_COPY_AND_ASSIGN(ThreatDetailsFactoryImpl);
-};
-
-static base::LazyInstance<ThreatDetailsFactoryImpl>::DestructorAtExit
- g_threat_details_factory_impl = LAZY_INSTANCE_INITIALIZER;
-
-// Create a ThreatDetails for the given tab.
-/* static */
-ThreatDetails* ThreatDetails::NewThreatDetails(
- BaseUIManager* ui_manager,
- WebContents* web_contents,
- const UnsafeResource& resource,
- net::URLRequestContextGetter* request_context_getter,
- history::HistoryService* history_service) {
- // Set up the factory if this has not been done already (tests do that
- // before this method is called).
- if (!factory_)
- factory_ = g_threat_details_factory_impl.Pointer();
- return factory_->CreateThreatDetails(ui_manager, web_contents, resource,
- request_context_getter, history_service);
-}
-
-// Create a ThreatDetails for the given tab. Runs in the UI thread.
-ThreatDetails::ThreatDetails(
- BaseUIManager* ui_manager,
- content::WebContents* web_contents,
- const UnsafeResource& resource,
- net::URLRequestContextGetter* request_context_getter,
- history::HistoryService* history_service)
- : content::WebContentsObserver(web_contents),
- request_context_getter_(request_context_getter),
- ui_manager_(ui_manager),
- resource_(resource),
- cache_result_(false),
- did_proceed_(false),
- num_visits_(0),
- ambiguous_dom_(false),
- cache_collector_(new ThreatDetailsCacheCollector) {
- redirects_collector_ = new ThreatDetailsRedirectsCollector(
- history_service ? history_service->AsWeakPtr()
- : base::WeakPtr<history::HistoryService>());
- StartCollection();
-}
-
-ThreatDetails::~ThreatDetails() {}
-
-bool ThreatDetails::OnMessageReceived(const IPC::Message& message,
- RenderFrameHost* render_frame_host) {
- bool handled = true;
- IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(ThreatDetails, message, render_frame_host)
- IPC_MESSAGE_HANDLER(SafeBrowsingHostMsg_ThreatDOMDetails,
- OnReceivedThreatDOMDetails)
- IPC_MESSAGE_UNHANDLED(handled = false)
- IPC_END_MESSAGE_MAP()
- return handled;
-}
-
-bool ThreatDetails::IsReportableUrl(const GURL& url) const {
- // TODO(panayiotis): also skip internal urls.
- return url.SchemeIs("http") || url.SchemeIs("https");
-}
-
-// Looks for a Resource for the given url in resources_. If found, it
-// updates |resource|. Otherwise, it creates a new message, adds it to
-// resources_ and updates |resource| to point to it.
-//
-ClientSafeBrowsingReportRequest::Resource* ThreatDetails::FindOrCreateResource(
- const GURL& url) {
- auto& resource = resources_[url.spec()];
- if (!resource) {
- // Create the resource for |url|.
- int id = resources_.size() - 1;
- std::unique_ptr<ClientSafeBrowsingReportRequest::Resource> new_resource(
- new ClientSafeBrowsingReportRequest::Resource());
- new_resource->set_url(url.spec());
- new_resource->set_id(id);
- resource = std::move(new_resource);
- }
- return resource.get();
-}
-
-HTMLElement* ThreatDetails::FindOrCreateElement(
- const std::string& element_key) {
- auto& element = elements_[element_key];
- if (!element) {
- // Create an entry for this element.
- int element_dom_id = elements_.size() - 1;
- std::unique_ptr<HTMLElement> new_element(new HTMLElement());
- new_element->set_id(element_dom_id);
- element = std::move(new_element);
- }
- return element.get();
-}
-
-ClientSafeBrowsingReportRequest::Resource* ThreatDetails::AddUrl(
- const GURL& url,
- const GURL& parent,
- const std::string& tagname,
- const std::vector<GURL>* children) {
- if (!url.is_valid() || !IsReportableUrl(url))
- return nullptr;
-
- // Find (or create) the resource for the url.
- ClientSafeBrowsingReportRequest::Resource* url_resource =
- FindOrCreateResource(url);
- if (!tagname.empty())
- url_resource->set_tag_name(tagname);
- if (!parent.is_empty() && IsReportableUrl(parent)) {
- // Add the resource for the parent.
- ClientSafeBrowsingReportRequest::Resource* parent_resource =
- FindOrCreateResource(parent);
- // Update the parent-child relation
- url_resource->set_parent_id(parent_resource->id());
- }
- if (children) {
- for (std::vector<GURL>::const_iterator it = children->begin();
- it != children->end(); ++it) {
- // TODO(lpz): Should this first check if the child URL is reportable
- // before creating the resource?
- ClientSafeBrowsingReportRequest::Resource* child_resource =
- FindOrCreateResource(*it);
- bool duplicate_child = false;
- for (auto child_id : url_resource->child_ids()) {
- if (child_id == child_resource->id()) {
- duplicate_child = true;
- break;
- }
- }
- if (!duplicate_child)
- url_resource->add_child_ids(child_resource->id());
- }
- }
-
- return url_resource;
-}
-
-void ThreatDetails::AddDomElement(
- const int frame_tree_node_id,
- const std::string& frame_url,
- const int element_node_id,
- const std::string& tagname,
- const int parent_element_node_id,
- const std::vector<AttributeNameValue>& attributes,
- const ClientSafeBrowsingReportRequest::Resource* resource) {
- // Create the element. It should not exist already since this function should
- // only be called once for each element.
- const std::string element_key =
- GetElementKey(frame_tree_node_id, element_node_id);
- HTMLElement* cur_element = FindOrCreateElement(element_key);
-
- // Set some basic metadata about the element.
- const std::string tag_name_upper = base::ToUpperASCII(tagname);
- if (!tag_name_upper.empty()) {
- cur_element->set_tag(tag_name_upper);
- }
- for (const AttributeNameValue& attribute : attributes) {
- HTMLElement::Attribute* attribute_pb = cur_element->add_attribute();
- attribute_pb->set_name(attribute.first);
- attribute_pb->set_value(attribute.second);
- }
- bool is_frame = tag_name_upper == "IFRAME" || tag_name_upper == "FRAME";
-
- if (resource) {
- cur_element->set_resource_id(resource->id());
-
- // For iframes, remember that this HTML Element represents an iframe with a
- // specific URL. Elements from a frame with this URL are children of this
- // element.
- if (is_frame &&
- !base::ContainsKey(iframe_src_to_element_map_, resource->url())) {
- iframe_src_to_element_map_[resource->url()] = cur_element;
- }
- }
-
- // Next we try to lookup the parent of the current element and add ourselves
- // as a child of it.
- HTMLElement* parent_element = nullptr;
- if (parent_element_node_id == 0) {
- // No parent indicates that this element is at the top of the current frame.
- // This frame could be a child of an iframe in another frame, or it could be
- // at the root of the whole page. If we have a frame URL then we can try to
- // map this element to its parent.
- if (!frame_url.empty()) {
- // First, remember that this element is at the top-level of a frame with
- // our frame URL.
- document_url_to_children_map_[frame_url].insert(cur_element->id());
-
- // Now check if the frame URL matches the src URL of an iframe elsewhere.
- // This means that we processed the parent iframe element earlier, so we
- // can add ourselves as a child of that iframe.
- // If no such iframe exists, it could be processed later, or this element
- // is in the top-level frame and truly has no parent.
- if (base::ContainsKey(iframe_src_to_element_map_, frame_url)) {
- parent_element = iframe_src_to_element_map_[frame_url];
- }
- }
- } else {
- // We have a parent ID, so this element is just a child of something inside
- // of our current frame. We can easily lookup our parent.
- const std::string& parent_key =
- GetElementKey(frame_tree_node_id, parent_element_node_id);
- if (base::ContainsKey(elements_, parent_key)) {
- parent_element = elements_[parent_key].get();
- }
- }
-
- // If a parent element was found, add ourselves as a child, ensuring not to
- // duplicate child IDs.
- if (parent_element) {
- bool duplicate_child = false;
- for (const int child_id : parent_element->child_ids()) {
- if (child_id == cur_element->id()) {
- duplicate_child = true;
- break;
- }
- }
- if (!duplicate_child) {
- parent_element->add_child_ids(cur_element->id());
- }
- }
-
- // Finally, we need to check if the current element is the parent of some
- // other elements that came in from another frame earlier. This only happens
- // if we are an iframe, and our src URL exists in
- // document_url_to_children_map_. If there is a match, then all of the
- // children in that map belong to us.
- if (is_frame && resource &&
- base::ContainsKey(document_url_to_children_map_, resource->url())) {
- const std::unordered_set<int>& child_ids =
- document_url_to_children_map_[resource->url()];
- for (const int child_id : child_ids) {
- cur_element->add_child_ids(child_id);
- }
- }
-}
-
-void ThreatDetails::StartCollection() {
- DVLOG(1) << "Starting to compute threat details.";
- report_.reset(new ClientSafeBrowsingReportRequest());
-
- if (IsReportableUrl(resource_.url)) {
- report_->set_url(resource_.url.spec());
- report_->set_type(GetReportTypeFromSBThreatType(resource_.threat_type));
- }
-
- GURL referrer_url;
- NavigationEntry* nav_entry = resource_.GetNavigationEntryForResource();
- if (nav_entry) {
- GURL page_url = nav_entry->GetURL();
- if (IsReportableUrl(page_url))
- report_->set_page_url(page_url.spec());
-
- referrer_url = nav_entry->GetReferrer().url;
- if (IsReportableUrl(referrer_url))
- report_->set_referrer_url(referrer_url.spec());
-
- // Add the nodes, starting from the page url.
- AddUrl(page_url, GURL(), std::string(), NULL);
- }
-
- // Add the resource_url and its original url, if non-empty and different.
- if (!resource_.original_url.is_empty() &&
- resource_.url != resource_.original_url) {
- // Add original_url, as the parent of resource_url.
- AddUrl(resource_.original_url, GURL(), std::string(), NULL);
- AddUrl(resource_.url, resource_.original_url, std::string(), NULL);
- } else {
- AddUrl(resource_.url, GURL(), std::string(), NULL);
- }
-
- // Add the redirect urls, if non-empty. The redirect urls do not include the
- // original url, but include the unsafe url which is the last one of the
- // redirect urls chain
- GURL parent_url;
- // Set the original url as the parent of the first redirect url if it's not
- // empty.
- if (!resource_.original_url.is_empty())
- parent_url = resource_.original_url;
-
- // Set the previous redirect url as the parent of the next one
- for (size_t i = 0; i < resource_.redirect_urls.size(); ++i) {
- AddUrl(resource_.redirect_urls[i], parent_url, std::string(), NULL);
- parent_url = resource_.redirect_urls[i];
- }
-
- // Add the referrer url.
- if (!referrer_url.is_empty())
- AddUrl(referrer_url, GURL(), std::string(), NULL);
-
- if (!resource_.IsMainPageLoadBlocked()) {
- // Get URLs of frames, scripts etc from the DOM.
- // OnReceivedThreatDOMDetails will be called when the renderer replies.
- // TODO(mattm): In theory, if the user proceeds through the warning DOM
- // detail collection could be started once the page loads.
- web_contents()->SendToAllFrames(
- new SafeBrowsingMsg_GetThreatDOMDetails(MSG_ROUTING_NONE));
- }
-}
-
-// When the renderer is done, this is called.
-void ThreatDetails::OnReceivedThreatDOMDetails(
- content::RenderFrameHost* sender,
- const std::vector<SafeBrowsingHostMsg_ThreatDOMDetails_Node>& params) {
- // Schedule this in IO thread, so it doesn't conflict with future users
- // of our data structures (eg GetSerializedReport).
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- base::BindOnce(&ThreatDetails::AddDOMDetails, this,
- sender->GetFrameTreeNodeId(),
- sender->GetLastCommittedURL(), params));
-}
-
-void ThreatDetails::AddDOMDetails(
- const int frame_tree_node_id,
- const GURL& frame_last_committed_url,
- const std::vector<SafeBrowsingHostMsg_ThreatDOMDetails_Node>& params) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- DVLOG(1) << "Nodes from the DOM: " << params.size();
-
- // If we have already started getting redirects from history service,
- // don't modify state, otherwise will invalidate the iterators.
- if (redirects_collector_->HasStarted())
- return;
-
- // If we have already started collecting data from the HTTP cache, don't
- // modify our state.
- if (cache_collector_->HasStarted())
- return;
-
- // Exit early if there are no nodes to process.
- if (params.empty())
- return;
-
- // Try to deduce the URL that the render frame was handling. First check if
- // the summary node from the renderer has a document URL. If not, try looking
- // at the last committed URL of the frame.
- GURL frame_url;
- if (IsReportableUrl(params.back().url)) {
- frame_url = params.back().url;
- } else if (IsReportableUrl(frame_last_committed_url)) {
- frame_url = frame_last_committed_url;
- }
-
- // If we can't figure out which URL the frame was rendering then we don't know
- // where these elements belong in the hierarchy. The DOM will be ambiguous.
- if (frame_url.is_empty()) {
- ambiguous_dom_ = true;
- }
-
- // Add the urls from the DOM to |resources_|. The renderer could be sending
- // bogus messages, so limit the number of nodes we accept.
- // Also update |elements_| with the DOM structure.
- for (size_t i = 0; i < params.size() && i < kMaxDomNodes; ++i) {
- SafeBrowsingHostMsg_ThreatDOMDetails_Node node = params[i];
- DVLOG(1) << node.url << ", " << node.tag_name << ", " << node.parent;
- ClientSafeBrowsingReportRequest::Resource* resource = nullptr;
- if (!node.url.is_empty()) {
- resource = AddUrl(node.url, node.parent, node.tag_name, &(node.children));
- }
- // Check for a tag_name to avoid adding the summary node to the DOM.
- if (!node.tag_name.empty()) {
- AddDomElement(frame_tree_node_id, frame_url.spec(), node.node_id,
- node.tag_name, node.parent_node_id, node.attributes,
- resource);
- }
- }
-}
-
-// Called from the SB Service on the IO thread, after the user has
-// closed the tab, or clicked proceed or goback. Since the user needs
-// to take an action, we expect this to be called after
-// OnReceivedThreatDOMDetails in most cases. If not, we don't include
-// the DOM data in our report.
-void ThreatDetails::FinishCollection(bool did_proceed, int num_visit) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
-
- did_proceed_ = did_proceed;
- num_visits_ = num_visit;
- std::vector<GURL> urls;
- for (ResourceMap::const_iterator it = resources_.begin();
- it != resources_.end(); ++it) {
- urls.push_back(GURL(it->first));
- }
- redirects_collector_->StartHistoryCollection(
- urls, base::Bind(&ThreatDetails::OnRedirectionCollectionReady, this));
-}
-
-void ThreatDetails::OnRedirectionCollectionReady() {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- const std::vector<RedirectChain>& redirects =
- redirects_collector_->GetCollectedUrls();
-
- for (size_t i = 0; i < redirects.size(); ++i)
- AddRedirectUrlList(redirects[i]);
-
- // Call the cache collector
- cache_collector_->StartCacheCollection(
- request_context_getter_.get(), &resources_, &cache_result_,
- base::Bind(&ThreatDetails::OnCacheCollectionReady, this));
-}
-
-void ThreatDetails::AddRedirectUrlList(const std::vector<GURL>& urls) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- for (size_t i = 0; i < urls.size() - 1; ++i) {
- AddUrl(urls[i], urls[i + 1], std::string(), NULL);
- }
-}
-
-void ThreatDetails::OnCacheCollectionReady() {
- DVLOG(1) << "OnCacheCollectionReady.";
- // Add all the urls in our |resources_| maps to the |report_| protocol buffer.
- for (auto& resource_pair : resources_) {
- ClientSafeBrowsingReportRequest::Resource* pb_resource =
- report_->add_resources();
- pb_resource->Swap(resource_pair.second.get());
- const GURL url(pb_resource->url());
- if (url.SchemeIs("https")) {
- // Sanitize the HTTPS resource by clearing out private data (like cookie
- // headers).
- DVLOG(1) << "Clearing out HTTPS resource: " << pb_resource->url();
- ClearHttpsResource(pb_resource);
- // Keep id, parent_id, child_ids, and tag_name.
- }
- }
- for (auto& element_pair : elements_) {
- report_->add_dom()->Swap(element_pair.second.get());
- }
- if (!elements_.empty()) {
- // TODO(lpz): Consider including the ambiguous_dom_ bit in the report
- // itself.
- UMA_HISTOGRAM_BOOLEAN("SafeBrowsing.ThreatReport.DomIsAmbiguous",
- ambiguous_dom_);
- }
-
- report_->set_did_proceed(did_proceed_);
- // Only sets repeat_visit if num_visits_ >= 0.
- if (num_visits_ >= 0) {
- report_->set_repeat_visit(num_visits_ > 0);
- }
- report_->set_complete(cache_result_);
-
- // Send the report, using the SafeBrowsingService.
- std::string serialized;
- if (!report_->SerializeToString(&serialized)) {
- DLOG(ERROR) << "Unable to serialize the threat report.";
- return;
- }
- ui_manager_->SendSerializedThreatDetails(serialized);
-}
-
-} // namespace safe_browsing
« no previous file with comments | « chrome/browser/safe_browsing/threat_details.h ('k') | chrome/browser/safe_browsing/threat_details_cache.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698