blob: c5c80e735c3c9cea69120847dc8eb4a7f4cac98d [file] [log] [blame]
// Copyright (c) 2012 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 "content/common/url_schemes.h"
#include <string.h>
#include <algorithm>
#include "base/strings/string_util.h"
#include "content/public/common/content_client.h"
#include "content/public/common/url_constants.h"
#include "url/url_util.h"
namespace content {
namespace {
// These lists are lazily initialized below and are leaked on shutdown to
// prevent any destructors from being called that will slow us down or cause
// problems.
std::vector<std::string>* savable_schemes = nullptr;
// Note we store url::Origins here instead of strings to deal with
// canonicalization.
std::vector<url::Origin>* secure_origins = nullptr;
std::vector<std::string>* service_worker_schemes = nullptr;
const char* const kDefaultSavableSchemes[] = {
url::kHttpScheme,
url::kHttpsScheme,
url::kFileScheme,
url::kFileSystemScheme,
url::kFtpScheme,
kChromeDevToolsScheme,
kChromeUIScheme,
url::kDataScheme
};
} // namespace
void RegisterContentSchemes(bool lock_schemes) {
ContentClient::Schemes schemes;
GetContentClient()->AddAdditionalSchemes(&schemes);
url::AddStandardScheme(kChromeDevToolsScheme, url::SCHEME_WITHOUT_PORT);
url::AddStandardScheme(kChromeUIScheme, url::SCHEME_WITHOUT_PORT);
url::AddStandardScheme(kGuestScheme, url::SCHEME_WITHOUT_PORT);
for (auto& scheme : schemes.standard_schemes)
url::AddStandardScheme(scheme.c_str(), url::SCHEME_WITHOUT_PORT);
for (auto& scheme : schemes.referrer_schemes)
url::AddReferrerScheme(scheme.c_str(), url::SCHEME_WITHOUT_PORT);
schemes.secure_schemes.push_back(kChromeUIScheme);
schemes.secure_schemes.push_back(kChromeErrorScheme);
for (auto& scheme : schemes.secure_schemes)
url::AddSecureScheme(scheme.c_str());
for (auto& scheme : schemes.local_schemes)
url::AddLocalScheme(scheme.c_str());
schemes.no_access_schemes.push_back(kChromeErrorScheme);
for (auto& scheme : schemes.no_access_schemes)
url::AddNoAccessScheme(scheme.c_str());
schemes.cors_enabled_schemes.push_back(kChromeUIScheme);
for (auto& scheme : schemes.cors_enabled_schemes)
url::AddCORSEnabledScheme(scheme.c_str());
// TODO(mkwst): Investigate whether chrome-error should be included in
// csp_bypassing_schemes.
for (auto& scheme : schemes.csp_bypassing_schemes)
url::AddCSPBypassingScheme(scheme.c_str());
for (auto& scheme : schemes.empty_document_schemes)
url::AddEmptyDocumentScheme(scheme.c_str());
// Prevent future modification of the scheme lists. This is to prevent
// accidental creation of data races in the program. Add*Scheme aren't
// threadsafe so must be called when GURL isn't used on any other thread. This
// is really easy to mess up, so we say that all calls to Add*Scheme in Chrome
// must be inside this function.
if (lock_schemes)
url::LockSchemeRegistries();
// Combine the default savable schemes with the additional ones given.
delete savable_schemes;
savable_schemes = new std::vector<std::string>;
for (auto* default_scheme : kDefaultSavableSchemes)
savable_schemes->push_back(default_scheme);
savable_schemes->insert(savable_schemes->end(),
schemes.savable_schemes.begin(),
schemes.savable_schemes.end());
delete service_worker_schemes;
service_worker_schemes = new std::vector<std::string>;
*service_worker_schemes = std::move(schemes.service_worker_schemes);
delete secure_origins;
secure_origins = new std::vector<url::Origin>;
*secure_origins = std::move(schemes.secure_origins);
}
const std::vector<std::string>& GetSavableSchemes() {
return *savable_schemes;
}
const std::vector<url::Origin>& GetSecureOrigins() {
return *secure_origins;
}
const std::vector<std::string>& GetServiceWorkerSchemes() {
return *service_worker_schemes;
}
} // namespace content