summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-01-13 15:07:53 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2020-01-13 15:07:53 +0000
commita5ab3467a705b62911feacc3cf627fdbb00aa198 (patch)
tree65143ce13405efccb922fc428624ad57c38b6efa /lib
parenteb30dd6e28f6fc9eb8021d205f6ed84511f001e2 (diff)
downloadgitlab-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.rb2
-rw-r--r--lib/gitlab/email/receiver.rb10
-rw-r--r--lib/gitlab/gitaly_client.rb23
-rw-r--r--lib/gitlab/graphql/authorize/authorize_resource.rb4
-rw-r--r--lib/gitlab/middleware/request_context.rb27
-rw-r--r--lib/gitlab/request_context.rb41
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