diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-01-13 15:07:53 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-01-13 15:07:53 +0000 |
commit | a5ab3467a705b62911feacc3cf627fdbb00aa198 (patch) | |
tree | 65143ce13405efccb922fc428624ad57c38b6efa /lib | |
parent | eb30dd6e28f6fc9eb8021d205f6ed84511f001e2 (diff) | |
download | gitlab-ce-a5ab3467a705b62911feacc3cf627fdbb00aa198.tar.gz |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'lib')
-rw-r--r-- | lib/gitlab/auth/unique_ips_limiter.rb | 2 | ||||
-rw-r--r-- | lib/gitlab/email/receiver.rb | 10 | ||||
-rw-r--r-- | lib/gitlab/gitaly_client.rb | 23 | ||||
-rw-r--r-- | lib/gitlab/graphql/authorize/authorize_resource.rb | 4 | ||||
-rw-r--r-- | lib/gitlab/middleware/request_context.rb | 27 | ||||
-rw-r--r-- | lib/gitlab/request_context.rb | 41 |
6 files changed, 81 insertions, 26 deletions
diff --git a/lib/gitlab/auth/unique_ips_limiter.rb b/lib/gitlab/auth/unique_ips_limiter.rb index 97e78ecf094..74f7fdfc180 100644 --- a/lib/gitlab/auth/unique_ips_limiter.rb +++ b/lib/gitlab/auth/unique_ips_limiter.rb @@ -8,7 +8,7 @@ module Gitlab class << self def limit_user_id!(user_id) if config.unique_ips_limit_enabled - ip = RequestContext.client_ip + ip = RequestContext.instance.client_ip unique_ips = update_and_return_ips_count(user_id, ip) raise TooManyIps.new(user_id, ip, unique_ips) if unique_ips > config.unique_ips_limit_per_user diff --git a/lib/gitlab/email/receiver.rb b/lib/gitlab/email/receiver.rb index 847260b2e0f..f028102da9b 100644 --- a/lib/gitlab/email/receiver.rb +++ b/lib/gitlab/email/receiver.rb @@ -66,7 +66,8 @@ module Gitlab def key_from_additional_headers(mail) find_key_from_references(mail) || - find_key_from_delivered_to_header(mail) + find_key_from_delivered_to_header(mail) || + find_key_from_envelope_to_header(mail) end def ensure_references_array(references) @@ -96,6 +97,13 @@ module Gitlab end end + def find_key_from_envelope_to_header(mail) + Array(mail[:envelope_to]).find do |header| + key = Gitlab::IncomingEmail.key_from_address(header.value) + break key if key + end + end + def ignore_auto_reply!(mail) if auto_submitted?(mail) || auto_replied?(mail) raise AutoGeneratedEmailError diff --git a/lib/gitlab/gitaly_client.rb b/lib/gitlab/gitaly_client.rb index 9636e75aba1..262a1ef653f 100644 --- a/lib/gitlab/gitaly_client.rb +++ b/lib/gitlab/gitaly_client.rb @@ -160,6 +160,7 @@ module Gitlab def self.execute(storage, service, rpc, request, remote_storage:, timeout:) enforce_gitaly_request_limits(:call) + Gitlab::RequestContext.instance.ensure_deadline_not_exceeded! kwargs = request_kwargs(storage, timeout: timeout.to_f, remote_storage: remote_storage) kwargs = yield(kwargs) if block_given? @@ -234,12 +235,28 @@ module Gitlab metadata['gitaly-session-id'] = session_id metadata.merge!(Feature::Gitaly.server_feature_flags) - result = { metadata: metadata } + deadline_info = request_deadline(timeout) + metadata.merge!(deadline_info.slice(:deadline_type)) - result[:deadline] = real_time + timeout if timeout > 0 - result + { metadata: metadata, deadline: deadline_info[:deadline] } end + def self.request_deadline(timeout) + # timeout being 0 means the request is allowed to run indefinitely. + # We can't allow that inside a request, but this won't count towards Gitaly + # error budgets + regular_deadline = real_time.to_i + timeout if timeout > 0 + + return { deadline: regular_deadline } if Sidekiq.server? + return { deadline: regular_deadline } unless Gitlab::RequestContext.instance.request_deadline + + limited_deadline = [regular_deadline, Gitlab::RequestContext.instance.request_deadline].compact.min + limited = limited_deadline < regular_deadline + + { deadline: limited_deadline, deadline_type: limited ? "limited" : "regular" } + end + private_class_method :request_deadline + def self.session_id Gitlab::SafeRequestStore[:gitaly_session_id] ||= SecureRandom.uuid end diff --git a/lib/gitlab/graphql/authorize/authorize_resource.rb b/lib/gitlab/graphql/authorize/authorize_resource.rb index 26e8c53032f..94871498cf8 100644 --- a/lib/gitlab/graphql/authorize/authorize_resource.rb +++ b/lib/gitlab/graphql/authorize/authorize_resource.rb @@ -40,7 +40,7 @@ module Gitlab def authorize!(object) unless authorized_resource?(object) - raise_resource_not_avaiable_error! + raise_resource_not_available_error! end end @@ -63,7 +63,7 @@ module Gitlab end end - def raise_resource_not_avaiable_error! + def raise_resource_not_available_error! raise Gitlab::Graphql::Errors::ResourceNotAvailable, RESOURCE_ACCESS_ERROR end end diff --git a/lib/gitlab/middleware/request_context.rb b/lib/gitlab/middleware/request_context.rb new file mode 100644 index 00000000000..953423b371c --- /dev/null +++ b/lib/gitlab/middleware/request_context.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +module Gitlab + module Middleware + class RequestContext + def initialize(app) + @app = app + end + + def call(env) + # We should be using ActionDispatch::Request instead of + # Rack::Request to be consistent with Rails, but due to a Rails + # bug described in + # https://gitlab.com/gitlab-org/gitlab-foss/issues/58573#note_149799010 + # hosts behind a load balancer will only see 127.0.0.1 for the + # load balancer's IP. + req = Rack::Request.new(env) + + Gitlab::RequestContext.instance.client_ip = req.ip + Gitlab::RequestContext.instance.start_thread_cpu_time = Gitlab::Metrics::System.thread_cpu_time + Gitlab::RequestContext.instance.request_start_time = Gitlab::Metrics::System.real_time + + @app.call(env) + end + end + end +end diff --git a/lib/gitlab/request_context.rb b/lib/gitlab/request_context.rb index 13187836e02..49c2c0c982c 100644 --- a/lib/gitlab/request_context.rb +++ b/lib/gitlab/request_context.rb @@ -2,34 +2,37 @@ module Gitlab class RequestContext - class << self - def client_ip - Gitlab::SafeRequestStore[:client_ip] - end + include Singleton + + RequestDeadlineExceeded = Class.new(StandardError) + + attr_accessor :client_ip, :start_thread_cpu_time, :request_start_time - def start_thread_cpu_time - Gitlab::SafeRequestStore[:start_thread_cpu_time] + class << self + def instance + Gitlab::SafeRequestStore[:request_context] ||= new end end - def initialize(app) - @app = app + def request_deadline + return unless request_start_time + return unless Feature.enabled?(:request_deadline) + + @request_deadline ||= request_start_time + max_request_duration_seconds end - def call(env) - # We should be using ActionDispatch::Request instead of - # Rack::Request to be consistent with Rails, but due to a Rails - # bug described in - # https://gitlab.com/gitlab-org/gitlab-foss/issues/58573#note_149799010 - # hosts behind a load balancer will only see 127.0.0.1 for the - # load balancer's IP. - req = Rack::Request.new(env) + def ensure_deadline_not_exceeded! + return unless request_deadline + return if Gitlab::Metrics::System.real_time < request_deadline - Gitlab::SafeRequestStore[:client_ip] = req.ip + raise RequestDeadlineExceeded, + "Request takes longer than #{max_request_duration_seconds}" + end - Gitlab::SafeRequestStore[:start_thread_cpu_time] = Gitlab::Metrics::System.thread_cpu_time + private - @app.call(env) + def max_request_duration_seconds + Settings.gitlab.max_request_duration_seconds end end end |