nice_http 1.8.10 → 1.9.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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