summaryrefslogtreecommitdiff
path: root/chromium/content/common/url_schemes.cc
blob: 6667cb10b30f9a5bdc657fd0def969345f80a51c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
// 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 GURLs here instead of strings to deal with canonicalization.
std::vector<GURL>* 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);
  for (auto& scheme : schemes.secure_schemes)
    url::AddSecureScheme(scheme.c_str());

  for (auto& scheme : schemes.local_schemes)
    url::AddLocalScheme(scheme.c_str());

  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());

  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<GURL>;
  *secure_origins = std::move(schemes.secure_origins);
}

const std::vector<std::string>& GetSavableSchemes() {
  return *savable_schemes;
}

const std::vector<GURL>& GetSecureOrigins() {
  return *secure_origins;
}

const std::vector<std::string>& GetServiceWorkerSchemes() {
  return *service_worker_schemes;
}

}  // namespace content