// 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