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/download/download_resource_throttle.h" 6 7 #include "base/bind.h" 8 #include "chrome/browser/download/download_stats.h" 9 #include "content/public/browser/resource_controller.h" 10 11 DownloadResourceThrottle::DownloadResourceThrottle( 12 DownloadRequestLimiter* limiter, 13 int render_process_id, 14 int render_view_id, 15 int request_id, 16 const std::string& request_method) 17 : querying_limiter_(true), 18 request_allowed_(false), 19 request_deferred_(false) { 20 limiter->CanDownloadOnIOThread( 21 render_process_id, 22 render_view_id, 23 request_id, 24 request_method, 25 base::Bind(&DownloadResourceThrottle::ContinueDownload, 26 AsWeakPtr())); 27 } 28 29 DownloadResourceThrottle::~DownloadResourceThrottle() { 30 } 31 32 void DownloadResourceThrottle::WillStartRequest(bool* defer) { 33 WillDownload(defer); 34 } 35 36 void DownloadResourceThrottle::WillRedirectRequest(const GURL& new_url, 37 bool* defer) { 38 WillDownload(defer); 39 } 40 41 void DownloadResourceThrottle::WillProcessResponse(bool* defer) { 42 WillDownload(defer); 43 } 44 45 void DownloadResourceThrottle::WillDownload(bool* defer) { 46 DCHECK(!request_deferred_); 47 48 // Defer the download until we have the DownloadRequestLimiter result. 49 if (querying_limiter_) { 50 request_deferred_ = true; 51 *defer = true; 52 return; 53 } 54 55 if (!request_allowed_) 56 controller()->Cancel(); 57 } 58 59 void DownloadResourceThrottle::ContinueDownload(bool allow) { 60 querying_limiter_ = false; 61 request_allowed_ = allow; 62 63 if (allow) { 64 // Presumes all downloads initiated by navigation use this throttle and 65 // nothing else does. 66 RecordDownloadSource(DOWNLOAD_INITIATED_BY_NAVIGATION); 67 } else { 68 RecordDownloadCount(CHROME_DOWNLOAD_COUNT_BLOCKED_BY_THROTTLING); 69 } 70 71 if (request_deferred_) { 72 request_deferred_ = false; 73 if (allow) { 74 controller()->Resume(); 75 } else { 76 controller()->Cancel(); 77 } 78 } 79 } 80