chromium/chromecast/browser/general_audience_browsing_navigation_throttle.cc

// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chromecast/browser/general_audience_browsing_navigation_throttle.h"

#include "base/functional/bind.h"
#include "base/logging.h"
#include "chromecast/browser/general_audience_browsing_service.h"
#include "components/url_matcher/url_util.h"
#include "content/public/browser/navigation_handle.h"
#include "url/gurl.h"

namespace chromecast {

GeneralAudienceBrowsingNavigationThrottle::
    GeneralAudienceBrowsingNavigationThrottle(
        content::NavigationHandle* navigation_handle,
        GeneralAudienceBrowsingService* general_audience_browsing_service)
    : NavigationThrottle(navigation_handle),
      general_audience_browsing_service_(general_audience_browsing_service),
      weak_ptr_factory_(this) {
  DCHECK(general_audience_browsing_service_);
}

GeneralAudienceBrowsingNavigationThrottle::
    ~GeneralAudienceBrowsingNavigationThrottle() = default;

content::NavigationThrottle::ThrottleCheckResult
GeneralAudienceBrowsingNavigationThrottle::CheckURL() {
  deferred_ = false;
  const GURL& url = navigation_handle()->GetURL();
  DVLOG(1) << "Check URL " << url.spec();

  // Only apply filters to HTTP[s] URLs.
  if (!url.SchemeIsHTTPOrHTTPS())
    return PROCEED;

  GURL effective_url = url_matcher::util::GetEmbeddedURL(url);
  if (!effective_url.is_valid())
    effective_url = url;
  GURL normalized_url = url_matcher::util::Normalize(effective_url);

  bool synchronous = general_audience_browsing_service_->CheckURL(
      effective_url,
      base::BindOnce(
          &GeneralAudienceBrowsingNavigationThrottle::CheckURLCallback,
          weak_ptr_factory_.GetWeakPtr()));

  if (!synchronous) {
    deferred_ = true;
    return DEFER;
  }

  if (should_cancel_) {
    DVLOG(1) << "Unsafe URL blocked";
    return ThrottleCheckResult(CANCEL, net::ERR_BLOCKED_BY_ADMINISTRATOR);
  }
  return PROCEED;
}

content::NavigationThrottle::ThrottleCheckResult
GeneralAudienceBrowsingNavigationThrottle::WillStartRequest() {
  return CheckURL();
}

content::NavigationThrottle::ThrottleCheckResult
GeneralAudienceBrowsingNavigationThrottle::WillRedirectRequest() {
  return CheckURL();
}

const char* GeneralAudienceBrowsingNavigationThrottle::GetNameForLogging() {
  return "GeneralAudienceBrowsingNavigationThrottle";
}

void GeneralAudienceBrowsingNavigationThrottle::CheckURLCallback(bool is_safe) {
  if (!deferred_) {
    should_cancel_ = !is_safe;
    return;
  }

  deferred_ = false;
  if (is_safe) {
    Resume();
  } else {
    DVLOG(1) << "Unsafe URL blocked";
    CancelDeferredNavigation(
        ThrottleCheckResult(CANCEL, net::ERR_BLOCKED_BY_ADMINISTRATOR));
  }
}

}  // namespace chromecast