diff options
Diffstat (limited to 'gems/gitlab-http')
-rw-r--r-- | gems/gitlab-http/.rubocop.yml | 6 | ||||
-rw-r--r-- | gems/gitlab-http/Gemfile.lock | 4 | ||||
-rw-r--r-- | gems/gitlab-http/gitlab-http.gemspec | 4 | ||||
-rw-r--r-- | gems/gitlab-http/lib/gitlab/http_v2/client.rb | 104 | ||||
-rw-r--r-- | gems/gitlab-http/lib/gitlab/http_v2/url_blocker.rb | 8 | ||||
-rw-r--r-- | gems/gitlab-http/lib/net_http/response_patch.rb | 11 | ||||
-rw-r--r-- | gems/gitlab-http/spec/gitlab/http_v2/net_http_patch_spec.rb | 2 |
7 files changed, 72 insertions, 67 deletions
diff --git a/gems/gitlab-http/.rubocop.yml b/gems/gitlab-http/.rubocop.yml index 73ea5f610b3..8bc6b6a4cfb 100644 --- a/gems/gitlab-http/.rubocop.yml +++ b/gems/gitlab-http/.rubocop.yml @@ -1,13 +1,13 @@ inherit_from: - ../config/rubocop.yml +Gemfile/MissingFeatureCategory: + Enabled: false + Naming/ClassAndModuleCamelCase: AllowedNames: - HTTP_V2 -Performance/RegexpMatch: - Enabled: false - Style/SpecialGlobalVars: Enabled: false diff --git a/gems/gitlab-http/Gemfile.lock b/gems/gitlab-http/Gemfile.lock index 4afa39ef750..c15bcd7cc18 100644 --- a/gems/gitlab-http/Gemfile.lock +++ b/gems/gitlab-http/Gemfile.lock @@ -19,11 +19,11 @@ PATH remote: . specs: gitlab-http (0.1.0) - activesupport (~> 7.0.6) + activesupport (~> 7) httparty (~> 0.21.0) ipaddress (~> 0.8.3) nokogiri (~> 1.15.4) - railties (~> 7.0.6) + railties (~> 7) GEM remote: https://rubygems.org/ diff --git a/gems/gitlab-http/gitlab-http.gemspec b/gems/gitlab-http/gitlab-http.gemspec index 2653d4d4fb7..6146ba7f78b 100644 --- a/gems/gitlab-http/gitlab-http.gemspec +++ b/gems/gitlab-http/gitlab-http.gemspec @@ -19,11 +19,11 @@ Gem::Specification.new do |spec| spec.test_files = Dir['spec/**/*'] spec.require_paths = ["lib"] - spec.add_runtime_dependency 'activesupport', '~> 7.0.6' + spec.add_runtime_dependency 'activesupport', '~> 7' spec.add_runtime_dependency 'httparty', '~> 0.21.0' spec.add_runtime_dependency 'ipaddress', '~> 0.8.3' spec.add_runtime_dependency 'nokogiri', '~> 1.15.4' - spec.add_runtime_dependency "railties", "~> 7.0.6" + spec.add_runtime_dependency "railties", "~> 7" spec.add_development_dependency 'gitlab-styles', '~> 10.1.0' spec.add_development_dependency 'rspec-rails', '~> 6.0.3' diff --git a/gems/gitlab-http/lib/gitlab/http_v2/client.rb b/gems/gitlab-http/lib/gitlab/http_v2/client.rb index 8daf19d7351..c10197e0385 100644 --- a/gems/gitlab-http/lib/gitlab/http_v2/client.rb +++ b/gems/gitlab-http/lib/gitlab/http_v2/client.rb @@ -25,70 +25,74 @@ module Gitlab include HTTParty # rubocop:disable Gitlab/HTTParty - class << self - alias_method :httparty_perform_request, :perform_request - end - connection_adapter NewConnectionAdapter - def self.perform_request(http_method, path, options, &block) - raise_if_blocked_by_silent_mode(http_method) if options.delete(:silent_mode_enabled) + class << self + def try_get(path, options = {}, &block) + self.get(path, options, &block) # rubocop:disable Style/RedundantSelf + rescue *HTTP_ERRORS + nil + end - log_info = options.delete(:extra_log_info) - options_with_timeouts = - if !options.has_key?(:timeout) - options.with_defaults(DEFAULT_TIMEOUT_OPTIONS) - else - options - end + def configuration + Gitlab::HTTP_V2.configuration + end - if options[:stream_body] - httparty_perform_request(http_method, path, options_with_timeouts, &block) - else - begin - start_time = nil - read_total_timeout = options.fetch(:timeout, DEFAULT_READ_TOTAL_TIMEOUT) + private - httparty_perform_request(http_method, path, options_with_timeouts) do |fragment| - start_time ||= system_monotonic_time - elapsed = system_monotonic_time - start_time + alias_method :httparty_perform_request, :perform_request - raise ReadTotalTimeout, "Request timed out after #{elapsed} seconds" if elapsed > read_total_timeout + # TODO: This overwrites a method implemented by `HTTPParty` + # The calls to `get/...` will call this method instead of `httparty_perform_request` + def perform_request(http_method, path, options, &block) + raise_if_blocked_by_silent_mode(http_method) if options.delete(:silent_mode_enabled) + + log_info = options.delete(:extra_log_info) + options_with_timeouts = + if !options.has_key?(:timeout) + options.with_defaults(DEFAULT_TIMEOUT_OPTIONS) + else + options + end - yield fragment if block + if options[:stream_body] + httparty_perform_request(http_method, path, options_with_timeouts, &block) + else + begin + start_time = nil + read_total_timeout = options.fetch(:timeout, DEFAULT_READ_TOTAL_TIMEOUT) + + httparty_perform_request(http_method, path, options_with_timeouts) do |fragment| + start_time ||= system_monotonic_time + elapsed = system_monotonic_time - start_time + + raise ReadTotalTimeout, "Request timed out after #{elapsed} seconds" if elapsed > read_total_timeout + + yield fragment if block + end + rescue HTTParty::RedirectionTooDeep + raise RedirectionTooDeep + rescue *HTTP_ERRORS => e + extra_info = log_info || {} + extra_info = log_info.call(e, path, options) if log_info.respond_to?(:call) + configuration.log_exception(e, extra_info) + + raise e end - rescue HTTParty::RedirectionTooDeep - raise RedirectionTooDeep - rescue *HTTP_ERRORS => e - extra_info = log_info || {} - extra_info = log_info.call(e, path, options) if log_info.respond_to?(:call) - configuration.log_exception(e, extra_info) - - raise e end end - end - - def self.try_get(path, options = {}, &block) - self.get(path, options, &block) # rubocop:disable Style/RedundantSelf - rescue *HTTP_ERRORS - nil - end - def self.raise_if_blocked_by_silent_mode(http_method) - return if SILENT_MODE_ALLOWED_METHODS.include?(http_method) + def raise_if_blocked_by_silent_mode(http_method) + return if SILENT_MODE_ALLOWED_METHODS.include?(http_method) - configuration.silent_mode_log_info('Outbound HTTP request blocked', http_method.to_s) + configuration.silent_mode_log_info('Outbound HTTP request blocked', http_method.to_s) - raise SilentModeBlockedError, 'only get, head, options, and trace methods are allowed in silent mode' - end - - def self.system_monotonic_time - Process.clock_gettime(Process::CLOCK_MONOTONIC, :float_second) - end + raise SilentModeBlockedError, 'only get, head, options, and trace methods are allowed in silent mode' + end - def self.configuration - Gitlab::HTTP_V2.configuration + def system_monotonic_time + Process.clock_gettime(Process::CLOCK_MONOTONIC, :float_second) + end end end end diff --git a/gems/gitlab-http/lib/gitlab/http_v2/url_blocker.rb b/gems/gitlab-http/lib/gitlab/http_v2/url_blocker.rb index a794ab2f443..878daf42d8a 100644 --- a/gems/gitlab-http/lib/gitlab/http_v2/url_blocker.rb +++ b/gems/gitlab-http/lib/gitlab/http_v2/url_blocker.rb @@ -188,7 +188,7 @@ module Gitlab # # @param uri [Addressable::URI] # - # @raise [Gitlab::UrlBlocker::BlockedUrlError, ArgumentError] - BlockedUrlError raised if host is too long. + # @raise [Gitlab::HTTP_V2::UrlBlocker::BlockedUrlError, ArgumentError] raised if host is too long. # # @return [Array<Addrinfo>] def get_address_info(uri) @@ -271,7 +271,7 @@ module Gitlab def multiline_blocked?(parsed_url) url = parsed_url.to_s - return true if url =~ /\n|\r/ + return true if /\n|\r/.match?(url) # Google Cloud Storage uses a multi-line, encoded Signature query string return false if %w[http https].include?(parsed_url.scheme&.downcase) @@ -295,7 +295,7 @@ module Gitlab def validate_user(value) return if value.blank? - return if value =~ /\A\p{Alnum}/ + return if /\A\p{Alnum}/.match?(value) raise BlockedUrlError, "Username needs to start with an alphanumeric character" end @@ -303,7 +303,7 @@ module Gitlab def validate_hostname(value) return if value.blank? return if IPAddress.valid?(value) - return if value =~ /\A\p{Alnum}/ + return if /\A\p{Alnum}/.match?(value) raise BlockedUrlError, "Hostname or IP address invalid" end diff --git a/gems/gitlab-http/lib/net_http/response_patch.rb b/gems/gitlab-http/lib/net_http/response_patch.rb index e5477a31318..303d629b32e 100644 --- a/gems/gitlab-http/lib/net_http/response_patch.rb +++ b/gems/gitlab-http/lib/net_http/response_patch.rb @@ -20,11 +20,12 @@ module Net start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC) key = value = nil while true - line = if sock.is_a?(Gitlab::HTTP_V2::BufferedIo) - sock.readuntil("\n", true, start_time) - else - sock.readuntil("\n", true) - end + uses_buffered_io = sock.is_a?(Gitlab::HTTP_V2::BufferedIo) + + # TODO: Gitlab::BufferedIo is temporarily used for an easy migration. + uses_buffered_io ||= sock.is_a?(Gitlab::BufferedIo) if defined?(Gitlab::BufferedIo) + + line = uses_buffered_io ? sock.readuntil("\n", true, start_time) : sock.readuntil("\n", true) line = line.sub(/\s{0,10}\z/, '') break if line.empty? if line[0] == ?\s or line[0] == ?\t and value diff --git a/gems/gitlab-http/spec/gitlab/http_v2/net_http_patch_spec.rb b/gems/gitlab-http/spec/gitlab/http_v2/net_http_patch_spec.rb index b82646fb365..f34b0d98403 100644 --- a/gems/gitlab-http/spec/gitlab/http_v2/net_http_patch_spec.rb +++ b/gems/gitlab-http/spec/gitlab/http_v2/net_http_patch_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' require 'net/http' -RSpec.describe 'Net::HTTP patch proxy user and password encoding' do +RSpec.describe 'Net::HTTP patch proxy user and password encoding', feature_category: :shared do let(:net_http) { Net::HTTP.new('hostname.example') } before do |