2022-01-01 13:38:12 +00:00
|
|
|
# Copyright (C) 2012-2022 Zammad Foundation, https://zammad-foundation.org/
|
2013-09-19 14:17:25 +00:00
|
|
|
|
|
|
|
require 'net/http'
|
|
|
|
require 'net/https'
|
|
|
|
require 'net/ftp'
|
|
|
|
|
|
|
|
class UserAgent
|
|
|
|
|
|
|
|
=begin
|
|
|
|
|
2015-03-22 22:13:39 +00:00
|
|
|
get http/https calls
|
2013-09-19 14:17:25 +00:00
|
|
|
|
2015-11-20 01:59:35 +00:00
|
|
|
result = UserAgent.get('http://host/some_dir/some_file?param1=123')
|
2013-09-19 14:17:25 +00:00
|
|
|
|
2015-03-22 22:13:39 +00:00
|
|
|
result = UserAgent.get(
|
|
|
|
'http://host/some_dir/some_file?param1=123',
|
2015-03-23 00:31:30 +00:00
|
|
|
{
|
2015-11-20 01:59:35 +00:00
|
|
|
param1: 'some value',
|
2015-03-23 00:31:30 +00:00
|
|
|
},
|
2015-03-22 22:13:39 +00:00
|
|
|
{
|
2015-11-20 01:59:35 +00:00
|
|
|
open_timeout: 4,
|
|
|
|
read_timeout: 10,
|
2015-03-22 22:13:39 +00:00
|
|
|
},
|
|
|
|
)
|
2013-09-19 14:17:25 +00:00
|
|
|
|
2015-09-08 15:01:26 +00:00
|
|
|
returns
|
|
|
|
|
|
|
|
result.body # as response
|
|
|
|
|
2015-04-27 06:20:52 +00:00
|
|
|
get json object
|
|
|
|
|
|
|
|
result = UserAgent.get(
|
|
|
|
'http://host/some_dir/some_file?param1=123',
|
|
|
|
{},
|
|
|
|
{
|
2015-11-20 01:59:35 +00:00
|
|
|
json: true,
|
2015-04-27 06:20:52 +00:00
|
|
|
}
|
|
|
|
)
|
|
|
|
|
2015-03-22 22:13:39 +00:00
|
|
|
returns
|
2013-09-19 14:17:25 +00:00
|
|
|
|
2015-04-27 06:20:52 +00:00
|
|
|
result.data # as json object
|
2015-03-22 22:13:39 +00:00
|
|
|
|
|
|
|
=end
|
|
|
|
|
2015-03-23 00:31:30 +00:00
|
|
|
def self.get(url, params = {}, options = {}, count = 10)
|
2015-03-22 22:13:39 +00:00
|
|
|
uri = URI.parse(url)
|
|
|
|
http = get_http(uri, options)
|
|
|
|
|
|
|
|
# prepare request
|
2020-09-30 09:37:57 +00:00
|
|
|
request = Net::HTTP::Get.new(uri)
|
|
|
|
|
|
|
|
# set headers
|
|
|
|
request = set_headers(request, options)
|
2015-03-22 22:13:39 +00:00
|
|
|
|
|
|
|
# http basic auth (if needed)
|
|
|
|
request = set_basic_auth(request, options)
|
|
|
|
|
2015-03-23 00:31:30 +00:00
|
|
|
# set params
|
|
|
|
request = set_params(request, params, options)
|
|
|
|
|
2020-09-30 12:31:33 +00:00
|
|
|
# add signature
|
|
|
|
request = set_signature(request, options)
|
|
|
|
|
2015-03-22 22:13:39 +00:00
|
|
|
# start http call
|
|
|
|
begin
|
2016-01-21 01:07:50 +00:00
|
|
|
total_timeout = options[:total_timeout] || 60
|
2019-09-16 09:15:12 +00:00
|
|
|
|
|
|
|
handled_open_timeout(options[:open_socket_tries]) do
|
|
|
|
Timeout.timeout(total_timeout) do
|
|
|
|
response = http.request(request)
|
|
|
|
return process(request, response, uri, count, params, options)
|
|
|
|
end
|
2016-01-21 01:07:50 +00:00
|
|
|
end
|
2015-05-08 14:09:24 +00:00
|
|
|
rescue => e
|
2016-04-18 00:02:31 +00:00
|
|
|
log(url, request, nil, options)
|
2020-02-18 19:51:31 +00:00
|
|
|
Result.new(
|
2018-12-19 17:31:51 +00:00
|
|
|
error: e.inspect,
|
2015-04-27 13:42:53 +00:00
|
|
|
success: false,
|
2018-12-19 17:31:51 +00:00
|
|
|
code: 0,
|
2015-03-22 22:13:39 +00:00
|
|
|
)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
=begin
|
|
|
|
|
|
|
|
post http/https calls
|
|
|
|
|
|
|
|
result = UserAgent.post(
|
|
|
|
'http://host/some_dir/some_file',
|
|
|
|
{
|
2015-11-20 01:59:35 +00:00
|
|
|
param1: 1,
|
|
|
|
param2: 2,
|
2015-03-22 22:13:39 +00:00
|
|
|
},
|
|
|
|
{
|
2015-11-20 01:59:35 +00:00
|
|
|
open_timeout: 4,
|
|
|
|
read_timeout: 10,
|
2016-01-21 01:07:50 +00:00
|
|
|
total_timeout: 60,
|
2015-03-22 22:13:39 +00:00
|
|
|
},
|
|
|
|
)
|
|
|
|
|
|
|
|
returns
|
|
|
|
|
|
|
|
result # result object
|
|
|
|
|
|
|
|
=end
|
|
|
|
|
|
|
|
def self.post(url, params = {}, options = {}, count = 10)
|
|
|
|
uri = URI.parse(url)
|
|
|
|
http = get_http(uri, options)
|
|
|
|
|
|
|
|
# prepare request
|
2020-09-30 09:37:57 +00:00
|
|
|
request = Net::HTTP::Post.new(uri)
|
|
|
|
|
|
|
|
# set headers
|
|
|
|
request = set_headers(request, options)
|
2015-03-22 22:13:39 +00:00
|
|
|
|
|
|
|
# set params
|
2015-03-23 00:31:30 +00:00
|
|
|
request = set_params(request, params, options)
|
2015-03-22 22:13:39 +00:00
|
|
|
|
|
|
|
# http basic auth (if needed)
|
|
|
|
request = set_basic_auth(request, options)
|
|
|
|
|
2020-09-30 12:31:33 +00:00
|
|
|
# add signature
|
|
|
|
request = set_signature(request, options)
|
|
|
|
|
2015-03-22 22:13:39 +00:00
|
|
|
# start http call
|
|
|
|
begin
|
2016-01-21 01:07:50 +00:00
|
|
|
total_timeout = options[:total_timeout] || 60
|
2019-09-16 09:15:12 +00:00
|
|
|
|
|
|
|
handled_open_timeout(options[:open_socket_tries]) do
|
|
|
|
Timeout.timeout(total_timeout) do
|
|
|
|
response = http.request(request)
|
|
|
|
return process(request, response, uri, count, params, options)
|
|
|
|
end
|
2016-01-21 01:07:50 +00:00
|
|
|
end
|
2015-05-08 14:09:24 +00:00
|
|
|
rescue => e
|
2016-04-18 00:02:31 +00:00
|
|
|
log(url, request, nil, options)
|
2020-02-18 19:51:31 +00:00
|
|
|
Result.new(
|
2018-12-19 17:31:51 +00:00
|
|
|
error: e.inspect,
|
2015-04-27 13:42:53 +00:00
|
|
|
success: false,
|
2018-12-19 17:31:51 +00:00
|
|
|
code: 0,
|
2015-03-22 22:13:39 +00:00
|
|
|
)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
=begin
|
|
|
|
|
|
|
|
put http/https calls
|
|
|
|
|
|
|
|
result = UserAgent.put(
|
|
|
|
'http://host/some_dir/some_file',
|
|
|
|
{
|
2015-11-20 01:59:35 +00:00
|
|
|
param1: 1,
|
|
|
|
param2: 2,
|
2015-03-22 22:13:39 +00:00
|
|
|
},
|
|
|
|
{
|
2015-11-20 01:59:35 +00:00
|
|
|
open_timeout: 4,
|
|
|
|
read_timeout: 10,
|
2015-03-22 22:13:39 +00:00
|
|
|
},
|
|
|
|
)
|
|
|
|
|
|
|
|
returns
|
|
|
|
|
|
|
|
result # result object
|
|
|
|
|
|
|
|
=end
|
|
|
|
|
|
|
|
def self.put(url, params = {}, options = {}, count = 10)
|
|
|
|
uri = URI.parse(url)
|
|
|
|
http = get_http(uri, options)
|
|
|
|
|
|
|
|
# prepare request
|
2020-09-30 09:37:57 +00:00
|
|
|
request = Net::HTTP::Put.new(uri)
|
|
|
|
|
|
|
|
# set headers
|
|
|
|
request = set_headers(request, options)
|
2015-03-22 22:13:39 +00:00
|
|
|
|
|
|
|
# set params
|
2015-03-23 00:31:30 +00:00
|
|
|
request = set_params(request, params, options)
|
2015-03-22 22:13:39 +00:00
|
|
|
|
|
|
|
# http basic auth (if needed)
|
|
|
|
request = set_basic_auth(request, options)
|
|
|
|
|
2020-09-30 12:31:33 +00:00
|
|
|
# add signature
|
|
|
|
request = set_signature(request, options)
|
|
|
|
|
2015-03-22 22:13:39 +00:00
|
|
|
# start http call
|
|
|
|
begin
|
2016-01-21 01:07:50 +00:00
|
|
|
total_timeout = options[:total_timeout] || 60
|
2019-09-16 09:15:12 +00:00
|
|
|
|
|
|
|
handled_open_timeout(options[:open_socket_tries]) do
|
|
|
|
Timeout.timeout(total_timeout) do
|
|
|
|
response = http.request(request)
|
|
|
|
return process(request, response, uri, count, params, options)
|
|
|
|
end
|
2016-01-21 01:07:50 +00:00
|
|
|
end
|
2015-05-08 14:09:24 +00:00
|
|
|
rescue => e
|
2016-04-18 00:02:31 +00:00
|
|
|
log(url, request, nil, options)
|
2020-02-18 19:51:31 +00:00
|
|
|
Result.new(
|
2018-12-19 17:31:51 +00:00
|
|
|
error: e.inspect,
|
2015-04-27 13:42:53 +00:00
|
|
|
success: false,
|
2018-12-19 17:31:51 +00:00
|
|
|
code: 0,
|
2015-03-22 22:13:39 +00:00
|
|
|
)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
=begin
|
|
|
|
|
|
|
|
delete http/https calls
|
|
|
|
|
|
|
|
result = UserAgent.delete(
|
|
|
|
'http://host/some_dir/some_file',
|
2015-03-22 10:46:05 +00:00
|
|
|
{
|
2015-11-20 01:59:35 +00:00
|
|
|
open_timeout: 4,
|
|
|
|
read_timeout: 10,
|
2015-03-22 10:46:05 +00:00
|
|
|
},
|
|
|
|
)
|
|
|
|
|
2015-03-22 22:13:39 +00:00
|
|
|
returns
|
|
|
|
|
|
|
|
result # result object
|
|
|
|
|
|
|
|
=end
|
|
|
|
|
2019-11-04 12:25:42 +00:00
|
|
|
def self.delete(url, params = {}, options = {}, count = 10)
|
2015-03-22 22:13:39 +00:00
|
|
|
uri = URI.parse(url)
|
|
|
|
http = get_http(uri, options)
|
|
|
|
|
|
|
|
# prepare request
|
2020-09-30 09:37:57 +00:00
|
|
|
request = Net::HTTP::Delete.new(uri)
|
|
|
|
|
|
|
|
# set headers
|
|
|
|
request = set_headers(request, options)
|
2015-03-22 22:13:39 +00:00
|
|
|
|
|
|
|
# http basic auth (if needed)
|
|
|
|
request = set_basic_auth(request, options)
|
|
|
|
|
2020-09-30 12:31:33 +00:00
|
|
|
# add signature
|
|
|
|
request = set_signature(request, options)
|
|
|
|
|
2015-03-22 22:13:39 +00:00
|
|
|
# start http call
|
|
|
|
begin
|
2016-01-21 01:07:50 +00:00
|
|
|
total_timeout = options[:total_timeout] || 60
|
2019-09-16 09:15:12 +00:00
|
|
|
handled_open_timeout(options[:open_socket_tries]) do
|
|
|
|
Timeout.timeout(total_timeout) do
|
|
|
|
response = http.request(request)
|
2019-11-04 12:25:42 +00:00
|
|
|
return process(request, response, uri, count, params, options)
|
2019-09-16 09:15:12 +00:00
|
|
|
end
|
2016-01-21 01:07:50 +00:00
|
|
|
end
|
2015-05-08 14:09:24 +00:00
|
|
|
rescue => e
|
2016-04-18 00:02:31 +00:00
|
|
|
log(url, request, nil, options)
|
2020-02-18 19:51:31 +00:00
|
|
|
Result.new(
|
2018-12-19 17:31:51 +00:00
|
|
|
error: e.inspect,
|
2015-04-27 13:42:53 +00:00
|
|
|
success: false,
|
2018-12-19 17:31:51 +00:00
|
|
|
code: 0,
|
2015-03-22 22:13:39 +00:00
|
|
|
)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
=begin
|
|
|
|
|
|
|
|
perform get http/https/ftp calls
|
|
|
|
|
2015-11-20 01:59:35 +00:00
|
|
|
result = UserAgent.request('ftp://host/some_dir/some_file.bin')
|
2015-03-22 22:13:39 +00:00
|
|
|
|
2015-11-20 01:59:35 +00:00
|
|
|
result = UserAgent.request('http://host/some_dir/some_file.bin')
|
2015-03-22 22:13:39 +00:00
|
|
|
|
2015-11-20 01:59:35 +00:00
|
|
|
result = UserAgent.request('https://host/some_dir/some_file.bin')
|
2015-03-22 22:13:39 +00:00
|
|
|
|
2015-03-22 10:46:05 +00:00
|
|
|
# get request
|
|
|
|
result = UserAgent.request(
|
|
|
|
'http://host/some_dir/some_file?param1=123',
|
|
|
|
{
|
2015-11-20 01:59:35 +00:00
|
|
|
open_timeout: 4,
|
|
|
|
read_timeout: 10,
|
2015-03-22 10:46:05 +00:00
|
|
|
},
|
|
|
|
)
|
2013-09-19 14:17:25 +00:00
|
|
|
|
|
|
|
returns
|
|
|
|
|
|
|
|
result # result object
|
|
|
|
|
|
|
|
=end
|
|
|
|
|
|
|
|
def self.request(url, options = {})
|
|
|
|
|
|
|
|
uri = URI.parse(url)
|
|
|
|
case uri.scheme.downcase
|
2021-05-12 11:37:44 +00:00
|
|
|
when %r{ftp}
|
2013-09-19 14:17:25 +00:00
|
|
|
ftp(uri, options)
|
2021-05-12 11:37:44 +00:00
|
|
|
when %r{http|https}
|
2015-11-20 01:59:35 +00:00
|
|
|
get(url, {}, options)
|
2013-09-19 14:17:25 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
|
2015-04-27 14:56:32 +00:00
|
|
|
def self.get_http(uri, options)
|
2017-01-16 00:24:56 +00:00
|
|
|
|
|
|
|
proxy = options['proxy'] || Setting.get('proxy')
|
2017-07-27 10:05:54 +00:00
|
|
|
proxy_no = options['proxy_no'] || Setting.get('proxy_no') || ''
|
|
|
|
proxy_no = proxy_no.split(',').map(&:strip) || []
|
|
|
|
proxy_no.push('localhost', '127.0.0.1', '::1')
|
2020-09-30 09:07:01 +00:00
|
|
|
if proxy.present? && proxy_no.exclude?(uri.host.downcase)
|
2021-05-12 11:37:44 +00:00
|
|
|
if proxy =~ %r{^(.+?):(.+?)$}
|
2017-01-16 00:24:56 +00:00
|
|
|
proxy_host = $1
|
|
|
|
proxy_port = $2
|
2017-11-23 08:09:44 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
if proxy_host.blank? || proxy_port.blank?
|
2017-01-16 00:24:56 +00:00
|
|
|
raise "Invalid proxy address: #{proxy} - expect e.g. proxy.example.com:3128"
|
|
|
|
end
|
|
|
|
|
|
|
|
proxy_username = options['proxy_username'] || Setting.get('proxy_username')
|
|
|
|
if proxy_username.blank?
|
|
|
|
proxy_username = nil
|
|
|
|
end
|
|
|
|
proxy_password = options['proxy_password'] || Setting.get('proxy_password')
|
|
|
|
if proxy_password.blank?
|
|
|
|
proxy_password = nil
|
|
|
|
end
|
|
|
|
|
|
|
|
http = Net::HTTP::Proxy(proxy_host, proxy_port, proxy_username, proxy_password).new(uri.host, uri.port)
|
|
|
|
else
|
|
|
|
http = Net::HTTP.new(uri.host, uri.port)
|
|
|
|
end
|
2013-09-19 14:17:25 +00:00
|
|
|
|
2015-04-27 14:56:32 +00:00
|
|
|
http.open_timeout = options[:open_timeout] || 4
|
|
|
|
http.read_timeout = options[:read_timeout] || 10
|
2015-02-16 12:40:10 +00:00
|
|
|
|
2021-05-12 11:37:44 +00:00
|
|
|
if uri.scheme.match?(%r{https}i)
|
2015-04-27 14:56:32 +00:00
|
|
|
http.use_ssl = true
|
2020-09-30 12:30:02 +00:00
|
|
|
|
|
|
|
if !options.fetch(:verify_ssl, false)
|
|
|
|
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
|
|
|
end
|
2015-03-22 22:13:39 +00:00
|
|
|
end
|
2013-09-19 14:17:25 +00:00
|
|
|
|
2015-04-27 14:56:32 +00:00
|
|
|
http
|
|
|
|
end
|
2013-09-19 14:17:25 +00:00
|
|
|
|
2015-04-27 14:56:32 +00:00
|
|
|
def self.set_basic_auth(request, options)
|
|
|
|
|
|
|
|
# http basic auth (if needed)
|
2021-03-03 09:54:59 +00:00
|
|
|
if options[:user].present? && options[:password].present?
|
2015-04-27 14:56:32 +00:00
|
|
|
request.basic_auth options[:user], options[:password]
|
2015-03-22 22:13:39 +00:00
|
|
|
end
|
2015-04-27 14:56:32 +00:00
|
|
|
request
|
|
|
|
end
|
2013-09-19 14:17:25 +00:00
|
|
|
|
2015-04-27 14:56:32 +00:00
|
|
|
def self.set_params(request, params, options)
|
|
|
|
if options[:json]
|
|
|
|
request.add_field('Content-Type', 'application/json')
|
2017-11-23 08:09:44 +00:00
|
|
|
if params.present?
|
2015-04-27 14:56:32 +00:00
|
|
|
request.body = params.to_json
|
|
|
|
end
|
2017-11-23 08:09:44 +00:00
|
|
|
elsif params.present?
|
2016-01-15 17:22:57 +00:00
|
|
|
request.set_form_data(params)
|
2015-03-23 00:31:30 +00:00
|
|
|
end
|
2015-04-27 14:56:32 +00:00
|
|
|
request
|
|
|
|
end
|
2015-03-24 12:22:40 +00:00
|
|
|
|
2020-09-30 09:37:57 +00:00
|
|
|
def self.set_headers(request, options)
|
2021-11-15 15:58:19 +00:00
|
|
|
defaults = { 'User-Agent' => __('Zammad User Agent') }
|
2020-09-30 09:37:57 +00:00
|
|
|
headers = defaults.merge(options.fetch(:headers, {}))
|
|
|
|
|
|
|
|
headers.each do |header, value|
|
|
|
|
request[header] = value
|
|
|
|
end
|
|
|
|
|
|
|
|
request
|
|
|
|
end
|
|
|
|
|
2020-09-30 12:31:33 +00:00
|
|
|
def self.set_signature(request, options)
|
|
|
|
return request if options[:signature_token].blank?
|
|
|
|
return request if request.body.blank?
|
|
|
|
|
|
|
|
signature = OpenSSL::HMAC.hexdigest('sha1', options[:signature_token], request.body)
|
|
|
|
request['X-Hub-Signature'] = "sha1=#{signature}"
|
|
|
|
|
|
|
|
request
|
|
|
|
end
|
|
|
|
|
2016-04-18 00:02:31 +00:00
|
|
|
def self.log(url, request, response, options)
|
|
|
|
return if !options[:log]
|
|
|
|
|
|
|
|
# request
|
|
|
|
request_data = {
|
2018-12-19 17:31:51 +00:00
|
|
|
content: '',
|
|
|
|
content_type: request['Content-Type'],
|
2016-04-18 00:02:31 +00:00
|
|
|
content_encoding: request['Content-Encoding'],
|
2018-12-19 17:31:51 +00:00
|
|
|
source: request['User-Agent'] || request['Server'],
|
2016-04-18 00:02:31 +00:00
|
|
|
}
|
2017-10-01 12:25:52 +00:00
|
|
|
request.each_header do |key, value|
|
2016-04-18 00:02:31 +00:00
|
|
|
request_data[:content] += "#{key}: #{value}\n"
|
2017-10-01 12:25:52 +00:00
|
|
|
end
|
2016-04-18 00:02:31 +00:00
|
|
|
body = request.body
|
|
|
|
if body
|
2020-09-30 09:07:01 +00:00
|
|
|
request_data[:content] += "\n#{body}"
|
2016-04-18 00:02:31 +00:00
|
|
|
end
|
|
|
|
request_data[:content] = request_data[:content].slice(0, 8000)
|
|
|
|
|
|
|
|
# response
|
|
|
|
response_data = {
|
2018-12-19 17:31:51 +00:00
|
|
|
code: 0,
|
|
|
|
content: '',
|
|
|
|
content_type: nil,
|
2016-04-18 00:02:31 +00:00
|
|
|
content_encoding: nil,
|
2018-12-19 17:31:51 +00:00
|
|
|
source: nil,
|
2016-04-18 00:02:31 +00:00
|
|
|
}
|
|
|
|
if response
|
|
|
|
response_data[:code] = response.code
|
|
|
|
response_data[:content_type] = response['Content-Type']
|
|
|
|
response_data[:content_encoding] = response['Content-Encoding']
|
|
|
|
response_data[:source] = response['User-Agent'] || response['Server']
|
2017-10-01 12:25:52 +00:00
|
|
|
response.each_header do |key, value|
|
2016-04-18 00:02:31 +00:00
|
|
|
response_data[:content] += "#{key}: #{value}\n"
|
2017-10-01 12:25:52 +00:00
|
|
|
end
|
2016-04-18 00:02:31 +00:00
|
|
|
body = response.body
|
|
|
|
if body
|
2020-09-30 09:07:01 +00:00
|
|
|
response_data[:content] += "\n#{body}"
|
2016-04-18 00:02:31 +00:00
|
|
|
end
|
|
|
|
response_data[:content] = response_data[:content].slice(0, 8000)
|
|
|
|
end
|
|
|
|
|
|
|
|
record = {
|
|
|
|
direction: 'out',
|
2018-12-19 17:31:51 +00:00
|
|
|
facility: options[:log][:facility],
|
|
|
|
url: url,
|
|
|
|
status: response_data[:code],
|
|
|
|
ip: nil,
|
|
|
|
request: request_data,
|
|
|
|
response: response_data,
|
|
|
|
method: request.method,
|
2016-04-18 00:02:31 +00:00
|
|
|
}
|
|
|
|
HttpLog.create(record)
|
|
|
|
end
|
|
|
|
|
|
|
|
def self.process(request, response, uri, count, params, options) # rubocop:disable Metrics/ParameterLists
|
|
|
|
log(uri.to_s, request, response, options)
|
|
|
|
|
2015-04-27 14:56:32 +00:00
|
|
|
if !response
|
|
|
|
return Result.new(
|
2018-12-19 17:31:51 +00:00
|
|
|
error: "Can't connect to #{uri}, got no response!",
|
2015-04-27 14:56:32 +00:00
|
|
|
success: false,
|
2018-12-19 17:31:51 +00:00
|
|
|
code: 0,
|
2015-04-27 14:56:32 +00:00
|
|
|
)
|
|
|
|
end
|
2013-09-19 14:17:25 +00:00
|
|
|
|
2015-04-27 14:56:32 +00:00
|
|
|
case response
|
|
|
|
when Net::HTTPNotFound
|
|
|
|
return Result.new(
|
2018-12-19 17:31:51 +00:00
|
|
|
error: "No such file #{uri}, 404!",
|
2015-04-27 14:56:32 +00:00
|
|
|
success: false,
|
2018-12-19 17:31:51 +00:00
|
|
|
code: response.code,
|
2021-07-06 17:43:56 +00:00
|
|
|
header: response.each_header.to_h,
|
2015-04-27 14:56:32 +00:00
|
|
|
)
|
|
|
|
when Net::HTTPClientError
|
|
|
|
return Result.new(
|
2018-12-19 17:31:51 +00:00
|
|
|
error: "Client Error: #{response.inspect}!",
|
2015-04-27 14:56:32 +00:00
|
|
|
success: false,
|
2018-12-19 17:31:51 +00:00
|
|
|
code: response.code,
|
2021-07-06 17:43:56 +00:00
|
|
|
body: response.body,
|
|
|
|
header: response.each_header.to_h,
|
2015-04-27 14:56:32 +00:00
|
|
|
)
|
|
|
|
when Net::HTTPInternalServerError
|
|
|
|
return Result.new(
|
2018-12-19 17:31:51 +00:00
|
|
|
error: "Server Error: #{response.inspect}!",
|
2015-04-27 14:56:32 +00:00
|
|
|
success: false,
|
2018-12-19 17:31:51 +00:00
|
|
|
code: response.code,
|
2021-07-06 17:43:56 +00:00
|
|
|
header: response.each_header.to_h,
|
2015-04-27 14:56:32 +00:00
|
|
|
)
|
|
|
|
when Net::HTTPRedirection
|
2021-11-15 15:58:19 +00:00
|
|
|
raise __('Too many redirections for the original URL, halting.') if count <= 0
|
2018-10-09 06:17:41 +00:00
|
|
|
|
2015-04-27 14:56:32 +00:00
|
|
|
url = response['location']
|
|
|
|
return get(url, params, options, count - 1)
|
2021-05-27 10:10:30 +00:00
|
|
|
when Net::HTTPSuccess
|
2015-04-27 14:56:32 +00:00
|
|
|
data = nil
|
|
|
|
if options[:json] && !options[:jsonParseDisable] && response.body
|
2015-11-20 01:59:35 +00:00
|
|
|
data = JSON.parse(response.body)
|
2015-04-27 14:56:32 +00:00
|
|
|
end
|
|
|
|
return Result.new(
|
2018-12-19 17:31:51 +00:00
|
|
|
data: data,
|
|
|
|
body: response.body,
|
2015-04-27 14:56:32 +00:00
|
|
|
content_type: response['Content-Type'],
|
2018-12-19 17:31:51 +00:00
|
|
|
success: true,
|
|
|
|
code: response.code,
|
2021-07-06 17:43:56 +00:00
|
|
|
header: response.each_header.to_h,
|
2015-04-27 14:56:32 +00:00
|
|
|
)
|
2013-09-19 14:17:25 +00:00
|
|
|
end
|
|
|
|
|
2016-03-01 14:26:46 +00:00
|
|
|
raise "Unable to process http call '#{response.inspect}'"
|
2015-04-27 14:56:32 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def self.ftp(uri, options)
|
|
|
|
host = uri.host
|
|
|
|
filename = File.basename(uri.path)
|
|
|
|
remote_dir = File.dirname(uri.path)
|
|
|
|
|
|
|
|
temp_file = Tempfile.new("download-#{filename}")
|
|
|
|
temp_file.binmode
|
|
|
|
|
|
|
|
begin
|
|
|
|
Net::FTP.open(host) do |ftp|
|
|
|
|
ftp.passive = true
|
|
|
|
if options[:user] && options[:password]
|
2015-11-20 01:59:35 +00:00
|
|
|
ftp.login(options[:user], options[:password])
|
2015-04-27 14:56:32 +00:00
|
|
|
else
|
|
|
|
ftp.login
|
|
|
|
end
|
2018-05-04 14:05:10 +00:00
|
|
|
ftp.chdir(remote_dir) if remote_dir != '.'
|
2015-04-27 14:56:32 +00:00
|
|
|
|
|
|
|
begin
|
2015-11-20 01:59:35 +00:00
|
|
|
ftp.getbinaryfile(filename, temp_file)
|
2015-04-27 14:56:32 +00:00
|
|
|
rescue => e
|
|
|
|
return Result.new(
|
2018-12-19 17:31:51 +00:00
|
|
|
error: e.inspect,
|
2015-04-27 14:56:32 +00:00
|
|
|
success: false,
|
2018-12-19 17:31:51 +00:00
|
|
|
code: '550',
|
2015-04-27 14:56:32 +00:00
|
|
|
)
|
2013-09-19 14:17:25 +00:00
|
|
|
end
|
|
|
|
end
|
2015-04-27 14:56:32 +00:00
|
|
|
rescue => e
|
|
|
|
return Result.new(
|
2018-12-19 17:31:51 +00:00
|
|
|
error: e.inspect,
|
2015-04-27 14:56:32 +00:00
|
|
|
success: false,
|
2018-12-19 17:31:51 +00:00
|
|
|
code: 0,
|
2013-09-19 14:17:25 +00:00
|
|
|
)
|
|
|
|
end
|
|
|
|
|
2015-04-27 14:56:32 +00:00
|
|
|
contents = temp_file.read
|
|
|
|
temp_file.close
|
|
|
|
Result.new(
|
2018-12-19 17:31:51 +00:00
|
|
|
body: contents,
|
2015-04-27 14:56:32 +00:00
|
|
|
success: true,
|
2018-12-19 17:31:51 +00:00
|
|
|
code: '200',
|
2015-04-27 14:56:32 +00:00
|
|
|
)
|
|
|
|
end
|
|
|
|
|
2019-09-16 09:15:12 +00:00
|
|
|
def self.handled_open_timeout(tries)
|
|
|
|
tries ||= 1
|
|
|
|
|
|
|
|
tries.times do |index|
|
|
|
|
yield
|
|
|
|
rescue Net::OpenTimeout
|
|
|
|
raise if (index + 1) == tries
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2013-09-19 14:17:25 +00:00
|
|
|
class Result
|
2015-04-30 18:02:52 +00:00
|
|
|
|
2021-07-06 17:43:56 +00:00
|
|
|
attr_reader :error, :body, :data, :code, :content_type, :header
|
2015-04-30 18:02:52 +00:00
|
|
|
|
2013-09-19 14:17:25 +00:00
|
|
|
def initialize(options)
|
2013-11-02 21:32:00 +00:00
|
|
|
@success = options[:success]
|
|
|
|
@body = options[:body]
|
2015-03-23 00:31:30 +00:00
|
|
|
@data = options[:data]
|
2013-11-02 21:32:00 +00:00
|
|
|
@code = options[:code]
|
|
|
|
@content_type = options[:content_type]
|
|
|
|
@error = options[:error]
|
2021-07-06 17:43:56 +00:00
|
|
|
@header = options[:header]
|
2013-09-19 14:17:25 +00:00
|
|
|
end
|
2015-04-30 18:02:52 +00:00
|
|
|
|
2013-09-19 14:17:25 +00:00
|
|
|
def success?
|
2015-08-21 22:40:32 +00:00
|
|
|
return true if @success
|
2018-10-09 06:17:41 +00:00
|
|
|
|
2015-08-21 22:40:32 +00:00
|
|
|
false
|
2013-09-19 14:17:25 +00:00
|
|
|
end
|
|
|
|
end
|
2015-04-27 14:15:29 +00:00
|
|
|
end
|