active_utils 2.2.3 → 3.0.0.pre1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/.travis.yml +13 -3
- data/Gemfile +1 -1
- data/Gemfile.activesupport32 +4 -0
- data/Gemfile.activesupport40 +4 -0
- data/Gemfile.activesupport41 +4 -0
- data/Gemfile.activesupport42 +4 -0
- data/active_utils.gemspec +2 -1
- data/lib/active_utils/common/connection.rb +3 -169
- data/lib/active_utils/common/country.rb +3 -329
- data/lib/active_utils/common/currency_code.rb +3 -49
- data/lib/active_utils/common/error.rb +3 -28
- data/lib/active_utils/common/network_connection_retries.rb +3 -72
- data/lib/active_utils/common/post_data.rb +3 -23
- data/lib/active_utils/common/posts_data.rb +3 -76
- data/lib/active_utils/common/requires_parameters.rb +3 -15
- data/lib/active_utils/common/utils.rb +3 -19
- data/lib/active_utils/common/validateable.rb +3 -80
- data/lib/active_utils/common/version.rb +4 -0
- data/lib/active_utils/connection.rb +170 -0
- data/lib/active_utils/country.rb +330 -0
- data/lib/active_utils/currency_code.rb +51 -0
- data/lib/active_utils/error.rb +29 -0
- data/lib/active_utils/network_connection_retries.rb +78 -0
- data/lib/active_utils/post_data.rb +24 -0
- data/lib/active_utils/posts_data.rb +78 -0
- data/lib/active_utils/requires_parameters.rb +16 -0
- data/lib/active_utils/utils.rb +20 -0
- data/lib/active_utils/validateable.rb +81 -0
- data/lib/active_utils/version.rb +1 -1
- data/lib/active_utils.rb +21 -16
- data/test/test_helper.rb +15 -4
- data/test/unit/connection_test.rb +15 -15
- data/test/unit/network_connection_retries_test.rb +62 -11
- data/test/unit/post_data_test.rb +6 -6
- data/test/unit/posts_data_test.rb +4 -4
- data/test/unit/utils_test.rb +1 -1
- data/test/unit/validateable_test.rb +1 -1
- data.tar.gz.sig +0 -0
- metadata +35 -6
- metadata.gz.sig +0 -0
@@ -1,50 +1,4 @@
|
|
1
|
-
|
2
|
-
class InvalidCurrencyCodeError < StandardError
|
3
|
-
end
|
1
|
+
require "active_utils/active_merchant_shim"
|
4
2
|
|
5
|
-
|
6
|
-
|
7
|
-
"AED", "ALL", "AMD", "ANG", "AOA", "ARS", "AUD", "AWG", "AZN", "BAM", "BBD", "BDT", "BGN", "BHD",
|
8
|
-
"BND", "BOB", "BRL", "BSD", "BTN", "BWP", "BYR", "BZD", "CAD", "CHF", "CLP", "CNY", "COP", "CRC",
|
9
|
-
"CZK", "DKK", "DOP", "DZD", "EGP", "ETB", "EUR", "FJD", "GBP", "GEL", "GHS", "GMD", "GTQ", "GYD",
|
10
|
-
"HKD", "HNL", "HRK", "HUF", "IDR", "ILS", "INR", "ISK", "JEP", "JMD", "JOD", "JPY", "KES", "KGS",
|
11
|
-
"KHR", "KRW", "KWD", "KYD", "KZT", "LBP", "LKR", "LTL", "LVL", "MAD", "MDL", "MGA", "MKD", "MMK",
|
12
|
-
"MNT", "MOP", "MUR", "MVR", "MXN", "MYR", "MZN", "NAD", "NGN", "NIO", "NOK", "NPR", "NZD", "OMR",
|
13
|
-
"PEN", "PGK", "PHP", "PKR", "PLN", "PYG", "QAR", "RON", "RSD", "RUB", "RWF", "SAR", "SCR", "SEK",
|
14
|
-
"SGD", "STD", "SYP", "THB", "TND", "TRY", "TTD", "TWD", "TZS", "UAH", "UGX", "USD", "UYU", "VEF",
|
15
|
-
"VND", "VUV", "WST", "XAF", "XCD", "XOF", "XPF", "ZAR", "ZMW"
|
16
|
-
]
|
17
|
-
|
18
|
-
NON_ISO_TO_ISO = {
|
19
|
-
"ARN" => "ARS",
|
20
|
-
"AZM" => "AZN",
|
21
|
-
"CHP" => "CLP",
|
22
|
-
"DHS" => "AED",
|
23
|
-
"ECD" => "XCD",
|
24
|
-
"GHC" => "GHS",
|
25
|
-
"JAD" => "JMD",
|
26
|
-
"JYE" => "JPY",
|
27
|
-
"KUD" => "KWD",
|
28
|
-
"MZM" => "MZN",
|
29
|
-
"NTD" => "TWD",
|
30
|
-
"NMP" => "MXN",
|
31
|
-
"RDD" => "DOP",
|
32
|
-
"RMB" => "CNY",
|
33
|
-
"SFR" => "CHF",
|
34
|
-
"SID" => "SGD",
|
35
|
-
"UKL" => "GBP",
|
36
|
-
"WON" => "KRW"
|
37
|
-
}
|
38
|
-
|
39
|
-
def self.standardize(code)
|
40
|
-
code = code.upcase unless code.nil?
|
41
|
-
|
42
|
-
return code if is_iso?(code)
|
43
|
-
NON_ISO_TO_ISO[code] || raise(InvalidCurrencyCodeError, "#{code} is not an ISO currency, nor can it be converted to one.")
|
44
|
-
end
|
45
|
-
|
46
|
-
def self.is_iso?(code)
|
47
|
-
ISO_CURRENCIES.include? code
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
3
|
+
ActiveUtils::Utils.deprecated(ActiveUtils::MOVED_FILE_MESSAGE)
|
4
|
+
require "active_utils/currency_code"
|
@@ -1,29 +1,4 @@
|
|
1
|
-
|
2
|
-
class ActiveMerchantError < StandardError #:nodoc:
|
3
|
-
end
|
1
|
+
require "active_utils/active_merchant_shim"
|
4
2
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
class RetriableConnectionError < ConnectionError # :nodoc:
|
9
|
-
end
|
10
|
-
|
11
|
-
class ResponseError < ActiveMerchantError # :nodoc:
|
12
|
-
attr_reader :response
|
13
|
-
|
14
|
-
def initialize(response, message = nil)
|
15
|
-
@response = response
|
16
|
-
@message = message
|
17
|
-
end
|
18
|
-
|
19
|
-
def to_s
|
20
|
-
"Failed with #{response.code} #{response.message if response.respond_to?(:message)}"
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
class ClientCertificateError < ActiveMerchantError # :nodoc
|
25
|
-
end
|
26
|
-
|
27
|
-
class InvalidResponseError < ActiveMerchantError # :nodoc
|
28
|
-
end
|
29
|
-
end
|
3
|
+
ActiveUtils::Utils.deprecated(ActiveUtils::MOVED_FILE_MESSAGE)
|
4
|
+
require "active_utils/error"
|
@@ -1,73 +1,4 @@
|
|
1
|
-
|
2
|
-
module NetworkConnectionRetries
|
3
|
-
DEFAULT_RETRIES = 3
|
4
|
-
DEFAULT_CONNECTION_ERRORS = {
|
5
|
-
EOFError => "The remote server dropped the connection",
|
6
|
-
Errno::ECONNRESET => "The remote server reset the connection",
|
7
|
-
Timeout::Error => "The connection to the remote server timed out",
|
8
|
-
Errno::ETIMEDOUT => "The connection to the remote server timed out",
|
9
|
-
SocketError => "The connection to the remote server could not be established",
|
10
|
-
OpenSSL::SSL::SSLError => "The SSL connection to the remote server could not be established"
|
11
|
-
}
|
1
|
+
require "active_utils/active_merchant_shim"
|
12
2
|
|
13
|
-
|
14
|
-
|
15
|
-
end
|
16
|
-
|
17
|
-
def retry_exceptions(options={})
|
18
|
-
connection_errors = DEFAULT_CONNECTION_ERRORS.merge(options[:connection_exceptions] || {})
|
19
|
-
|
20
|
-
retry_network_exceptions(options) do
|
21
|
-
begin
|
22
|
-
yield
|
23
|
-
rescue Errno::ECONNREFUSED => e
|
24
|
-
raise ActiveMerchant::RetriableConnectionError, "The remote server refused the connection"
|
25
|
-
rescue OpenSSL::X509::CertificateError => e
|
26
|
-
NetworkConnectionRetries.log(options[:logger], :error, e.message, options[:tag])
|
27
|
-
raise ActiveMerchant::ClientCertificateError, "The remote server did not accept the provided SSL certificate"
|
28
|
-
rescue Zlib::BufError => e
|
29
|
-
raise ActiveMerchant::InvalidResponseError, "The remote server replied with an invalid response"
|
30
|
-
rescue *connection_errors.keys => e
|
31
|
-
raise ActiveMerchant::ConnectionError, connection_errors[e.class]
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
private
|
37
|
-
|
38
|
-
def retry_network_exceptions(options = {})
|
39
|
-
initial_retries = options[:max_retries] || DEFAULT_RETRIES
|
40
|
-
retries = initial_retries
|
41
|
-
request_start = nil
|
42
|
-
|
43
|
-
begin
|
44
|
-
request_start = Time.now.to_f
|
45
|
-
result = yield
|
46
|
-
log_with_retry_details(options[:logger], initial_retries-retries + 1, Time.now.to_f - request_start, "success", options[:tag])
|
47
|
-
result
|
48
|
-
rescue ActiveMerchant::RetriableConnectionError => e
|
49
|
-
retries -= 1
|
50
|
-
|
51
|
-
log_with_retry_details(options[:logger], initial_retries-retries, Time.now.to_f - request_start, e.message, options[:tag])
|
52
|
-
retry unless retries.zero?
|
53
|
-
raise ActiveMerchant::ConnectionError, e.message
|
54
|
-
rescue ActiveMerchant::ConnectionError, ActiveMerchant::InvalidResponseError => e
|
55
|
-
retries -= 1
|
56
|
-
log_with_retry_details(options[:logger], initial_retries-retries, Time.now.to_f - request_start, e.message, options[:tag])
|
57
|
-
retry if (options[:retry_safe] || retry_safe) && !retries.zero?
|
58
|
-
raise
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
def self.log(logger, level, message, tag=nil)
|
63
|
-
tag ||= self.class.to_s
|
64
|
-
message = "[#{tag}] #{message}"
|
65
|
-
logger.send(level, message) if logger
|
66
|
-
end
|
67
|
-
|
68
|
-
private
|
69
|
-
def log_with_retry_details(logger, attempts, time, message, tag)
|
70
|
-
NetworkConnectionRetries.log(logger, :info, "connection_attempt=%d connection_request_time=%.4fs connection_msg=\"%s\"" % [attempts, time, message], tag)
|
71
|
-
end
|
72
|
-
end
|
73
|
-
end
|
3
|
+
ActiveUtils::Utils.deprecated(ActiveUtils::MOVED_FILE_MESSAGE)
|
4
|
+
require "active_utils/network_connection_retries"
|
@@ -1,24 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require "active_utils/active_merchant_shim"
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
class_attribute :required_fields, :instance_writer => false
|
6
|
-
self.required_fields = []
|
7
|
-
|
8
|
-
def []=(key, value)
|
9
|
-
return if value.blank? && !required?(key)
|
10
|
-
super
|
11
|
-
end
|
12
|
-
|
13
|
-
def to_post_data
|
14
|
-
collect { |key, value| "#{key}=#{CGI.escape(value.to_s)}" }.join("&")
|
15
|
-
end
|
16
|
-
|
17
|
-
alias_method :to_s, :to_post_data
|
18
|
-
|
19
|
-
private
|
20
|
-
def required?(key)
|
21
|
-
required_fields.include?(key)
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
3
|
+
ActiveUtils::Utils.deprecated(ActiveUtils::MOVED_FILE_MESSAGE)
|
4
|
+
require "active_utils/post_data"
|
@@ -1,77 +1,4 @@
|
|
1
|
-
|
2
|
-
module PostsData #:nodoc:
|
1
|
+
require "active_utils/active_merchant_shim"
|
3
2
|
|
4
|
-
|
5
|
-
|
6
|
-
base.ssl_strict = true
|
7
|
-
|
8
|
-
base.superclass_delegating_accessor :ssl_version
|
9
|
-
base.ssl_version = nil
|
10
|
-
|
11
|
-
base.class_attribute :retry_safe
|
12
|
-
base.retry_safe = false
|
13
|
-
|
14
|
-
base.superclass_delegating_accessor :open_timeout
|
15
|
-
base.open_timeout = 60
|
16
|
-
|
17
|
-
base.superclass_delegating_accessor :read_timeout
|
18
|
-
base.read_timeout = 60
|
19
|
-
|
20
|
-
base.superclass_delegating_accessor :max_retries
|
21
|
-
base.max_retries = Connection::MAX_RETRIES
|
22
|
-
|
23
|
-
base.superclass_delegating_accessor :logger
|
24
|
-
base.superclass_delegating_accessor :wiredump_device
|
25
|
-
end
|
26
|
-
|
27
|
-
def ssl_get(endpoint, headers={})
|
28
|
-
ssl_request(:get, endpoint, nil, headers)
|
29
|
-
end
|
30
|
-
|
31
|
-
def ssl_post(endpoint, data, headers = {})
|
32
|
-
ssl_request(:post, endpoint, data, headers)
|
33
|
-
end
|
34
|
-
|
35
|
-
def ssl_request(method, endpoint, data, headers)
|
36
|
-
handle_response(raw_ssl_request(method, endpoint, data, headers))
|
37
|
-
end
|
38
|
-
|
39
|
-
def raw_ssl_request(method, endpoint, data, headers = {})
|
40
|
-
logger.warn "#{self.class} using ssl_strict=false, which is insecure" if logger unless ssl_strict
|
41
|
-
|
42
|
-
connection = new_connection(endpoint)
|
43
|
-
connection.open_timeout = open_timeout
|
44
|
-
connection.read_timeout = read_timeout
|
45
|
-
connection.retry_safe = retry_safe
|
46
|
-
connection.verify_peer = ssl_strict
|
47
|
-
connection.ssl_version = ssl_version
|
48
|
-
connection.logger = logger
|
49
|
-
connection.max_retries = max_retries
|
50
|
-
connection.tag = self.class.name
|
51
|
-
connection.wiredump_device = wiredump_device
|
52
|
-
|
53
|
-
connection.pem = @options[:pem] if @options
|
54
|
-
connection.pem_password = @options[:pem_password] if @options
|
55
|
-
|
56
|
-
connection.ignore_http_status = @options[:ignore_http_status] if @options
|
57
|
-
|
58
|
-
connection.request(method, data, headers)
|
59
|
-
end
|
60
|
-
|
61
|
-
private
|
62
|
-
|
63
|
-
def new_connection(endpoint)
|
64
|
-
Connection.new(endpoint)
|
65
|
-
end
|
66
|
-
|
67
|
-
def handle_response(response)
|
68
|
-
case response.code.to_i
|
69
|
-
when 200...300
|
70
|
-
response.body
|
71
|
-
else
|
72
|
-
raise ResponseError.new(response)
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
end
|
77
|
-
end
|
3
|
+
ActiveUtils::Utils.deprecated(ActiveUtils::MOVED_FILE_MESSAGE)
|
4
|
+
require "active_utils/posts_data"
|
@@ -1,16 +1,4 @@
|
|
1
|
-
|
2
|
-
module RequiresParameters #:nodoc:
|
3
|
-
def requires!(hash, *params)
|
4
|
-
params.each do |param|
|
5
|
-
if param.is_a?(Array)
|
6
|
-
raise ArgumentError.new("Missing required parameter: #{param.first}") unless hash.has_key?(param.first)
|
1
|
+
require "active_utils/active_merchant_shim"
|
7
2
|
|
8
|
-
|
9
|
-
|
10
|
-
else
|
11
|
-
raise ArgumentError.new("Missing required parameter: #{param}") unless hash.has_key?(param)
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
3
|
+
ActiveUtils::Utils.deprecated(ActiveUtils::MOVED_FILE_MESSAGE)
|
4
|
+
require "active_utils/requires_parameters"
|
@@ -1,20 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require "active_utils/active_merchant_shim"
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
def generate_unique_id
|
6
|
-
SecureRandom.hex(16)
|
7
|
-
end
|
8
|
-
|
9
|
-
module_function :generate_unique_id
|
10
|
-
|
11
|
-
def deprecated(message)
|
12
|
-
warning = Kernel.caller[1] + message
|
13
|
-
if respond_to?(:logger) && logger.present?
|
14
|
-
logger.warn(warning)
|
15
|
-
else
|
16
|
-
warn(warning)
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
3
|
+
ActiveUtils::Utils.deprecated(ActiveUtils::MOVED_FILE_MESSAGE)
|
4
|
+
require "active_utils/utils"
|
@@ -1,81 +1,4 @@
|
|
1
|
-
|
2
|
-
module Validateable #:nodoc:
|
3
|
-
def valid?
|
4
|
-
errors.clear
|
1
|
+
require "active_utils/active_merchant_shim"
|
5
2
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
errors.empty?
|
10
|
-
end
|
11
|
-
|
12
|
-
def initialize(attributes = {})
|
13
|
-
self.attributes = attributes
|
14
|
-
end
|
15
|
-
|
16
|
-
def errors
|
17
|
-
@errors ||= Errors.new(self)
|
18
|
-
end
|
19
|
-
|
20
|
-
private
|
21
|
-
|
22
|
-
def attributes=(attributes)
|
23
|
-
unless attributes.nil?
|
24
|
-
for key, value in attributes
|
25
|
-
send("#{key}=", value )
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
# This hash keeps the errors of the object
|
31
|
-
class Errors < HashWithIndifferentAccess
|
32
|
-
|
33
|
-
def initialize(base)
|
34
|
-
super() { |h, k| h[k] = [] ; h[k] }
|
35
|
-
@base = base
|
36
|
-
end
|
37
|
-
|
38
|
-
def count
|
39
|
-
size
|
40
|
-
end
|
41
|
-
|
42
|
-
def empty?
|
43
|
-
all? { |k, v| v && v.empty? }
|
44
|
-
end
|
45
|
-
|
46
|
-
# returns a specific fields error message.
|
47
|
-
# if more than one error is available we will only return the first. If no error is available
|
48
|
-
# we return an empty string
|
49
|
-
def on(field)
|
50
|
-
self[field].to_a.first
|
51
|
-
end
|
52
|
-
|
53
|
-
def add(field, error)
|
54
|
-
self[field] << error
|
55
|
-
end
|
56
|
-
|
57
|
-
def add_to_base(error)
|
58
|
-
add(:base, error)
|
59
|
-
end
|
60
|
-
|
61
|
-
def each_full
|
62
|
-
full_messages.each { |msg| yield msg }
|
63
|
-
end
|
64
|
-
|
65
|
-
def full_messages
|
66
|
-
result = []
|
67
|
-
|
68
|
-
self.each do |key, messages|
|
69
|
-
next if messages.blank?
|
70
|
-
if key == 'base'
|
71
|
-
result << "#{messages.first}"
|
72
|
-
else
|
73
|
-
result << "#{key.to_s.humanize} #{messages.first}"
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
result
|
78
|
-
end
|
79
|
-
end
|
80
|
-
end
|
81
|
-
end
|
3
|
+
ActiveUtils::Utils.deprecated(ActiveUtils::MOVED_FILE_MESSAGE)
|
4
|
+
require "active_utils/validateable"
|
@@ -0,0 +1,170 @@
|
|
1
|
+
require 'uri'
|
2
|
+
require 'net/http'
|
3
|
+
require 'net/https'
|
4
|
+
require 'benchmark'
|
5
|
+
|
6
|
+
module ActiveUtils
|
7
|
+
class Connection
|
8
|
+
include NetworkConnectionRetries
|
9
|
+
|
10
|
+
MAX_RETRIES = 3
|
11
|
+
OPEN_TIMEOUT = 60
|
12
|
+
READ_TIMEOUT = 60
|
13
|
+
VERIFY_PEER = true
|
14
|
+
CA_FILE = (File.dirname(__FILE__) + '/../../certs/cacert.pem')
|
15
|
+
CA_PATH = nil
|
16
|
+
RETRY_SAFE = false
|
17
|
+
RUBY_184_POST_HEADERS = { "Content-Type" => "application/x-www-form-urlencoded" }
|
18
|
+
|
19
|
+
attr_accessor :endpoint
|
20
|
+
attr_accessor :open_timeout
|
21
|
+
attr_accessor :read_timeout
|
22
|
+
attr_accessor :verify_peer
|
23
|
+
attr_accessor :ssl_version
|
24
|
+
attr_accessor :ca_file
|
25
|
+
attr_accessor :ca_path
|
26
|
+
attr_accessor :retry_safe
|
27
|
+
attr_accessor :pem
|
28
|
+
attr_accessor :pem_password
|
29
|
+
attr_accessor :wiredump_device
|
30
|
+
attr_accessor :logger
|
31
|
+
attr_accessor :tag
|
32
|
+
attr_accessor :ignore_http_status
|
33
|
+
attr_accessor :max_retries
|
34
|
+
attr_accessor :proxy_address
|
35
|
+
attr_accessor :proxy_port
|
36
|
+
|
37
|
+
def initialize(endpoint)
|
38
|
+
@endpoint = endpoint.is_a?(URI) ? endpoint : URI.parse(endpoint)
|
39
|
+
@open_timeout = OPEN_TIMEOUT
|
40
|
+
@read_timeout = READ_TIMEOUT
|
41
|
+
@retry_safe = RETRY_SAFE
|
42
|
+
@verify_peer = VERIFY_PEER
|
43
|
+
@ca_file = CA_FILE
|
44
|
+
@ca_path = CA_PATH
|
45
|
+
@max_retries = MAX_RETRIES
|
46
|
+
@ignore_http_status = false
|
47
|
+
@ssl_version = nil
|
48
|
+
@proxy_address = nil
|
49
|
+
@proxy_port = nil
|
50
|
+
end
|
51
|
+
|
52
|
+
def request(method, body, headers = {})
|
53
|
+
request_start = Time.now.to_f
|
54
|
+
|
55
|
+
retry_exceptions(:max_retries => max_retries, :logger => logger, :tag => tag) do
|
56
|
+
begin
|
57
|
+
info "connection_http_method=#{method.to_s.upcase} connection_uri=#{endpoint}", tag
|
58
|
+
|
59
|
+
result = nil
|
60
|
+
|
61
|
+
realtime = Benchmark.realtime do
|
62
|
+
result = case method
|
63
|
+
when :get
|
64
|
+
raise ArgumentError, "GET requests do not support a request body" if body
|
65
|
+
http.get(endpoint.request_uri, headers)
|
66
|
+
when :post
|
67
|
+
debug body
|
68
|
+
http.post(endpoint.request_uri, body, RUBY_184_POST_HEADERS.merge(headers))
|
69
|
+
when :put
|
70
|
+
debug body
|
71
|
+
http.put(endpoint.request_uri, body, headers)
|
72
|
+
when :delete
|
73
|
+
# It's kind of ambiguous whether the RFC allows bodies
|
74
|
+
# for DELETE requests. But Net::HTTP's delete method
|
75
|
+
# very unambiguously does not.
|
76
|
+
raise ArgumentError, "DELETE requests do not support a request body" if body
|
77
|
+
http.delete(endpoint.request_uri, headers)
|
78
|
+
else
|
79
|
+
raise ArgumentError, "Unsupported request method #{method.to_s.upcase}"
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
info "--> %d %s (%d %.4fs)" % [result.code, result.message, result.body ? result.body.length : 0, realtime], tag
|
84
|
+
debug result.body
|
85
|
+
result
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
ensure
|
90
|
+
info "connection_request_total_time=%.4fs" % [Time.now.to_f - request_start], tag
|
91
|
+
end
|
92
|
+
|
93
|
+
private
|
94
|
+
def http
|
95
|
+
http = Net::HTTP.new(endpoint.host, endpoint.port, proxy_address, proxy_port)
|
96
|
+
configure_debugging(http)
|
97
|
+
configure_timeouts(http)
|
98
|
+
configure_ssl(http)
|
99
|
+
configure_cert(http)
|
100
|
+
http
|
101
|
+
end
|
102
|
+
|
103
|
+
def configure_debugging(http)
|
104
|
+
http.set_debug_output(wiredump_device)
|
105
|
+
end
|
106
|
+
|
107
|
+
def configure_timeouts(http)
|
108
|
+
http.open_timeout = open_timeout
|
109
|
+
http.read_timeout = read_timeout
|
110
|
+
end
|
111
|
+
|
112
|
+
def configure_ssl(http)
|
113
|
+
return unless endpoint.scheme == "https"
|
114
|
+
|
115
|
+
http.use_ssl = true
|
116
|
+
http.ssl_version = ssl_version if ssl_version
|
117
|
+
|
118
|
+
if verify_peer
|
119
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
120
|
+
http.ca_file = ca_file
|
121
|
+
http.ca_path = ca_path
|
122
|
+
else
|
123
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
124
|
+
end
|
125
|
+
|
126
|
+
end
|
127
|
+
|
128
|
+
def configure_cert(http)
|
129
|
+
return if pem.blank?
|
130
|
+
|
131
|
+
http.cert = OpenSSL::X509::Certificate.new(pem)
|
132
|
+
|
133
|
+
if pem_password
|
134
|
+
http.key = OpenSSL::PKey::RSA.new(pem, pem_password)
|
135
|
+
else
|
136
|
+
http.key = OpenSSL::PKey::RSA.new(pem)
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
def handle_response(response)
|
141
|
+
if @ignore_http_status then
|
142
|
+
return response.body
|
143
|
+
else
|
144
|
+
case response.code.to_i
|
145
|
+
when 200...300
|
146
|
+
response.body
|
147
|
+
else
|
148
|
+
raise ResponseError.new(response)
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
def debug(message, tag = nil)
|
154
|
+
log(:debug, message, tag)
|
155
|
+
end
|
156
|
+
|
157
|
+
def info(message, tag = nil)
|
158
|
+
log(:info, message, tag)
|
159
|
+
end
|
160
|
+
|
161
|
+
def error(message, tag = nil)
|
162
|
+
log(:error, message, tag)
|
163
|
+
end
|
164
|
+
|
165
|
+
def log(level, message, tag)
|
166
|
+
message = "[#{tag}] #{message}" if tag
|
167
|
+
logger.send(level, message) if logger
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|