| Index: components/safe_browsing/resource_throttle.cc | 
| diff --git a/components/safe_browsing/resource_throttle.cc b/components/safe_browsing/resource_throttle.cc | 
| new file mode 100644 | 
| index 0000000000000000000000000000000000000000..6910f46bf8d4e1e7df32ff3120bdfdd07797e0cc | 
| --- /dev/null | 
| +++ b/components/safe_browsing/resource_throttle.cc | 
| @@ -0,0 +1,110 @@ | 
| +// Copyright (c) 2017 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. | 
| + | 
| +#include "components/safe_browsing/resource_throttle.h" | 
| + | 
| +#include <utility> | 
| + | 
| +#include "components/safe_browsing/base_ui_manager.h" | 
| +#include "components/security_interstitials/content/unsafe_resource.h" | 
| +#include "content/public/browser/browser_thread.h" | 
| +#include "content/public/browser/resource_request_info.h" | 
| +#include "content/public/browser/web_contents.h" | 
| +#include "net/base/load_flags.h" | 
| +#include "net/log/net_log_capture_mode.h" | 
| +#include "net/log/net_log_source.h" | 
| +#include "net/log/net_log_source_type.h" | 
| +#include "net/url_request/redirect_info.h" | 
| +#include "net/url_request/url_request.h" | 
| + | 
| +namespace safe_browsing { | 
| + | 
| +ResourceThrottle::ResourceThrottle( | 
| +    const net::URLRequest* request, | 
| +    content::ResourceType resource_type, | 
| +    scoped_refptr<SafeBrowsingDatabaseManager> database_manager, | 
| +    scoped_refptr<BaseUIManager> ui_manager, | 
| +    std::unique_ptr<ResourceThrottle::Delegate> delegate) | 
| +    : request_checker_(request, | 
| +                       resource_type, | 
| +                       std::move(database_manager), | 
| +                       std::move(ui_manager), | 
| +                       this), | 
| +      delegate_(std::move(delegate)), | 
| +      weak_factory_(this) {} | 
| + | 
| +ResourceThrottle::~ResourceThrottle() {} | 
| + | 
| +void ResourceThrottle::WillStartRequest(bool* defer) { | 
| +  if (request_checker_.CheckNewRequest() == RequestChecker::DEFER) | 
| +    *defer = true; | 
| +} | 
| + | 
| +void ResourceThrottle::WillProcessResponse(bool* defer) { | 
| +  if (request_checker_.ShouldDeferResponse() == RequestChecker::DEFER) | 
| +    *defer = true; | 
| +} | 
| + | 
| +bool ResourceThrottle::MustProcessResponseBeforeReadingBody() { | 
| +  // On Android, SafeBrowsing may only decide to cancel the request when the | 
| +  // response has been received. Therefore, no part of it should be cached | 
| +  // until this ResourceThrottle has been able to check the response. This | 
| +  // prevents the following scenario: | 
| +  //   1) A request is made for foo.com which has been hacked. | 
| +  //   2) The request is only canceled at WillProcessResponse stage, but part of | 
| +  //   it has been cached. | 
| +  //   3) foo.com is no longer hacked and removed from the SafeBrowsing list. | 
| +  //   4) The user requests foo.com, which is not on the SafeBrowsing list. This | 
| +  //   is deemed safe. However, the resource is actually served from cache, | 
| +  //   using the version that was previously stored. | 
| +  //   5) This results in the  user accessing an unsafe resource without being | 
| +  //   notified that it's dangerous. | 
| +  // TODO(clamy): Add a browser test that checks this specific scenario. | 
| +  return true;  // Harmless when OS != Android | 
| +} | 
| + | 
| +void ResourceThrottle::WillRedirectRequest( | 
| +    const net::RedirectInfo& redirect_info, | 
| +    bool* defer) { | 
| +  if (request_checker_.CheckRedirect(redirect_info.new_url) == | 
| +      RequestChecker::DEFER) { | 
| +    *defer = true; | 
| +  } | 
| +} | 
| + | 
| +const char* ResourceThrottle::GetNameForLogging() const { | 
| +  return "safe_browsing::ResourceThrottle"; | 
| +} | 
| + | 
| +void ResourceThrottle::MaybeDestroyPrerenderContents( | 
| +    const content::ResourceRequestInfo::WebContentsGetter& | 
| +        web_contents_getter) { | 
| +  delegate_->MaybeDestroyPrerenderContents(web_contents_getter); | 
| +} | 
| + | 
| +RequestChecker::Delegate::WebContentsGetter | 
| +ResourceThrottle::GetWebContentsGetterForRequest( | 
| +    const net::URLRequest* request) const { | 
| +  const auto* info = content::ResourceRequestInfo::ForRequest(request); | 
| +  DCHECK(info); | 
| +  return info->GetWebContentsGetterForRequest(); | 
| +} | 
| + | 
| +void ResourceThrottle::StartDisplayingBlockingPage( | 
| +    const security_interstitials::UnsafeResource& resource, | 
| +    scoped_refptr<BaseUIManager> ui_manager) { | 
| +  delegate_->StartDisplayingBlockingPage( | 
| +      resource, std::move(ui_manager), | 
| +      base::BindOnce(&ResourceThrottle::Cancel, weak_factory_.GetWeakPtr())); | 
| +} | 
| + | 
| +void ResourceThrottle::CancelResourceLoad() { | 
| +  Cancel(); | 
| +} | 
| + | 
| +void ResourceThrottle::ResumeResourceRequest() { | 
| +  Resume(); | 
| +} | 
| + | 
| +}  // namespace safe_browsing | 
|  |