| Index: chrome/renderer/safe_browsing/safe_browsing_url_loader_throttle.cc
 | 
| diff --git a/chrome/renderer/safe_browsing/safe_browsing_url_loader_throttle.cc b/chrome/renderer/safe_browsing/safe_browsing_url_loader_throttle.cc
 | 
| new file mode 100644
 | 
| index 0000000000000000000000000000000000000000..514acc9198f45cfeeb0716b0dfeeaeee7f07e9b8
 | 
| --- /dev/null
 | 
| +++ b/chrome/renderer/safe_browsing/safe_browsing_url_loader_throttle.cc
 | 
| @@ -0,0 +1,104 @@
 | 
| +// Copyright 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 "chrome/renderer/safe_browsing/safe_browsing_url_loader_throttle.h"
 | 
| +
 | 
| +#include "base/logging.h"
 | 
| +#include "mojo/public/cpp/bindings/interface_request.h"
 | 
| +#include "net/url_request/redirect_info.h"
 | 
| +
 | 
| +namespace safe_browsing {
 | 
| +
 | 
| +SafeBrowsingURLLoaderThrottle::SafeBrowsingURLLoaderThrottle(
 | 
| +    chrome::mojom::SafeBrowsing* safe_browsing,
 | 
| +    int render_frame_id)
 | 
| +    : safe_browsing_(safe_browsing),
 | 
| +      render_frame_id_(render_frame_id),
 | 
| +      weak_factory_(this) {}
 | 
| +
 | 
| +SafeBrowsingURLLoaderThrottle::~SafeBrowsingURLLoaderThrottle() = default;
 | 
| +
 | 
| +void SafeBrowsingURLLoaderThrottle::WillStartRequest(
 | 
| +    const GURL& url,
 | 
| +    int load_flags,
 | 
| +    content::ResourceType resource_type,
 | 
| +    bool* defer) {
 | 
| +  DCHECK_EQ(0u, pending_checks_);
 | 
| +  DCHECK(!blocked_);
 | 
| +  DCHECK(!url_checker_);
 | 
| +
 | 
| +  pending_checks_++;
 | 
| +  // Use a weak pointer to self because |safe_browsing_| is not owned by this
 | 
| +  // object.
 | 
| +  safe_browsing_->CreateCheckerAndCheck(
 | 
| +      render_frame_id_, mojo::MakeRequest(&url_checker_), url, load_flags,
 | 
| +      resource_type,
 | 
| +      base::BindOnce(&SafeBrowsingURLLoaderThrottle::OnCheckUrlResult,
 | 
| +                     weak_factory_.GetWeakPtr()));
 | 
| +  safe_browsing_ = nullptr;
 | 
| +
 | 
| +  url_checker_.set_connection_error_handler(
 | 
| +      base::Bind(&SafeBrowsingURLLoaderThrottle::OnConnectionError,
 | 
| +                 base::Unretained(this)));
 | 
| +}
 | 
| +
 | 
| +void SafeBrowsingURLLoaderThrottle::WillRedirectRequest(
 | 
| +    const net::RedirectInfo& redirect_info,
 | 
| +    bool* defer) {
 | 
| +  // If |blocked_| is true, the resource load has been canceled and there
 | 
| +  // shouldn't be such a notification.
 | 
| +  DCHECK(!blocked_);
 | 
| +
 | 
| +  if (!url_checker_) {
 | 
| +    DCHECK_EQ(0u, pending_checks_);
 | 
| +    return;
 | 
| +  }
 | 
| +
 | 
| +  pending_checks_++;
 | 
| +  url_checker_->CheckUrl(
 | 
| +      redirect_info.new_url,
 | 
| +      base::BindOnce(&SafeBrowsingURLLoaderThrottle::OnCheckUrlResult,
 | 
| +                     base::Unretained(this)));
 | 
| +}
 | 
| +
 | 
| +void SafeBrowsingURLLoaderThrottle::WillProcessResponse(bool* defer) {
 | 
| +  // If |blocked_| is true, the resource load has been canceled and there
 | 
| +  // shouldn't be such a notification.
 | 
| +  DCHECK(!blocked_);
 | 
| +
 | 
| +  if (pending_checks_ > 0)
 | 
| +    *defer = true;
 | 
| +}
 | 
| +
 | 
| +void SafeBrowsingURLLoaderThrottle::OnCheckUrlResult(bool safe) {
 | 
| +  if (blocked_ || !url_checker_)
 | 
| +    return;
 | 
| +
 | 
| +  DCHECK_LT(0u, pending_checks_);
 | 
| +  pending_checks_--;
 | 
| +
 | 
| +  if (safe) {
 | 
| +    if (pending_checks_ == 0) {
 | 
| +      // The resource load is not necessarily deferred, in that case Resume() is
 | 
| +      // a no-op.
 | 
| +      delegate_->Resume();
 | 
| +    }
 | 
| +  } else {
 | 
| +    url_checker_.reset();
 | 
| +    blocked_ = true;
 | 
| +    pending_checks_ = 0;
 | 
| +    delegate_->CancelWithError(net::ERR_ABORTED);
 | 
| +  }
 | 
| +}
 | 
| +
 | 
| +void SafeBrowsingURLLoaderThrottle::OnConnectionError() {
 | 
| +  DCHECK(!blocked_);
 | 
| +
 | 
| +  // If a service-side disconnect happens, treat all URLs as if they are safe.
 | 
| +  url_checker_.reset();
 | 
| +  pending_checks_ = 0;
 | 
| +  delegate_->Resume();
 | 
| +}
 | 
| +
 | 
| +}  // namespace safe_browsing
 | 
| 
 |