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.
@@ -31,7 +31,7 @@ module NiceHttpManageResponse
31
31
 
32
32
  begin
33
33
  # this is to be able to access all keys as symbols on Ruby < 2.6.0
34
- if RUBY_VERSION < '2.6.0'
34
+ if RUBY_VERSION < "2.6.0"
35
35
  new_resp = Hash.new()
36
36
  resp.each { |key, value|
37
37
  if key.kind_of?(String)
@@ -107,11 +107,11 @@ module NiceHttpManageResponse
107
107
  if key.kind_of?(Symbol)
108
108
  if key == :code or key == :data or key == :header or key == :message
109
109
  if key == :data and !@response[:'content-type'].to_s.include?("text/html")
110
- if key == :data and
111
- (!@response[:'content-type'].include?('text') and
112
- !@response[:'content-type'].include?('json') and
113
- !@response[:'content-type'].include?('xml') and
114
- !@response[:'content-type'].include?('charset=utf-8'))
110
+ if key == :data and
111
+ (!@response[:'content-type'].include?("text") and
112
+ !@response[:'content-type'].include?("json") and
113
+ !@response[:'content-type'].include?("xml") and
114
+ !@response[:'content-type'].include?("charset=utf-8"))
115
115
  message += "\n data: It's not text data so won't be in the logs."
116
116
  else
117
117
  begin
@@ -185,6 +185,7 @@ module NiceHttpManageResponse
185
185
  end
186
186
  end
187
187
  end
188
+ @response = wait_async_operation() if @response[:code] == "202"
188
189
  @prev_response = @response
189
190
  rescue Exception => stack
190
191
  @logger.fatal stack
@@ -192,109 +193,4 @@ module NiceHttpManageResponse
192
193
  end
193
194
  @start_time = nil
194
195
  end
195
-
196
- private
197
-
198
- def set_stats(hash)
199
- unless hash.key?(:num_requests)
200
- # to add to the end the previous keys so num_requests and time_elapsed come first
201
- keys = hash.keys
202
- hash.keys.each do |k|
203
- hash.delete(k)
204
- end
205
-
206
- hash[:num_requests] = 0
207
- hash[:started] = @start_time
208
- hash[:finished] = @start_time
209
- hash[:real_time_elapsed] = 0
210
- hash[:time_elapsed] = {
211
- total: 0,
212
- maximum: 0,
213
- minimum: 100000,
214
- average: 0,
215
- }
216
-
217
- # to add to the end the previous keys so num_requests and time_elapsed come first
218
- keys.each do |k|
219
- hash[k] = {}
220
- end
221
- end
222
- hash[:num_requests] += 1
223
- hash[:started] = hash[:finished] = @start_time if hash[:started].nil?
224
-
225
- if @start_time < hash[:finished]
226
- hash[:real_time_elapsed] += (@finish_time - hash[:finished])
227
- else
228
- hash[:real_time_elapsed] += (@finish_time - @start_time)
229
- end
230
- hash[:finished] = @finish_time
231
-
232
- hash[:time_elapsed][:total] += @response[:time_elapsed]
233
- hash[:time_elapsed][:maximum] = @response[:time_elapsed] if @response[:time_elapsed] > hash[:time_elapsed][:maximum]
234
- hash[:time_elapsed][:minimum] = @response[:time_elapsed] if @response[:time_elapsed] < hash[:time_elapsed][:minimum]
235
- hash[:time_elapsed][:average] = hash[:time_elapsed][:total] / hash[:num_requests]
236
- end
237
-
238
- private
239
-
240
- def create_stats(resp)
241
- # all
242
- set_stats(self.class.stats[:all])
243
- # all method
244
- unless self.class.stats[:all][:method].key?(@prev_request[:method])
245
- self.class.stats[:all][:method][@prev_request[:method]] = {
246
- response: {},
247
- }
248
- end
249
- set_stats(self.class.stats[:all][:method][@prev_request[:method]])
250
- # all method response
251
- unless self.class.stats[:all][:method][@prev_request[:method]][:response].key?(resp.code)
252
- self.class.stats[:all][:method][@prev_request[:method]][:response][resp.code] = {}
253
- end
254
- set_stats(self.class.stats[:all][:method][@prev_request[:method]][:response][resp.code])
255
-
256
- # server
257
- server = "#{@host}:#{@port}"
258
- unless self.class.stats[:path].key?(server)
259
- self.class.stats[:path][server] = {}
260
- end
261
- set_stats(self.class.stats[:path][server])
262
- # server path
263
- unless self.class.stats[:path][server].key?(@prev_request[:path])
264
- self.class.stats[:path][server][@prev_request[:path]] = { method: {} }
265
- end
266
- set_stats(self.class.stats[:path][server][@prev_request[:path]])
267
- # server path method
268
- unless self.class.stats[:path][server][@prev_request[:path]][:method].key?(@prev_request[:method])
269
- self.class.stats[:path][server][@prev_request[:path]][:method][@prev_request[:method]] = {
270
- response: {},
271
- }
272
- end
273
- set_stats(self.class.stats[:path][server][@prev_request[:path]][:method][@prev_request[:method]])
274
- # server path method response
275
- unless self.class.stats[:path][server][@prev_request[:path]][:method][@prev_request[:method]][:response].key?(resp.code)
276
- self.class.stats[:path][server][@prev_request[:path]][:method][@prev_request[:method]][:response][resp.code] = {}
277
- end
278
- set_stats(self.class.stats[:path][server][@prev_request[:path]][:method][@prev_request[:method]][:response][resp.code])
279
-
280
- if @prev_request.key?(:name)
281
- # name
282
- unless self.class.stats[:name].key?(@prev_request[:name])
283
- self.class.stats[:name][@prev_request[:name]] = { method: {} }
284
- end
285
- set_stats(self.class.stats[:name][@prev_request[:name]])
286
- # name method
287
- unless self.class.stats[:name][@prev_request[:name]][:method].key?(@prev_request[:method])
288
- self.class.stats[:name][@prev_request[:name]][:method][@prev_request[:method]] = {
289
- response: {},
290
- }
291
- end
292
- set_stats(self.class.stats[:name][@prev_request[:name]][:method][@prev_request[:method]])
293
- # name method response
294
- unless self.class.stats[:name][@prev_request[:name]][:method][@prev_request[:method]][:response].key?(resp.code)
295
- self.class.stats[:name][@prev_request[:name]][:method][@prev_request[:method]][:response][resp.code] = {}
296
- end
297
- set_stats(self.class.stats[:name][@prev_request[:name]][:method][@prev_request[:method]][:response][resp.code])
298
- end
299
- end
300
196
  end
@@ -0,0 +1,43 @@
1
+ module NiceHttpManageResponse
2
+ private
3
+
4
+ def set_stats(hash)
5
+ unless hash.key?(:num_requests)
6
+ # to add to the end the previous keys so num_requests and time_elapsed come first
7
+ keys = hash.keys
8
+ hash.keys.each do |k|
9
+ hash.delete(k)
10
+ end
11
+
12
+ hash[:num_requests] = 0
13
+ hash[:started] = @start_time
14
+ hash[:finished] = @start_time
15
+ hash[:real_time_elapsed] = 0
16
+ hash[:time_elapsed] = {
17
+ total: 0,
18
+ maximum: 0,
19
+ minimum: 100000,
20
+ average: 0,
21
+ }
22
+
23
+ # to add to the end the previous keys so num_requests and time_elapsed come first
24
+ keys.each do |k|
25
+ hash[k] = {}
26
+ end
27
+ end
28
+ hash[:num_requests] += 1
29
+ hash[:started] = hash[:finished] = @start_time if hash[:started].nil?
30
+
31
+ if @start_time < hash[:finished]
32
+ hash[:real_time_elapsed] += (@finish_time - hash[:finished])
33
+ else
34
+ hash[:real_time_elapsed] += (@finish_time - @start_time)
35
+ end
36
+ hash[:finished] = @finish_time
37
+
38
+ hash[:time_elapsed][:total] += @response[:time_elapsed]
39
+ hash[:time_elapsed][:maximum] = @response[:time_elapsed] if @response[:time_elapsed] > hash[:time_elapsed][:maximum]
40
+ hash[:time_elapsed][:minimum] = @response[:time_elapsed] if @response[:time_elapsed] < hash[:time_elapsed][:minimum]
41
+ hash[:time_elapsed][:average] = hash[:time_elapsed][:total] / hash[:num_requests]
42
+ end
43
+ end
@@ -0,0 +1,43 @@
1
+ module NiceHttpManageResponse
2
+ def wait_async_operation(response: @response, async_wait_seconds: @async_wait_seconds, async_header: @async_header, async_completed: @async_completed, async_resource: @async_resource, async_status: @async_status)
3
+ resp_orig = response.deep_copy
4
+ if async_wait_seconds.to_i > 0 and !async_header.empty? and !async_completed.empty?
5
+ if response.code == 202 and response.key?(async_header.to_sym)
6
+ begin
7
+ location = response[async_header.to_sym]
8
+ time_elapsed = 0
9
+ resp_async = {body: ''}
10
+ while time_elapsed <= async_wait_seconds
11
+ path, data, headers_t = manage_request({ path: location })
12
+ resp_async = @http.get path
13
+ completed = resp_async.body.json(async_completed.to_sym)
14
+ break if completed.to_i == 100 or time_elapsed >= async_wait_seconds
15
+ time_elapsed += 1
16
+ sleep 1
17
+ end
18
+ resp_orig.async = {}
19
+ resp_orig.async.seconds = time_elapsed
20
+ resp_orig.async.data = resp_async.body
21
+ if resp_async.body.json.key?(async_status.to_sym)
22
+ resp_orig.async.status = resp_async.body.json(async_status.to_sym)
23
+ else
24
+ resp_orig.async.status = ''
25
+ end
26
+ unless async_resource.empty?
27
+ location = resp_async.body.json(async_resource.to_sym)
28
+ if location.empty?
29
+ resp_orig.async.resource = {}
30
+ else
31
+ path, data, headers_t = manage_request({ path: location })
32
+ resp_async = @http.get path
33
+ resp_orig.async.resource = {data: resp_async.body}
34
+ end
35
+ end
36
+ rescue Exception => stack
37
+ @logger.warn stack
38
+ end
39
+ end
40
+ end
41
+ return resp_orig
42
+ end
43
+ end
@@ -0,0 +1,108 @@
1
+ module NiceHttpHttpMethods
2
+
3
+ ######################################################
4
+ # Delete an existing resource
5
+ # @param argument [Hash, String] hash containing at least key :path or a string with the path
6
+ #
7
+ # @return [Hash] response
8
+ # Including at least the symbol keys:
9
+ # :data = the response data body.
10
+ # :message = plain text response.
11
+ # :code = code response (200=ok,500=wrong...).
12
+ # All keys in response are lowercase.
13
+ # data, message and code can also be accessed as attributes like .message .code .data.
14
+ # In case of fatal error returns { fatal_error: "the error description", code: nil, message: nil, data: '' }
15
+ # @example
16
+ # resp = @http.delete(Requests::Customer.remove_session)
17
+ # assert resp.code == 204
18
+ ######################################################
19
+ def delete(argument)
20
+ begin
21
+ if argument.kind_of?(String)
22
+ argument = { :path => argument }
23
+ end
24
+ path, data, headers_t = manage_request(argument)
25
+ @start_time = Time.now if @start_time.nil?
26
+ if argument.kind_of?(Hash)
27
+ arg = argument
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
+ if data.to_s == ""
51
+ resp = @http.delete(path, headers_t)
52
+ if (resp.code == 401 or resp.code == 408) and @headers_orig.values.map(&:class).include?(Proc)
53
+ try = false
54
+ @headers_orig.each do |k, v|
55
+ if v.is_a?(Proc) and headers_t.key?(k)
56
+ try = true
57
+ headers_t[k] = v.call
58
+ end
59
+ end
60
+ if try
61
+ @logger.warn "Not authorized. Trying to generate a new token."
62
+ resp = @http.delete(path, headers_t)
63
+ end
64
+ end
65
+ else
66
+ request = Net::HTTP::Delete.new(path, headers_t)
67
+ request.body = data
68
+ resp = @http.request(request)
69
+ if (resp.code == 401 or resp.code == 408) and @headers_orig.values.map(&:class).include?(Proc)
70
+ try = false
71
+ @headers_orig.each do |k, v|
72
+ if v.is_a?(Proc) and headers_t.key?(k)
73
+ try = true
74
+ headers_t[k] = v.call
75
+ end
76
+ end
77
+ if try
78
+ @logger.warn "Not authorized. Trying to generate a new token."
79
+ request = Net::HTTP::Delete.new(path, headers_t)
80
+ request.body = data
81
+ resp = @http.request(request)
82
+ end
83
+ end
84
+ end
85
+ data = resp.body
86
+ rescue Exception => stack
87
+ @logger.warn stack
88
+ if !@timeout.nil? and (Time.now - @start_time_net) > @timeout
89
+ @logger.warn "The connection seems to be closed in the host machine. Timeout."
90
+ return { fatal_error: "Net::ReadTimeout", code: nil, message: nil, data: "" }
91
+ else
92
+ @logger.warn "The connection seems to be closed in the host machine. Trying to reconnect"
93
+ @http.finish()
94
+ @http.start()
95
+ @headers_orig.each { |k, v| headers_t[k] = v.call if v.is_a?(Proc) and headers_t.key?(k) }
96
+ @start_time_net = Time.now if @start_time_net.nil?
97
+ resp, data = @http.delete(path, headers_t)
98
+ end
99
+ end
100
+ manage_response(resp, data)
101
+
102
+ return @response
103
+ rescue Exception => stack
104
+ @logger.fatal stack
105
+ return { fatal_error: stack.to_s, code: nil, message: nil, data: "" }
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,159 @@
1
+ module NiceHttpHttpMethods
2
+
3
+ ######################################################
4
+ # Get data from path
5
+ #
6
+ # @param arg [Hash, String] hash containing at least key :path or a string with the path
7
+ # @param save_data [String] the path or path and file name where we want to save the response data
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
+ #
18
+ # @example
19
+ # resp = @http.get(Requests::Customer.get_profile)
20
+ # assert resp.code == 200
21
+ # @example
22
+ # resp = @http.get("/customers/1223")
23
+ # assert resp.message == "OK"
24
+ # @example
25
+ # resp = @http.get("/assets/images/logo.png", save_data: './tmp/')
26
+ # @example
27
+ # resp = @http.get("/assets/images/logo.png", save_data: './tmp/example.png')
28
+ ######################################################
29
+ def get(arg, save_data: "")
30
+ begin
31
+ path, data, headers_t = manage_request(arg)
32
+
33
+ @start_time = Time.now if @start_time.nil?
34
+ if @use_mocks and arg.kind_of?(Hash) and arg.keys.include?(:mock_response)
35
+ data = ""
36
+ if arg[:mock_response].keys.include?(:data)
37
+ data = arg[:mock_response][:data]
38
+ if data.kind_of?(Hash) #to json
39
+ begin
40
+ require "json"
41
+ data = data.to_json
42
+ rescue
43
+ @logger.fatal "There was a problem converting to json: #{data}"
44
+ end
45
+ end
46
+ end
47
+ @logger.warn "Pay attention!!! This is a mock response:"
48
+ @start_time_net = Time.now if @start_time_net.nil?
49
+ manage_response(arg[:mock_response], data.to_s)
50
+ return @response
51
+ end
52
+ begin
53
+ if path.start_with?("http:") or path.start_with?("https:") #server included on path problably because of a redirection to a different server
54
+ require "uri"
55
+ uri = URI.parse(path)
56
+ ssl = false
57
+ ssl = true if path.include?("https:")
58
+
59
+ server = "http://"
60
+ server = "https://" if path.start_with?("https:")
61
+ if uri.port != 443
62
+ server += "#{uri.host}:#{uri.port}"
63
+ else
64
+ server += "#{uri.host}"
65
+ end
66
+
67
+ http_redir = nil
68
+ self.class.connections.each { |conn|
69
+ if conn.host == uri.host and conn.port == uri.port
70
+ http_redir = conn
71
+ break
72
+ end
73
+ }
74
+
75
+ if !http_redir.nil?
76
+ path, data, headers_t = manage_request(arg)
77
+ http_redir.cookies.merge!(@cookies)
78
+ http_redir.headers.merge!(headers_t)
79
+ #todo: remove only the server at the begining in case in query is the server it will be replaced when it should not be
80
+ resp = http_redir.get(path.gsub(server, ""))
81
+ @response = http_redir.response
82
+ else
83
+ @logger.warn "It seems like the http connection cannot redirect to #{server} because there is no active connection for that server. You need to create previously one."
84
+ end
85
+ else
86
+ @start_time_net = Time.now if @start_time_net.nil?
87
+ resp = @http.get(path, headers_t)
88
+ if (resp.code == 401 or resp.code == 408) and @headers_orig.values.map(&:class).include?(Proc)
89
+ try = false
90
+ @headers_orig.each do |k, v|
91
+ if v.is_a?(Proc) and headers_t.key?(k)
92
+ try = true
93
+ headers_t[k] = v.call
94
+ end
95
+ end
96
+ if try
97
+ @logger.warn "Not authorized. Trying to generate a new token."
98
+ resp = @http.get(path, headers_t)
99
+ end
100
+ end
101
+ data = resp.body
102
+ manage_response(resp, data)
103
+ end
104
+ rescue Exception => stack
105
+ @logger.warn stack
106
+ if !@timeout.nil? and (Time.now - @start_time_net) > @timeout
107
+ @logger.warn "The connection seems to be closed in the host machine. Timeout."
108
+ return { fatal_error: "Net::ReadTimeout", code: nil, message: nil, data: "" }
109
+ else
110
+ @logger.warn "The connection seems to be closed in the host machine. Trying to reconnect"
111
+ @http.finish()
112
+ @http.start()
113
+ @start_time_net = Time.now if @start_time_net.nil?
114
+ @headers_orig.each { |k, v| headers_t[k] = v.call if v.is_a?(Proc) and headers_t.key?(k) }
115
+ resp = @http.get(path, headers_t)
116
+ data = resp.body
117
+ manage_response(resp, data)
118
+ end
119
+ end
120
+ if @auto_redirect and @response[:code].to_i >= 300 and @response[:code].to_i < 400 and @response.include?(:location)
121
+ if @num_redirects <= 30
122
+ @num_redirects += 1
123
+ current_server = "http"
124
+ current_server += "s" if @ssl == true
125
+ current_server += "://#{@host}"
126
+ location = @response[:location].gsub(current_server, "")
127
+ @logger.info "(#{@num_redirects}) Redirecting NiceHttp to #{location}"
128
+ get(location)
129
+ else
130
+ @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"
131
+ @num_redirects = 0
132
+ end
133
+ else
134
+ @num_redirects = 0
135
+ end
136
+ if save_data != ""
137
+ require "pathname"
138
+ pn_get = Pathname.new(path)
139
+
140
+ if Dir.exist?(save_data)
141
+ save = save_data + "/" + pn_get.basename.to_s
142
+ elsif save_data[-1] == "/"
143
+ save = save_data + pn_get.basename.to_s
144
+ else
145
+ save = save_data
146
+ end
147
+ if Dir.exist?(Pathname.new(save).dirname)
148
+ File.open(save, "wb") { |fp| fp.write(@response.data) }
149
+ else
150
+ @logger.fatal "The folder #{Pathname.new(save).dirname} doesn't exist"
151
+ end
152
+ end
153
+ return @response
154
+ rescue Exception => stack
155
+ @logger.fatal stack
156
+ return { fatal_error: stack.to_s, code: nil, message: nil, data: "" }
157
+ end
158
+ end
159
+ end
@@ -0,0 +1,72 @@
1
+ module NiceHttpHttpMethods
2
+
3
+ ######################################################
4
+ # Implementation of the http HEAD method.
5
+ # Asks for the response identical to the one that would correspond to a GET request, but without the response body.
6
+ # This is useful for retrieving meta-information written in response headers, without having to transport the entire content.
7
+ # @param argument [Hash, String] hash containing at least key :path or directly an string with the path
8
+ #
9
+ # @return [Hash] response
10
+ # Including at least the symbol keys:
11
+ # :message = plain text response.
12
+ # :code = code response (200=ok,500=wrong...).
13
+ # All keys in response are lowercase.
14
+ # message and code can also be accessed as attributes like .message .code.
15
+ # In case of fatal error returns { fatal_error: "the error description", code: nil, message: nil }
16
+ ######################################################
17
+ def head(argument)
18
+ begin
19
+ if argument.kind_of?(String)
20
+ argument = { :path => argument }
21
+ end
22
+ path, data, headers_t = manage_request(argument)
23
+ @start_time = Time.now if @start_time.nil?
24
+ if argument.kind_of?(Hash)
25
+ arg = argument
26
+ if @use_mocks and arg.kind_of?(Hash) and arg.keys.include?(:mock_response)
27
+ @logger.warn "Pay attention!!! This is a mock response:"
28
+ @start_time_net = Time.now if @start_time_net.nil?
29
+ manage_response(arg[:mock_response], "")
30
+ return @response
31
+ end
32
+ end
33
+
34
+ begin
35
+ @start_time_net = Time.now if @start_time_net.nil?
36
+ resp = @http.head(path, headers_t)
37
+ if (resp.code == 401 or resp.code == 408) and @headers_orig.values.map(&:class).include?(Proc)
38
+ try = false
39
+ @headers_orig.each do |k, v|
40
+ if v.is_a?(Proc) and headers_t.key?(k)
41
+ try = true
42
+ headers_t[k] = v.call
43
+ end
44
+ end
45
+ if try
46
+ @logger.warn "Not authorized. Trying to generate a new token."
47
+ resp = @http.head(path, headers_t)
48
+ end
49
+ end
50
+ data = resp.body
51
+ rescue Exception => stack
52
+ @logger.warn stack
53
+ if !@timeout.nil? and (Time.now - @start_time_net) > @timeout
54
+ @logger.warn "The connection seems to be closed in the host machine. Timeout."
55
+ return { fatal_error: "Net::ReadTimeout", code: nil, message: nil, data: "" }
56
+ else
57
+ @logger.warn "The connection seems to be closed in the host machine. Trying to reconnect"
58
+ @http.finish()
59
+ @http.start()
60
+ @headers_orig.each { |k, v| headers_t[k] = v.call if v.is_a?(Proc) and headers_t.key?(k) }
61
+ @start_time_net = Time.now if @start_time_net.nil?
62
+ resp, data = @http.head(path, headers_t)
63
+ end
64
+ end
65
+ manage_response(resp, data)
66
+ return @response
67
+ rescue Exception => stack
68
+ @logger.fatal stack
69
+ return { fatal_error: stack.to_s, code: nil, message: nil }
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,103 @@
1
+ module NiceHttpHttpMethods
2
+
3
+ ######################################################
4
+ # Patch data to path
5
+ #
6
+ # @param arguments [Hash] containing at least keys :data and :path.
7
+ # In case :data not supplied and :data_examples array supplied, it will be taken the first example as :data.
8
+ # @param arguments [Array<path, data, additional_headers>]
9
+ # path (string).
10
+ # data (json data for example).
11
+ # additional_headers (Hash key=>value).
12
+ # @return [Hash] response
13
+ # Including at least the symbol keys:
14
+ # :data = the response data body.
15
+ # :message = plain text response.
16
+ # :code = code response (200=ok,500=wrong...).
17
+ # All keys in response are lowercase.
18
+ # data, message and code can also be accessed as attributes like .message .code .data.
19
+ # In case of fatal error returns { fatal_error: "the error description", code: nil, message: nil, data: '' }
20
+ # @example
21
+ # resp = @http.patch(Requests::Customer.unrelease_account)
22
+ ######################################################
23
+ def patch(*arguments)
24
+ begin
25
+ path, data, headers_t = manage_request(*arguments)
26
+ @start_time = Time.now if @start_time.nil?
27
+ if arguments.size > 0 and arguments[0].kind_of?(Hash)
28
+ arg = arguments[0]
29
+ if @use_mocks and arg.kind_of?(Hash) and arg.keys.include?(:mock_response)
30
+ data = ""
31
+ if arg[:mock_response].keys.include?(:data)
32
+ data = arg[:mock_response][:data]
33
+ if data.kind_of?(Hash) #to json
34
+ begin
35
+ require "json"
36
+ data = data.to_json
37
+ rescue
38
+ @logger.fatal "There was a problem converting to json: #{data}"
39
+ end
40
+ end
41
+ end
42
+ @logger.warn "Pay attention!!! This is a mock response:"
43
+ @start_time_net = Time.now if @start_time_net.nil?
44
+ manage_response(arg[:mock_response], data.to_s)
45
+ return @response
46
+ end
47
+ end
48
+
49
+ begin
50
+ @start_time_net = Time.now if @start_time_net.nil?
51
+ resp = @http.patch(path, data, headers_t)
52
+ if (resp.code == 401 or resp.code == 408) and @headers_orig.values.map(&:class).include?(Proc)
53
+ try = false
54
+ @headers_orig.each do |k, v|
55
+ if v.is_a?(Proc) and headers_t.key?(k)
56
+ try = true
57
+ headers_t[k] = v.call
58
+ end
59
+ end
60
+ if try
61
+ @logger.warn "Not authorized. Trying to generate a new token."
62
+ resp = @http.patch(path, data, headers_t)
63
+ end
64
+ end
65
+ data = resp.body
66
+ rescue Exception => stack
67
+ @logger.warn stack
68
+ if !@timeout.nil? and (Time.now - @start_time_net) > @timeout
69
+ @logger.warn "The connection seems to be closed in the host machine. Timeout."
70
+ return { fatal_error: "Net::ReadTimeout", code: nil, message: nil, data: "" }
71
+ else
72
+ @logger.warn "The connection seems to be closed in the host machine. Trying to reconnect"
73
+ @http.finish()
74
+ @http.start()
75
+ @headers_orig.each { |k, v| headers_t[k] = v.call if v.is_a?(Proc) and headers_t.key?(k) }
76
+ @start_time_net = Time.now if @start_time_net.nil?
77
+ resp, data = @http.patch(path, data, headers_t)
78
+ end
79
+ end
80
+ manage_response(resp, data)
81
+ if @auto_redirect and @response[:code].to_i >= 300 and @response[:code].to_i < 400 and @response.include?(:location)
82
+ if @num_redirects <= 30
83
+ @num_redirects += 1
84
+ current_server = "http"
85
+ current_server += "s" if @ssl == true
86
+ current_server += "://#{@host}"
87
+ location = @response[:location].gsub(current_server, "")
88
+ @logger.info "(#{@num_redirects}) Redirecting NiceHttp to #{location}"
89
+ get(location)
90
+ else
91
+ @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"
92
+ @num_redirects = 0
93
+ end
94
+ else
95
+ @num_redirects = 0
96
+ end
97
+ return @response
98
+ rescue Exception => stack
99
+ @logger.fatal stack
100
+ return { fatal_error: stack.to_s, code: nil, message: nil, data: "" }
101
+ end
102
+ end
103
+ end