nice_http 1.8.10 → 1.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,122 @@
1
+ module NiceHttpHttpMethods
2
+
3
+ ######################################################
4
+ # Post data to path
5
+ # @param arguments [Hash] containing at least keys :data and :path.
6
+ # In case :data not supplied and :data_examples array supplied, it will be taken the first example as :data.
7
+ # @param arguments [Array<path, data, additional_headers>]
8
+ # path (string).
9
+ # data (json data for example).
10
+ # additional_headers (Hash key=>value).
11
+ # @return [Hash] response
12
+ # Including at least the symbol keys:
13
+ # :data = the response data body.
14
+ # :message = plain text response.
15
+ # :code = code response (200=ok,500=wrong...).
16
+ # All keys in response are lowercase.
17
+ # data, message and code can also be accessed as attributes like .message .code .data.
18
+ # In case of fatal error returns { fatal_error: "the error description", code: nil, message: nil, data: '' }
19
+ # @example
20
+ # resp = @http.post(Requests::Customer.update_customer)
21
+ # assert resp.code == 201
22
+ # @example
23
+ # resp = http.post( {
24
+ # path: "/api/users",
25
+ # data: {name: "morpheus", job: "leader"}
26
+ # } )
27
+ # pp resp.data.json
28
+ ######################################################
29
+ def post(*arguments)
30
+ begin
31
+ path, data, headers_t = manage_request(*arguments)
32
+ @start_time = Time.now if @start_time.nil?
33
+ if arguments.size > 0 and arguments[0].kind_of?(Hash)
34
+ arg = arguments[0]
35
+ if @use_mocks and arg.kind_of?(Hash) and arg.keys.include?(:mock_response)
36
+ data = ""
37
+ if arg[:mock_response].keys.include?(:data)
38
+ data = arg[:mock_response][:data]
39
+ if data.kind_of?(Hash) #to json
40
+ begin
41
+ require "json"
42
+ data = data.to_json
43
+ rescue
44
+ @logger.fatal "There was a problem converting to json: #{data}"
45
+ end
46
+ end
47
+ end
48
+ @logger.warn "Pay attention!!! This is a mock response:"
49
+ @start_time_net = Time.now if @start_time_net.nil?
50
+ manage_response(arg[:mock_response], data.to_s)
51
+ return @response
52
+ end
53
+ end
54
+
55
+ begin
56
+ @start_time_net = Time.now if @start_time_net.nil?
57
+ if headers_t["Content-Type"] == "multipart/form-data"
58
+ require "net/http/post/multipart"
59
+ headers_t.each { |key, value|
60
+ arguments[0][:data].add_field(key, value) #add to Headers
61
+ }
62
+ resp = @http.request(arguments[0][:data])
63
+ elsif headers_t["Content-Type"].to_s.include?("application/x-www-form-urlencoded")
64
+ encoded_form = URI.encode_www_form(arguments[0][:data])
65
+ resp = @http.request_post(path, encoded_form, headers_t)
66
+ data = resp.body
67
+ else
68
+ resp = @http.post(path, data, headers_t)
69
+ #todo: do it also for forms and multipart
70
+ if (resp.code == 401 or resp.code == 408) and @headers_orig.values.map(&:class).include?(Proc)
71
+ try = false
72
+ @headers_orig.each do |k, v|
73
+ if v.is_a?(Proc) and headers_t.key?(k)
74
+ try = true
75
+ headers_t[k] = v.call
76
+ end
77
+ end
78
+ if try
79
+ @logger.warn "Not authorized. Trying to generate a new token."
80
+ resp = @http.post(path, data, headers_t)
81
+ end
82
+ end
83
+ data = resp.body
84
+ end
85
+ rescue Exception => stack
86
+ @logger.warn stack
87
+ if !@timeout.nil? and (Time.now - @start_time_net) > @timeout
88
+ @logger.warn "The connection seems to be closed in the host machine. Timeout."
89
+ return { fatal_error: "Net::ReadTimeout", code: nil, message: nil, data: "" }
90
+ else
91
+ @logger.warn "The connection seems to be closed in the host machine. Trying to reconnect"
92
+ @http.finish()
93
+ @http.start()
94
+ @start_time_net = Time.now if @start_time_net.nil?
95
+ @headers_orig.each { |k, v| headers_t[k] = v.call if v.is_a?(Proc) and headers_t.key?(k) }
96
+ resp, data = @http.post(path, data, headers_t)
97
+ end
98
+ end
99
+ manage_response(resp, data)
100
+ if @auto_redirect and @response[:code].to_i >= 300 and @response[:code].to_i < 400 and @response.include?(:location)
101
+ if @num_redirects <= 30
102
+ @num_redirects += 1
103
+ current_server = "http"
104
+ current_server += "s" if @ssl == true
105
+ current_server += "://#{@host}"
106
+ location = @response[:location].gsub(current_server, "")
107
+ @logger.info "(#{@num_redirects}) Redirecting NiceHttp to #{location}"
108
+ get(location)
109
+ else
110
+ @logger.fatal "(#{@num_redirects}) Maximum number of redirections for a single request reached. Be sure everything is correct, it seems there is a non ending loop"
111
+ @num_redirects = 0
112
+ end
113
+ else
114
+ @num_redirects = 0
115
+ end
116
+ return @response
117
+ rescue Exception => stack
118
+ @logger.fatal stack
119
+ return { fatal_error: stack.to_s, code: nil, message: nil, data: "" }
120
+ end
121
+ end
122
+ end
@@ -0,0 +1,87 @@
1
+ module NiceHttpHttpMethods
2
+
3
+ ######################################################
4
+ # Put data to path
5
+ # @param arguments [Hash] containing at least keys :data and :path.
6
+ # In case :data not supplied and :data_examples array supplied, it will be taken the first example as :data.
7
+ # @param arguments [Array<path, data, additional_headers>]
8
+ # path (string).
9
+ # data (json data for example).
10
+ # additional_headers (Hash key=>value).
11
+ # @return [Hash] response
12
+ # Including at least the symbol keys:
13
+ # :data = the response data body.
14
+ # :message = plain text response.
15
+ # :code = code response (200=ok,500=wrong...).
16
+ # All keys in response are lowercase.
17
+ # data, message and code can also be accessed as attributes like .message .code .data.
18
+ # In case of fatal error returns { fatal_error: "the error description", code: nil, message: nil, data: '' }
19
+ # @example
20
+ # resp = @http.put(Requests::Customer.remove_phone)
21
+ ######################################################
22
+ def put(*arguments)
23
+ begin
24
+ path, data, headers_t = manage_request(*arguments)
25
+ @start_time = Time.now if @start_time.nil?
26
+ if arguments.size > 0 and arguments[0].kind_of?(Hash)
27
+ arg = arguments[0]
28
+ if @use_mocks and arg.kind_of?(Hash) and arg.keys.include?(:mock_response)
29
+ data = ""
30
+ if arg[:mock_response].keys.include?(:data)
31
+ data = arg[:mock_response][:data]
32
+ if data.kind_of?(Hash) #to json
33
+ begin
34
+ require "json"
35
+ data = data.to_json
36
+ rescue
37
+ @logger.fatal "There was a problem converting to json: #{data}"
38
+ end
39
+ end
40
+ end
41
+ @logger.warn "Pay attention!!! This is a mock response:"
42
+ @start_time_net = Time.now if @start_time_net.nil?
43
+ manage_response(arg[:mock_response], data.to_s)
44
+ return @response
45
+ end
46
+ end
47
+
48
+ begin
49
+ @start_time_net = Time.now if @start_time_net.nil?
50
+ resp = @http.send_request("PUT", path, data, headers_t)
51
+ if (resp.code == 401 or resp.code == 408) and @headers_orig.values.map(&:class).include?(Proc)
52
+ try = false
53
+ @headers_orig.each do |k, v|
54
+ if v.is_a?(Proc) and headers_t.key?(k)
55
+ try = true
56
+ headers_t[k] = v.call
57
+ end
58
+ end
59
+ if try
60
+ @logger.warn "Not authorized. Trying to generate a new token."
61
+ resp = @http.send_request("PUT", path, data, headers_t)
62
+ end
63
+ end
64
+ data = resp.body
65
+ rescue Exception => stack
66
+ @logger.warn stack
67
+ if !@timeout.nil? and (Time.now - @start_time_net) > @timeout
68
+ @logger.warn "The connection seems to be closed in the host machine. Timeout."
69
+ return { fatal_error: "Net::ReadTimeout", code: nil, message: nil, data: "" }
70
+ else
71
+ @logger.warn "The connection seems to be closed in the host machine. Trying to reconnect"
72
+ @http.finish()
73
+ @http.start()
74
+ @headers_orig.each { |k, v| headers_t[k] = v.call if v.is_a?(Proc) and headers_t.key?(k) }
75
+ @start_time_net = Time.now if @start_time_net.nil?
76
+ resp, data = @http.send_request("PUT", path, data, headers_t)
77
+ end
78
+ end
79
+ manage_response(resp, data)
80
+
81
+ return @response
82
+ rescue Exception => stack
83
+ @logger.fatal stack
84
+ return { fatal_error: stack.to_s, code: nil, message: nil, data: "" }
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,47 @@
1
+ module NiceHttpHttpMethods
2
+
3
+ ######################################################
4
+ # It will send the request depending on the :method declared on the request hash
5
+ # Take a look at https://github.com/MarioRuiz/Request-Hash
6
+ #
7
+ # @param request_hash [Hash] containing at least key :path and :method. The methods that are accepted are: :get, :head, :post, :put, :delete, :patch
8
+ #
9
+ # @return [Hash] response
10
+ # Including at least the symbol keys:
11
+ # :data = the response data body.
12
+ # :message = plain text response.
13
+ # :code = code response (200=ok,500=wrong...).
14
+ # All keys in response are lowercase.
15
+ # data, message and code can also be accessed as attributes like .message .code .data.
16
+ # In case of fatal error returns { fatal_error: "the error description", code: nil, message: nil, data: '' }
17
+ # @example
18
+ # resp = @http.send_request Requests::Customer.remove_session
19
+ # assert resp.code == 204
20
+ ######################################################
21
+ def send_request(request_hash)
22
+ unless request_hash.is_a?(Hash) and request_hash.key?(:method) and request_hash.key?(:path) and
23
+ request_hash[:method].is_a?(Symbol) and
24
+ [:get, :head, :post, :put, :delete, :patch].include?(request_hash[:method])
25
+ message = "send_request: it needs to be supplied a Request Hash that includes a :method and :path. "
26
+ message += "Supported methods: :get, :head, :post, :put, :delete, :patch"
27
+ @logger.fatal message
28
+ return { fatal_error: message, code: nil, message: nil }
29
+ else
30
+ case request_hash[:method]
31
+ when :get
32
+ resp = get request_hash
33
+ when :post
34
+ resp = post request_hash
35
+ when :head
36
+ resp = head request_hash
37
+ when :put
38
+ resp = put request_hash
39
+ when :delete
40
+ resp = delete request_hash
41
+ when :patch
42
+ resp = patch request_hash
43
+ end
44
+ return resp
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,54 @@
1
+ class NiceHttp
2
+ ######################################################
3
+ # to reset to the original defaults
4
+ ######################################################
5
+ def self.reset!
6
+ @host = nil
7
+ @port = 80
8
+ @ssl = false
9
+ @timeout = nil
10
+ @headers = {}
11
+ @values_for = {}
12
+ @debug = false
13
+ @log = :fix_file
14
+ @log_path = ""
15
+ @log_headers = :all
16
+ @proxy_host = nil
17
+ @proxy_port = nil
18
+ @last_request = nil
19
+ @request = nil
20
+ @requests = nil
21
+ @last_response = nil
22
+ @request_id = ""
23
+ @use_mocks = false
24
+ @connections = []
25
+ @active = 0
26
+ @auto_redirect = true
27
+ @log_files = {}
28
+ @create_stats = false
29
+ @stats = {
30
+ all: {
31
+ num_requests: 0,
32
+ started: nil,
33
+ finished: nil,
34
+ real_time_elapsed: 0,
35
+ time_elapsed: {
36
+ total: 0,
37
+ maximum: 0,
38
+ minimum: 1000000,
39
+ average: 0,
40
+ },
41
+ method: {},
42
+ },
43
+ path: {},
44
+ name: {},
45
+ }
46
+ @capture = false
47
+ @captured = []
48
+ @async_wait_seconds = 0
49
+ @async_header = "location"
50
+ @async_completed = ""
51
+ @async_resource = ""
52
+ @async_status = ""
53
+ end
54
+ end
@@ -0,0 +1,37 @@
1
+ class NiceHttp
2
+ ######################################################
3
+ # It will save the NiceHttp.stats on different files, each key of the hash in a different file.
4
+ #
5
+ # @param file_name [String] path and file name to be used to store the stats.
6
+ # In case no one supplied it will be used the value in NiceHttp.log and it will be saved on YAML format.
7
+ # In case extension is .yaml will be saved on YAML format.
8
+ # In case extension is .json will be saved on JSON format.
9
+ #
10
+ # @example
11
+ # NiceHttp.save_stats
12
+ # NiceHttp.save_stats('./stats/my_stats.yaml')
13
+ # NiceHttp.save_stats('./stats/my_stats.json')
14
+ ######################################################
15
+ def self.save_stats(file_name = "")
16
+ if file_name == ""
17
+ if self.log.is_a?(String)
18
+ file_name = self.log
19
+ else
20
+ file_name = "./#{self.log_path}nice_http.log"
21
+ end
22
+ end
23
+ require "fileutils"
24
+ FileUtils.mkdir_p File.dirname(file_name)
25
+ if file_name.match?(/\.json$/)
26
+ require "json"
27
+ self.stats.keys.each do |key|
28
+ File.open("#{file_name.gsub(/.json$/, "_stats_")}#{key}.json", "w") { |file| file.write(self.stats[key].to_json) }
29
+ end
30
+ else
31
+ require "yaml"
32
+ self.stats.keys.each do |key|
33
+ File.open("#{file_name.gsub(/.\w+$/, "_stats_")}#{key}.yaml", "w") { |file| file.write(self.stats[key].to_yaml) }
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,18 @@
1
+ module NiceHttpUtils
2
+ ##################################################
3
+ # returns the seed for Basic authentication
4
+ # @param user [String]
5
+ # @param password [String]
6
+ # @param strict [Boolean] (default: false) use strict_encode64 if true, if not encode64
7
+ # @return [String] seed string to be used on Authorization key header on a get request
8
+ ####################################################
9
+ def self.basic_authentication(user:, password:, strict: false)
10
+ require "base64"
11
+ if strict
12
+ seed = "Basic " + Base64.strict_encode64(user + ":" + password)
13
+ else
14
+ seed = "Basic " + Base64.encode64(user + ":" + password)
15
+ end
16
+ return seed
17
+ end
18
+ end
@@ -60,49 +60,4 @@ module NiceHttpUtils
60
60
  return ret
