Commit db972aae authored by Mark Pilgrim's avatar Mark Pilgrim Committed by Commit Bot

Migrate CommonNameMismatchHandler to SimpleURLLoader

Bug: 773295
Change-Id: I51e9af84ff43b34044851f409a7bc4b1877a0ab6
Reviewed-on: https://chromium-review.googlesource.com/1052071
Commit-Queue: Mark Pilgrim <pilgrim@chromium.org>
Reviewed-by: default avatarMatt Menke <mmenke@chromium.org>
Reviewed-by: default avatarRyan Sleevi <rsleevi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#557251}
parent 78ad7b11
......@@ -12,12 +12,17 @@
#include "net/http/http_response_headers.h"
#include "net/http/http_util.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "net/url_request/url_request_status.h"
#include "net/url_request/redirect_info.h"
#include "services/network/public/cpp/resource_request.h"
#include "services/network/public/cpp/resource_response.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
#include "services/network/public/cpp/simple_url_loader.h"
CommonNameMismatchHandler::CommonNameMismatchHandler(
const GURL& request_url,
const scoped_refptr<net::URLRequestContextGetter>& request_context)
: request_url_(request_url), request_context_(request_context) {}
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory)
: request_url_(request_url),
url_loader_factory_(std::move(url_loader_factory)) {}
CommonNameMismatchHandler::~CommonNameMismatchHandler() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
......@@ -38,6 +43,7 @@ void CommonNameMismatchHandler::CheckSuggestedUrl(
DCHECK(!IsCheckingSuggestedUrl());
DCHECK(check_url_callback_.is_null());
check_url_ = url;
check_url_callback_ = callback;
// Create traffic annotation tag.
......@@ -68,19 +74,29 @@ void CommonNameMismatchHandler::CheckSuggestedUrl(
"Not implemented."
})");
url_fetcher_ = net::URLFetcher::Create(url, net::URLFetcher::HEAD, this,
traffic_annotation);
url_fetcher_->SetAutomaticallyRetryOn5xx(false);
url_fetcher_->SetRequestContext(request_context_.get());
auto resource_request = std::make_unique<network::ResourceRequest>();
// Can't safely use net::LOAD_DISABLE_CERT_REVOCATION_CHECKING here,
// since then the connection may be reused without checking the cert.
url_fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SAVE_COOKIES |
net::LOAD_DO_NOT_SEND_COOKIES |
net::LOAD_DO_NOT_SEND_AUTH_DATA);
resource_request->url = check_url_;
resource_request->method = "HEAD";
resource_request->load_flags = net::LOAD_DO_NOT_SAVE_COOKIES |
net::LOAD_DO_NOT_SEND_COOKIES |
net::LOAD_DO_NOT_SEND_AUTH_DATA;
simple_url_loader_ = network::SimpleURLLoader::Create(
std::move(resource_request), traffic_annotation);
// Don't follow redirects to prevent leaking URL data to HTTP sites.
url_fetcher_->SetStopOnRedirect(true);
url_fetcher_->Start();
simple_url_loader_->SetOnRedirectCallback(
base::BindRepeating(&CommonNameMismatchHandler::OnSimpleLoaderRedirect,
base::Unretained(this)));
simple_url_loader_->SetOnResponseStartedCallback(
base::BindOnce(&CommonNameMismatchHandler::OnSimpleLoaderResponseStarted,
base::Unretained(this)));
simple_url_loader_->DownloadToString(
url_loader_factory_.get(),
base::BindOnce(&CommonNameMismatchHandler::OnSimpleLoaderComplete,
base::Unretained(this)),
1 /*max_body_size*/);
}
// static
......@@ -103,36 +119,45 @@ bool CommonNameMismatchHandler::GetSuggestedUrl(
}
void CommonNameMismatchHandler::Cancel() {
url_fetcher_.reset();
simple_url_loader_.reset();
check_url_callback_.Reset();
}
void CommonNameMismatchHandler::OnURLFetchComplete(
const net::URLFetcher* source) {
void CommonNameMismatchHandler::OnSimpleLoaderRedirect(
const net::RedirectInfo& redirect_info,
const network::ResourceResponseHead& response_head) {
OnSimpleLoaderResponseStarted(redirect_info.new_url, response_head);
}
void CommonNameMismatchHandler::OnSimpleLoaderResponseStarted(
const GURL& final_url,
const network::ResourceResponseHead& response_head) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(IsCheckingSuggestedUrl());
DCHECK_EQ(url_fetcher_.get(), source);
DCHECK(!check_url_callback_.is_null());
DCHECK(!url_fetcher_.get()->GetStatus().is_io_pending());
SuggestedUrlCheckResult result = SUGGESTED_URL_NOT_AVAILABLE;
// Save a copy of |suggested_url| so it can be used after |url_fetcher_|
// is destroyed.
const GURL suggested_url = url_fetcher_->GetOriginalURL();
const GURL landing_url = url_fetcher_->GetURL();
// Make sure the |landing_url| is a HTTPS page and returns a proper response
// code.
if (url_fetcher_.get()->GetResponseCode() == 200 &&
landing_url.SchemeIsCryptographic() &&
landing_url.host() != request_url_.host()) {
DCHECK_EQ(landing_url.host(), suggested_url.host());
// Make sure the URL is a HTTPS page and returns a proper response code.
int response_code = -1;
if (response_head.headers) {
response_code = response_head.headers->response_code();
}
if (response_code == 200 && final_url.SchemeIsCryptographic() &&
final_url.host() != request_url_.host()) {
DCHECK_EQ(final_url.host(), final_url.host());
result = SUGGESTED_URL_AVAILABLE;
}
url_fetcher_.reset();
base::ResetAndReturn(&check_url_callback_).Run(result, suggested_url);
simple_url_loader_.reset();
base::ResetAndReturn(&check_url_callback_).Run(result, check_url_);
}
void CommonNameMismatchHandler::OnSimpleLoaderComplete(
std::unique_ptr<std::string> response_body) {
OnSimpleLoaderResponseStarted(simple_url_loader_->GetFinalURL(),
*simple_url_loader_->ResponseInfo());
}
bool CommonNameMismatchHandler::IsCheckingSuggestedUrl() const {
return !!url_fetcher_;
return !!simple_url_loader_;
}
......@@ -10,21 +10,25 @@
#include "base/callback.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_refptr.h"
#include "base/sequence_checker.h"
#include "base/time/time.h"
#include "net/url_request/url_fetcher.h"
#include "net/url_request/url_fetcher_delegate.h"
#include "net/url_request/url_request_context_getter.h"
#include "url/gurl.h"
namespace net {
class URLFetcher;
}
struct RedirectInfo;
} // namespace net
namespace network {
struct ResourceResponseHead;
class SharedURLLoaderFactory;
class SimpleURLLoader;
} // namespace network
// This class handles errors due to common name mismatches
// (|ERR_CERT_COMMON_NAME_INVALID|) and helps remediate them by suggesting
// alternative URLs that may be what the user intended to load.
class CommonNameMismatchHandler : public net::URLFetcherDelegate {
class CommonNameMismatchHandler {
public:
enum SuggestedUrlCheckResult {
// The request succeeds with good response code i.e. URL exists and its
......@@ -46,8 +50,8 @@ class CommonNameMismatchHandler : public net::URLFetcherDelegate {
CommonNameMismatchHandler(
const GURL& request_url,
const scoped_refptr<net::URLRequestContextGetter>& request_context);
~CommonNameMismatchHandler() override;
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory);
~CommonNameMismatchHandler();
// Performs a network request to suggested URL. After completion, runs the
// |callback|.
......@@ -73,17 +77,23 @@ class CommonNameMismatchHandler : public net::URLFetcherDelegate {
void Cancel();
private:
// net::URLFetcherDelegate:
void OnURLFetchComplete(const net::URLFetcher* source) override;
void OnSimpleLoaderRedirect(
const net::RedirectInfo& redirect_info,
const network::ResourceResponseHead& response_head);
void OnSimpleLoaderResponseStarted(
const GURL& final_url,
const network::ResourceResponseHead& response_head);
void OnSimpleLoaderComplete(std::unique_ptr<std::string> response_body);
// Returns true if the check is currently running.
bool IsCheckingSuggestedUrl() const;
static TestingState testing_state_;
const GURL request_url_;
scoped_refptr<net::URLRequestContextGetter> request_context_;
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_;
GURL check_url_;
CheckUrlCallback check_url_callback_;
std::unique_ptr<net::URLFetcher> url_fetcher_;
std::unique_ptr<network::SimpleURLLoader> simple_url_loader_;
SEQUENCE_CHECKER(sequence_checker_);
......
......@@ -36,13 +36,16 @@
#include "components/security_interstitials/core/ssl_error_ui.h"
#include "components/ssl_errors/error_classification.h"
#include "components/ssl_errors/error_info.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/navigation_handle.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_source.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/browser/web_contents.h"
#include "net/base/net_errors.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
#include "third_party/protobuf/src/google/protobuf/io/zero_copy_stream_impl_lite.h"
#if BUILDFLAG(ENABLE_CAPTIVE_PORTAL_DETECTION)
......@@ -508,10 +511,11 @@ bool SSLErrorHandlerDelegateImpl::GetSuggestedUrl(
void SSLErrorHandlerDelegateImpl::CheckSuggestedUrl(
const GURL& suggested_url,
const CommonNameMismatchHandler::CheckUrlCallback& callback) {
scoped_refptr<net::URLRequestContextGetter> request_context(
profile_->GetRequestContext());
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory(
content::BrowserContext::GetDefaultStoragePartition(profile_)
->GetURLLoaderFactoryForBrowserProcess());
common_name_mismatch_handler_.reset(
new CommonNameMismatchHandler(request_url_, request_context));
new CommonNameMismatchHandler(request_url_, url_loader_factory));
common_name_mismatch_handler_->CheckSuggestedUrl(suggested_url, callback);
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment