Popular sites on the NTP: check that experiment group StartsWith (rather than IS...
[chromium-blink-merge.git] / chrome / browser / ssl / common_name_mismatch_handler.cc
blob941127b7d95d4fda27dbc828fdcc54eb8cd93cd4
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/ssl/common_name_mismatch_handler.h"
7 #include "base/callback_helpers.h"
8 #include "base/logging.h"
9 #include "base/strings/string_number_conversions.h"
10 #include "chrome/browser/ssl/ssl_error_classification.h"
11 #include "net/base/load_flags.h"
12 #include "net/http/http_response_headers.h"
13 #include "net/http/http_util.h"
14 #include "net/url_request/url_request_status.h"
16 CommonNameMismatchHandler::CommonNameMismatchHandler(
17 const GURL& request_url,
18 const scoped_refptr<net::URLRequestContextGetter>& request_context)
19 : request_url_(request_url), request_context_(request_context) {}
21 CommonNameMismatchHandler::~CommonNameMismatchHandler() {}
23 // static
24 CommonNameMismatchHandler::TestingState
25 CommonNameMismatchHandler::testing_state_ = NOT_TESTING;
27 void CommonNameMismatchHandler::CheckSuggestedUrl(
28 const GURL& url,
29 const CheckUrlCallback& callback) {
30 // Should be used only in tests.
31 if (testing_state_ == IGNORE_REQUESTS_FOR_TESTING)
32 return;
34 DCHECK(CalledOnValidThread());
35 DCHECK(!IsCheckingSuggestedUrl());
36 DCHECK(check_url_callback_.is_null());
38 check_url_callback_ = callback;
40 url_fetcher_ = net::URLFetcher::Create(url, net::URLFetcher::HEAD, this);
41 url_fetcher_->SetAutomaticallyRetryOn5xx(false);
42 url_fetcher_->SetRequestContext(request_context_.get());
44 // Can't safely use net::LOAD_DISABLE_CERT_REVOCATION_CHECKING here,
45 // since then the connection may be reused without checking the cert.
46 url_fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SAVE_COOKIES |
47 net::LOAD_DO_NOT_SEND_COOKIES |
48 net::LOAD_DO_NOT_SEND_AUTH_DATA);
49 url_fetcher_->Start();
52 // static
53 bool CommonNameMismatchHandler::GetSuggestedUrl(
54 const GURL& request_url,
55 const std::vector<std::string>& dns_names,
56 GURL* suggested_url) {
57 std::string host_name = request_url.host();
58 std::string www_mismatch_hostname;
59 if (!SSLErrorClassification::GetWWWSubDomainMatch(host_name, dns_names,
60 &www_mismatch_hostname)) {
61 return false;
63 // The full URL should be pinged, not just the new hostname. So, get the
64 // |suggested_url| with the |request_url|'s hostname replaced with
65 // new hostname. Keep resource path, query params the same.
66 GURL::Replacements replacements;
67 replacements.SetHostStr(www_mismatch_hostname);
68 *suggested_url = request_url.ReplaceComponents(replacements);
69 return true;
72 void CommonNameMismatchHandler::Cancel() {
73 url_fetcher_.reset();
74 check_url_callback_.Reset();
77 void CommonNameMismatchHandler::OnURLFetchComplete(
78 const net::URLFetcher* source) {
79 DCHECK(CalledOnValidThread());
80 DCHECK(IsCheckingSuggestedUrl());
81 DCHECK_EQ(url_fetcher_.get(), source);
82 DCHECK(!check_url_callback_.is_null());
83 DCHECK(!url_fetcher_.get()->GetStatus().is_io_pending());
85 SuggestedUrlCheckResult result = SUGGESTED_URL_NOT_AVAILABLE;
86 // Save a copy of |suggested_url| so it can be used after |url_fetcher_|
87 // is destroyed.
88 const GURL suggested_url = url_fetcher_->GetOriginalURL();
89 const GURL& landing_url = url_fetcher_->GetURL();
91 // Make sure the |landing_url| is a HTTPS page and returns a proper response
92 // code.
93 if (url_fetcher_.get()->GetResponseCode() == 200 &&
94 landing_url.SchemeIsCryptographic() &&
95 landing_url.host() != request_url_.host()) {
96 result = SUGGESTED_URL_AVAILABLE;
98 url_fetcher_.reset();
99 base::ResetAndReturn(&check_url_callback_).Run(result, suggested_url);
102 bool CommonNameMismatchHandler::IsCheckingSuggestedUrl() const {
103 return url_fetcher_;