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

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

Issue 6611023: The optional Malware Details also collects HTTP cache information. See design... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 9 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
Index: chrome/browser/safe_browsing/malware_details_cache.cc
===================================================================
--- chrome/browser/safe_browsing/malware_details_cache.cc (revision 0)
+++ chrome/browser/safe_browsing/malware_details_cache.cc (revision 0)
@@ -0,0 +1,200 @@
+// Copyright (c) 2011 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 MalwareDetails class.
+
+#include "chrome/browser/safe_browsing/malware_details.h"
+
+#include "base/callback.h"
+#include "base/lazy_instance.h"
+#include "base/md5.h"
+#include "chrome/browser/net/chrome_url_request_context.h"
+#include "chrome/browser/safe_browsing/malware_details_cache.h"
+#include "chrome/browser/safe_browsing/safe_browsing_service.h"
+#include "chrome/browser/safe_browsing/report.pb.h"
+#include "content/browser/browser_thread.h"
+#include "net/base/load_flags.h"
+#include "net/http/http_response_headers.h"
+#include "net/url_request/url_request_context_getter.h"
+#include "net/url_request/url_request_status.h"
+
+using safe_browsing::ClientMalwareReportRequest;
+
+// Only send small files for now, a better strategy would use the size
+// of the whole report and the user's bandwidth.
+static const uint32 kMaxBodySizeBytes = 1024;
+
+MalwareDetailsCacheCollector::MalwareDetailsCacheCollector()
+ : has_started_(false),
+ current_fetch_(NULL) {
+}
+
+MalwareDetailsCacheCollector::~MalwareDetailsCacheCollector() {
+}
+
+void MalwareDetailsCacheCollector::StartCacheCollection(
+ net::URLRequestContextGetter* request_context_getter,
+ safe_browsing::ResourceMap* resources,
+ bool* result,
+ Task* callback) {
+ // Start the data collection from the HTTP cache. We use a URLFetcher
+ // and set the right flags so we only hit the cache.
+ DVLOG(1) << "Getting cache data for all urls...";
+ request_context_getter_ = request_context_getter;
+ resources_ = resources;
+ resources_it_ = resources_->begin();
+ result_ = result;
+ callback_ = callback;
+ has_started_ = true;
+
+ // Post a task in the message loop, so the callers don't need to
+ // check if we call their callback immediately.
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ NewRunnableMethod(this, &MalwareDetailsCacheCollector::OpenEntry));
+}
+
+bool MalwareDetailsCacheCollector::HasStarted() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ return has_started_;
+}
+
+// Fetch a URL and advance to the next one when done.
+void MalwareDetailsCacheCollector::OpenEntry() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ DVLOG(1) << "OpenEntry";
+
+ if (resources_it_ == resources_->end()) { // We are done.
+ AllDone(true);
+ return;
+ }
+
+ if (!request_context_getter_) {
+ DVLOG(1) << "Missing request context getter";
+ AllDone(false);
+ return;
+ }
+
+ current_fetch_.reset(new URLFetcher(
+ GURL(resources_it_->first),
+ URLFetcher::GET,
+ this));
+ current_fetch_->set_request_context(request_context_getter_);
+ // Only from cache, and don't save cookies.
+ current_fetch_->set_load_flags(net::LOAD_ONLY_FROM_CACHE |
+ net::LOAD_DO_NOT_SAVE_COOKIES);
+ current_fetch_->set_automatically_retry_on_5xx(false); // No retries.
+ current_fetch_->Start(); // OnURLFetchComplete will be called when done.
+}
+
+ClientMalwareReportRequest::Resource* MalwareDetailsCacheCollector::GetResource(
+ const GURL& url) {
+ safe_browsing::ResourceMap::iterator it = resources_->find(url.spec());
+ if (it != resources_->end()) {
+ return it->second.get();
+ }
+ return NULL;
+}
+
+void MalwareDetailsCacheCollector::OnURLFetchComplete(
+ const URLFetcher* source,
+ const GURL& url,
+ const net::URLRequestStatus& status,
+ int response_code,
+ const ResponseCookies& cookies,
+ const std::string& data) {
+ DVLOG(1) << "OnUrlFetchComplete";
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ DCHECK(current_fetch_.get());
+ if (resources_it_->first != url.spec()) {
+ DVLOG(1) << "Mismatching urls (probably a redirect)" <<
+ resources_it_->first << " vs " << url;
+ }
+
+ if (status.status() != net::URLRequestStatus::SUCCESS &&
+ status.os_error() == net::ERR_CACHE_MISS) {
mattm 2011/04/18 02:19:24 do we need a test for status != SUCCESS && os_erro
panayiotis 2011/04/18 17:26:40 Done.
+ // Cache miss, skip this resource.
+ DVLOG(1) << "Cache miss for url: " << url;
+ AdvanceEntry();
+ return;
+ }
+
+ // Set the response headers and body to the right resource, which
+ // might not be the same as the one we asked for.
+ ClientMalwareReportRequest::Resource* resource = GetResource(url);
+ if (!resource) {
+ DVLOG(1) << "Cannot find resource for url:" << url;
+ AdvanceEntry();
+ return;
+ }
+
+ ReadResponse(resource, source);
+ ReadData(resource, data);
+ AdvanceEntry();
+}
+
+void MalwareDetailsCacheCollector::ReadResponse(
+ ClientMalwareReportRequest::Resource* pb_resource,
+ const URLFetcher* source) {
+ DVLOG(1) << "ReadResponse";
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ net::HttpResponseHeaders* headers = source->response_headers();
+ if (!headers) {
+ DVLOG(1) << "Missing response headers.";
+ return;
+ }
+
+ ClientMalwareReportRequest::HTTPResponse* pb_response =
+ pb_resource->mutable_response();
+ pb_response->mutable_firstline()->set_code(headers->response_code());
+ void* iter = NULL;
+ std::string name, value;
+ while (headers->EnumerateHeaderLines(&iter, &name, &value)) {
+ ClientMalwareReportRequest::HTTPHeader* pb_header =
+ pb_response->add_headers();
+ pb_header->set_name(name);
+ // Strip any Set-Cookie headers.
+ if (LowerCaseEqualsASCII(name, "set-cookie")) {
+ pb_header->set_value("");
+ } else {
+ pb_header->set_value(value);
+ }
+ }
+}
+
+void MalwareDetailsCacheCollector::ReadData(
+ ClientMalwareReportRequest::Resource* pb_resource,
+ const std::string& data) {
+ DVLOG(1) << "ReadData";
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ ClientMalwareReportRequest::HTTPResponse* pb_response =
+ pb_resource->mutable_response();
+ if (data.size() <= kMaxBodySizeBytes) { // Only send small bodies for now.
+ pb_response->set_body(data);
+ }
+ pb_response->set_bodylength(data.size());
+ MD5Digest digest;
+ MD5Sum(data.c_str(), data.size(), &digest);
+ pb_response->set_bodydigest(MD5DigestToBase16(digest));
+}
+
+void MalwareDetailsCacheCollector::AdvanceEntry() {
+ DVLOG(1) << "AdvanceEntry";
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ // Advance to the next resource.
+ ++resources_it_;
+ current_fetch_.reset(NULL);
+
+ // Create a task so we don't take over the IO thread for too long.
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ NewRunnableMethod(this, &MalwareDetailsCacheCollector::OpenEntry));
+}
+
+void MalwareDetailsCacheCollector::AllDone(bool success) {
+ DVLOG(1) << "AllDone";
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ *result_ = success;
+ BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, callback_);
+}
Property changes on: chrome/browser/safe_browsing/malware_details_cache.cc
___________________________________________________________________
Added: svn:eol-style
+ LF

Powered by Google App Engine
This is Rietveld 408576698