diff options
Diffstat (limited to 'lib/gitlab/pages/random_domain.rb')
-rw-r--r-- | lib/gitlab/pages/random_domain.rb | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/lib/gitlab/pages/random_domain.rb b/lib/gitlab/pages/random_domain.rb new file mode 100644 index 00000000000..8aa7611c910 --- /dev/null +++ b/lib/gitlab/pages/random_domain.rb @@ -0,0 +1,51 @@ +# frozen_string_literal: true + +module Gitlab + module Pages + class RandomDomain + PROJECT_PATH_LIMIT = 48 + SUBDOMAIN_LABEL_LIMIT = 63 + + def self.generate(project_path:, namespace_path:) + new(project_path: project_path, namespace_path: namespace_path).generate + end + + def initialize(project_path:, namespace_path:) + @project_path = project_path + @namespace_path = namespace_path + end + + # Subdomains have a limit of 63 bytes (https://www.freesoft.org/CIE/RFC/1035/9.htm) + # For this reason we're limiting each part of the unique subdomain + # + # The domain is made up of 3 parts, like: projectpath-namespacepath-randomstring + # - project path: between 1 and 48 chars + # - namespace path: when the project path has less than 48 chars, + # the namespace full path will be used to fill the value up to 48 chars + # - random hexadecimal: to ensure a random value, the domain is then filled + # with a random hexadecimal value to complete 63 chars + def generate + domain = project_path.byteslice(0, PROJECT_PATH_LIMIT) + + # if the project_path has less than PROJECT_PATH_LIMIT chars, + # fill the domain with the parent full_path up to 48 chars like: + # projectpath-namespacepath + if domain.length < PROJECT_PATH_LIMIT + namespace_size = PROJECT_PATH_LIMIT - domain.length - 1 + domain.concat('-', namespace_path.byteslice(0, namespace_size)) + end + + # Complete the domain with random hexadecimal values util it is 63 chars long + # PS.: SecureRandom.hex return an string twice the size passed as argument. + domain.concat('-', SecureRandom.hex(SUBDOMAIN_LABEL_LIMIT - domain.length - 1)) + + # Slugify ensures the format and size (63 chars) of the given string + Gitlab::Utils.slugify(domain) + end + + private + + attr_reader :project_path, :namespace_path + end + end +end |