Class: Gitlab::Throttle

Inherits:
Object
  • Object
show all
Defined in:
lib/gitlab/throttle.rb

Constant Summary collapse

DEFAULT_RATE_LIMITING_RESPONSE_TEXT =
'Retry later'
REGULAR_THROTTLES =

Each of these settings follows the same pattern of specifying separate authenticated and unauthenticated rates via settings. New throttles should ideally be regular as well.

[:api, :packages_api, :files_api, :deprecated_api].freeze

Class Method Summary collapse

Class Method Details

.authenticated_web_optionsObject



60
61
62
63
64
65
# File 'lib/gitlab/throttle.rb', line 60

def self.authenticated_web_options
  limit_proc = proc { |req| settings.throttle_authenticated_web_requests_per_period }
  period_proc = proc { |req| settings.throttle_authenticated_web_period_in_seconds.seconds }

  { limit: limit_proc, period: period_proc }
end

.bypass_headerObject



25
26
27
28
29
30
# File 'lib/gitlab/throttle.rb', line 25

def self.bypass_header
  env_value = ENV['GITLAB_THROTTLE_BYPASS_HEADER']
  return unless env_value.present?

  "HTTP_#{env_value.upcase.tr('-', '_')}"
end

.omnibus_protected_paths_present?Boolean

Returns:

  • (Boolean)


21
22
23
# File 'lib/gitlab/throttle.rb', line 21

def self.omnibus_protected_paths_present?
  Rack::Attack.throttles.key?('protected paths')
end

.options(throttle, authenticated:) ⇒ Object



33
34
35
36
37
38
39
40
41
42
# File 'lib/gitlab/throttle.rb', line 33

def options(throttle, authenticated:)
  fragment = throttle_fragment!(throttle, authenticated: authenticated)

  # rubocop:disable GitlabSecurity/PublicSend
  limit_proc = proc { |req| settings.public_send("#{fragment}_requests_per_period") }
  period_proc = proc { |req| settings.public_send("#{fragment}_period_in_seconds").seconds }
  # rubocop:enable GitlabSecurity/PublicSend

  { limit: limit_proc, period: period_proc }
end

.protected_paths_enabled?Boolean

Returns true if we should use the Admin Area protected paths throttle

Returns:

  • (Boolean)


17
18
19
# File 'lib/gitlab/throttle.rb', line 17

def self.protected_paths_enabled?
  self.settings.throttle_protected_paths_enabled?
end

.protected_paths_optionsObject



67
68
69
70
71
72
# File 'lib/gitlab/throttle.rb', line 67

def self.protected_paths_options
  limit_proc = proc { |req| settings.throttle_protected_paths_requests_per_period }
  period_proc = proc { |req| settings.throttle_protected_paths_period_in_seconds.seconds }

  { limit: limit_proc, period: period_proc }
end

.rate_limiting_response_textObject



81
82
83
# File 'lib/gitlab/throttle.rb', line 81

def self.rate_limiting_response_text
  (settings.rate_limiting_response_text.presence || DEFAULT_RATE_LIMITING_RESPONSE_TEXT) + "\n"
end

.settingsObject



12
13
14
# File 'lib/gitlab/throttle.rb', line 12

def self.settings
  Gitlab::CurrentSettings.current_application_settings
end

.throttle_authenticated_git_lfs_optionsObject



74
75
76
77
78
79
# File 'lib/gitlab/throttle.rb', line 74

def self.throttle_authenticated_git_lfs_options
  limit_proc = proc { |req| settings.throttle_authenticated_git_lfs_requests_per_period }
  period_proc = proc { |req| settings.throttle_authenticated_git_lfs_period_in_seconds.seconds }

  { limit: limit_proc, period: period_proc }
end

.throttle_fragment!(throttle, authenticated:) ⇒ Object



44
45
46
47
48
# File 'lib/gitlab/throttle.rb', line 44

def throttle_fragment!(throttle, authenticated:)
  raise("Unknown throttle: #{throttle}") unless REGULAR_THROTTLES.include?(throttle)

  "throttle_#{'un' unless authenticated}authenticated_#{throttle}"
end

.unauthenticated_web_optionsObject



51
52
53
54
55
56
57
58
# File 'lib/gitlab/throttle.rb', line 51

def self.unauthenticated_web_options
  # TODO: Columns will be renamed in https://gitlab.com/gitlab-org/gitlab/-/issues/340031
  # Once this is done, web can be made into a regular throttle
  limit_proc = proc { |req| settings.throttle_unauthenticated_requests_per_period }
  period_proc = proc { |req| settings.throttle_unauthenticated_period_in_seconds.seconds }

  { limit: limit_proc, period: period_proc }
end