diff options
author | Alejandro RodrÃguez <alejorro70@gmail.com> | 2017-01-03 19:34:09 -0300 |
---|---|---|
committer | Alejandro RodrÃguez <alejorro70@gmail.com> | 2017-01-05 23:09:25 -0300 |
commit | 2e1299cc7436b9c7143037f12bea518c7813d707 (patch) | |
tree | c0a1fed41effbe3852913a2d88224abd43b6dac4 | |
parent | f61bdfe39c6b0618144f369d5cf4df1099be9948 (diff) | |
download | gitlab-shell-2e1299cc7436b9c7143037f12bea518c7813d707.tar.gz |
Separate HTTP logic from GitlabNet
-rwxr-xr-x | bin/check | 2 | ||||
-rw-r--r-- | lib/gitlab_access.rb | 2 | ||||
-rw-r--r-- | lib/gitlab_net.rb | 116 | ||||
-rw-r--r-- | lib/gitlab_post_receive.rb | 2 | ||||
-rw-r--r-- | lib/gitlab_shell.rb | 4 | ||||
-rw-r--r-- | lib/http_client.rb | 118 | ||||
-rw-r--r-- | spec/gitlab_access_spec.rb | 2 | ||||
-rw-r--r-- | spec/gitlab_net_spec.rb | 6 | ||||
-rw-r--r-- | spec/gitlab_shell_spec.rb | 2 |
9 files changed, 132 insertions, 122 deletions
@@ -15,7 +15,7 @@ begin else abort "FAILED. code: #{resp.code}" end -rescue GitlabNet::ApiUnreachableError +rescue HttpClient::ApiUnreachableError abort "FAILED: Failed to connect to internal API" end diff --git a/lib/gitlab_access.rb b/lib/gitlab_access.rb index 1b2a065..ad06f85 100644 --- a/lib/gitlab_access.rb +++ b/lib/gitlab_access.rb @@ -33,7 +33,7 @@ class GitlabAccess raise AccessDeniedError, status.message unless status.allowed? true - rescue GitlabNet::ApiUnreachableError + rescue HttpClient::ApiUnreachableError $stderr.puts "GitLab: Failed to authorize your Git request: internal API unreachable" false rescue AccessDeniedError => ex diff --git a/lib/gitlab_net.rb b/lib/gitlab_net.rb index e06557c..f5136cd 100644 --- a/lib/gitlab_net.rb +++ b/lib/gitlab_net.rb @@ -1,20 +1,11 @@ -require 'net/http' -require 'openssl' require 'json' -require_relative 'gitlab_config' -require_relative 'gitlab_logger' require_relative 'gitlab_access' require_relative 'gitlab_redis' require_relative 'gitlab_lfs_authentication' -require_relative 'httpunix' - -class GitlabNet - class ApiUnreachableError < StandardError; end - - CHECK_TIMEOUT = 5 - READ_TIMEOUT = 300 +require_relative 'http_client' +class GitlabNet < HttpClient def check_access(cmd, repo, actor, changes, protocol, env: {}) changes = changes.join("\n") unless changes.kind_of?(String) @@ -119,114 +110,15 @@ class GitlabNet protected - def sanitize_path(repo) - repo.gsub("'", "") - end - - def config - @config ||= GitlabConfig.new + def http_request_for(method, uri, params = {}) + super(method, uri, params.merge(secret_token: secret_token)) end def host "#{config.gitlab_url}/api/v3/internal" end - def http_client_for(uri, options={}) - if uri.is_a?(URI::HTTPUNIX) - http = Net::HTTPUNIX.new(uri.hostname) - else - http = Net::HTTP.new(uri.host, uri.port) - end - - http.read_timeout = options[:read_timeout] || read_timeout - - if uri.is_a?(URI::HTTPS) - http.use_ssl = true - http.cert_store = cert_store - http.verify_mode = OpenSSL::SSL::VERIFY_NONE if config.http_settings['self_signed_cert'] - end - - http - end - - def http_request_for(method, uri, params = {}) - request_klass = method == :get ? Net::HTTP::Get : Net::HTTP::Post - request = request_klass.new(uri.request_uri) - - user = config.http_settings['user'] - password = config.http_settings['password'] - request.basic_auth(user, password) if user && password - - request.set_form_data(params.merge(secret_token: secret_token)) - - if uri.is_a?(URI::HTTPUNIX) - # The HTTPUNIX HTTP client does not set a correct Host header. This can - # lead to 400 Bad Request responses. - request['Host'] = 'localhost' - end - - request - end - - def request(method, url, params = {}, options={}) - $logger.debug "Performing #{method.to_s.upcase} #{url}" - - uri = URI.parse(url) - - http = http_client_for(uri, options) - request = http_request_for(method, uri, params) - - begin - start_time = Time.new - response = http.start { http.request(request) } - rescue => e - $logger.warn "Failed to connect to internal API <#{method.to_s.upcase} #{url}>: #{e.inspect}" - raise ApiUnreachableError - ensure - $logger.info do - sprintf('%s %s %0.5f', method.to_s.upcase, url, Time.new - start_time) - end - end - - if response.code == "200" - $logger.debug "Received response #{response.code} => <#{response.body}>." - else - $logger.error "API call <#{method.to_s.upcase} #{url}> failed: #{response.code} => <#{response.body}>." - end - - response - end - - def get(url, options={}) - request(:get, url, {}, options) - end - - def post(url, params) - request(:post, url, params) - end - - def cert_store - @cert_store ||= begin - store = OpenSSL::X509::Store.new - store.set_default_paths - - if ca_file = config.http_settings['ca_file'] - store.add_file(ca_file) - end - - if ca_path = config.http_settings['ca_path'] - store.add_path(ca_path) - end - - store - end - end - def secret_token @secret_token ||= File.read config.secret_file end - - def read_timeout - config.http_settings['read_timeout'] || READ_TIMEOUT - end end diff --git a/lib/gitlab_post_receive.rb b/lib/gitlab_post_receive.rb index 7e3b310..e9ca14d 100644 --- a/lib/gitlab_post_receive.rb +++ b/lib/gitlab_post_receive.rb @@ -35,7 +35,7 @@ class GitlabPostReceive api.merge_request_urls(@repo_path, @changes) end print_merge_request_links(merge_request_urls) - rescue GitlabNet::ApiUnreachableError + rescue HttpClient::ApiUnreachableError nil end diff --git a/lib/gitlab_shell.rb b/lib/gitlab_shell.rb index e243aac..5e18842 100644 --- a/lib/gitlab_shell.rb +++ b/lib/gitlab_shell.rb @@ -40,7 +40,7 @@ class GitlabShell process_cmd(args) true - rescue GitlabNet::ApiUnreachableError => ex + rescue HttpClient::ApiUnreachableError => ex $stderr.puts "GitLab: Failed to authorize your Git request: internal API unreachable" false rescue AccessDeniedError => ex @@ -174,7 +174,7 @@ class GitlabShell begin @user = api.discover(@key_id) - rescue GitlabNet::ApiUnreachableError + rescue HttpClient::ApiUnreachableError @user = nil end end diff --git a/lib/http_client.rb b/lib/http_client.rb new file mode 100644 index 0000000..3c3c242 --- /dev/null +++ b/lib/http_client.rb @@ -0,0 +1,118 @@ +require 'net/http' +require 'openssl' + +require_relative 'gitlab_config' +require_relative 'gitlab_logger' +require_relative 'httpunix' + +class HttpClient + class ApiUnreachableError < StandardError; end + + CHECK_TIMEOUT = 5 + READ_TIMEOUT = 300 + + protected + + def sanitize_path(repo) + repo.gsub("'", "") + end + + def config + @config ||= GitlabConfig.new + end + + def http_client_for(uri, options={}) + if uri.is_a?(URI::HTTPUNIX) + http = Net::HTTPUNIX.new(uri.hostname) + else + http = Net::HTTP.new(uri.host, uri.port) + end + + http.read_timeout = options[:read_timeout] || read_timeout + + if uri.is_a?(URI::HTTPS) + http.use_ssl = true + http.cert_store = cert_store + http.verify_mode = OpenSSL::SSL::VERIFY_NONE if config.http_settings['self_signed_cert'] + end + + http + end + + def http_request_for(method, uri, params = {}) + request_klass = method == :get ? Net::HTTP::Get : Net::HTTP::Post + request = request_klass.new(uri.request_uri) + + user = config.http_settings['user'] + password = config.http_settings['password'] + request.basic_auth(user, password) if user && password + + request.set_form_data(params) + + if uri.is_a?(URI::HTTPUNIX) + # The HTTPUNIX HTTP client does not set a correct Host header. This can + # lead to 400 Bad Request responses. + request['Host'] = 'localhost' + end + + request + end + + def request(method, url, params = {}, options={}) + $logger.debug "Performing #{method.to_s.upcase} #{url}" + + uri = URI.parse(url) + + http = http_client_for(uri, options) + request = http_request_for(method, uri, params) + + begin + start_time = Time.new + response = http.start { http.request(request) } + rescue => e + $logger.warn "Failed to connect to <#{method.to_s.upcase} #{url}>: #{e.inspect}" + raise ApiUnreachableError + ensure + $logger.info do + sprintf('%s %s %0.5f', method.to_s.upcase, url, Time.new - start_time) + end + end + + if response.code == "200" + $logger.debug "Received response #{response.code} => <#{response.body}>." + else + $logger.error "HTTP call <#{method.to_s.upcase} #{url}> failed: #{response.code} => <#{response.body}>." + end + + response + end + + def get(url, options={}) + request(:get, url, {}, options) + end + + def post(url, params) + request(:post, url, params) + end + + def cert_store + @cert_store ||= begin + store = OpenSSL::X509::Store.new + store.set_default_paths + + if ca_file = config.http_settings['ca_file'] + store.add_file(ca_file) + end + + if ca_path = config.http_settings['ca_path'] + store.add_path(ca_path) + end + + store + end + end + + def read_timeout + config.http_settings['read_timeout'] || READ_TIMEOUT + end +end diff --git a/spec/gitlab_access_spec.rb b/spec/gitlab_access_spec.rb index a602883..2a2e493 100644 --- a/spec/gitlab_access_spec.rb +++ b/spec/gitlab_access_spec.rb @@ -49,7 +49,7 @@ describe GitlabAccess do context "API connection fails" do before do - api.stub(:check_access).and_raise(GitlabNet::ApiUnreachableError) + api.stub(:check_access).and_raise(HttpClient::ApiUnreachableError) end it "returns false" do diff --git a/spec/gitlab_net_spec.rb b/spec/gitlab_net_spec.rb index e3ab16c..1d95dbb 100644 --- a/spec/gitlab_net_spec.rb +++ b/spec/gitlab_net_spec.rb @@ -29,7 +29,7 @@ describe GitlabNet, vcr: true do it "raises an exception if the connection fails" do Net::HTTP.any_instance.stub(:request).and_raise(StandardError) - expect { gitlab_net.check }.to raise_error(GitlabNet::ApiUnreachableError) + expect { gitlab_net.check }.to raise_error(HttpClient::ApiUnreachableError) end end @@ -52,7 +52,7 @@ describe GitlabNet, vcr: true do it "raises an exception if the connection fails" do VCR.use_cassette("discover-ok") do Net::HTTP.any_instance.stub(:request).and_raise(StandardError) - expect { gitlab_net.discover('key-126') }.to raise_error(GitlabNet::ApiUnreachableError) + expect { gitlab_net.discover('key-126') }.to raise_error(HttpClient::ApiUnreachableError) end end end @@ -225,7 +225,7 @@ describe GitlabNet, vcr: true do Net::HTTP.any_instance.stub(:request).and_raise(StandardError) expect { gitlab_net.check_access('git-upload-pack', 'gitlab/gitlabhq.git', 'user-1', changes, 'ssh') - }.to raise_error(GitlabNet::ApiUnreachableError) + }.to raise_error(HttpClient::ApiUnreachableError) end end diff --git a/spec/gitlab_shell_spec.rb b/spec/gitlab_shell_spec.rb index b9b8659..33c43d5 100644 --- a/spec/gitlab_shell_spec.rb +++ b/spec/gitlab_shell_spec.rb @@ -217,7 +217,7 @@ describe GitlabShell do let(:ssh_cmd) { 'git-upload-pack gitlab-ci.git' } before { - api.stub(:check_access).and_raise(GitlabNet::ApiUnreachableError) + api.stub(:check_access).and_raise(HttpClient::ApiUnreachableError) } after { subject.exec(ssh_cmd) } |