61
61
  end
62
62
  end
63
-
64
- ##################################################
65
- # set a value on xml tag
66
- # @param tag_name [String]
67
- # @param xml_string [String]
68
- # @param value [String]
69
- # @param take_off_prefix [Boolean] (optional). true, false(default)
70
- # @return [String] with the new value
71
- ####################################################
72
- def self.set_value_xml_tag(tag_name, xml_string, value, take_off_prefix = false)
73
- tag_name = tag_name.to_s
74
- if take_off_prefix
75
- i = tag_name.index(":")
76
- tag_name = tag_name[i + 1..tag_name.length] unless i.nil?
77
- end
78
- if xml_string.to_s != ""
79
- if take_off_prefix
80
- old_value = NiceHttpUtils.get_value_xml_tag(tag_name, xml_string.dup, true)
81
- xml_string.gsub!(/:#{tag_name}>#{Regexp.escape(old_value)}<\//i, ":" + tag_name + ">" + value + "</")
82
- xml_string.gsub!(/<#{tag_name}>#{Regexp.escape(old_value)}<\//i, "<" + tag_name + ">" + value + "</")
83
- else
84
- xml_string.gsub!(/<#{tag_name}>.*<\/#{tag_name}>/i, "<" + tag_name + ">" + value + "</" + tag_name + ">")
85
- end
86
- return xml_string
87
- else
88
- return ""
89
- end
90
- end
91
-
92
- ##################################################
93
- # returns the seed for Basic authentication
94
- # @param user [String]
95
- # @param password [String]
96
- # @param strict [Boolean] (default: false) use strict_encode64 if true, if not encode64
97
- # @return [String] seed string to be used on Authorization key header on a get request
98
- ####################################################
99
- def self.basic_authentication(user:, password:, strict: false)
100
- require "base64"
101
- if strict
102
- seed = "Basic " + Base64.strict_encode64(user + ":" + password)
103
- else
104
- seed = "Basic " + Base64.encode64(user + ":" + password)
105
- end
106
- return seed
107
- end
108
63
  end
@@ -0,0 +1,30 @@
1
+ module NiceHttpUtils
2
+
3
+ ##################################################
4
+ # set a value on xml tag
5
+ # @param tag_name [String]
6
+ # @param xml_string [String]
7
+ # @param value [String]
8
+ # @param take_off_prefix [Boolean] (optional). true, false(default)
9
+ # @return [String] with the new value
10
+ ####################################################
11
+ def self.set_value_xml_tag(tag_name, xml_string, value, take_off_prefix = false)
12
+ tag_name = tag_name.to_s
13
+ if take_off_prefix
14
+ i = tag_name.index(":")
15
+ tag_name = tag_name[i + 1..tag_name.length] unless i.nil?
16
+ end
17
+ if xml_string.to_s != ""
18
+ if take_off_prefix
19
+ old_value = NiceHttpUtils.get_value_xml_tag(tag_name, xml_string.dup, true)
20
+ xml_string.gsub!(/:#{tag_name}>#{Regexp.escape(old_value)}<\//i, ":" + tag_name + ">" + value + "</")
21
+ xml_string.gsub!(/<#{tag_name}>#{Regexp.escape(old_value)}<\//i, "<" + tag_name + ">" + value + "</")
22
+ else
23
+ xml_string.gsub!(/<#{tag_name}>.*<\/#{tag_name}>/i, "<" + tag_name + ">" + value + "</" + tag_name + ">")
24
+ end
25
+ return xml_string
26
+ else
27
+ return ""
28
+ end
29
+ end
30
+ end