nice_http 1.5.0 → 1.5.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 14ef0915599e45b4cf51c12cd11057661ee6a95167834b832f64364fe84db1d8
4
- data.tar.gz: a57efa9684af2c57a0156c44f224d9f0d4bbb9a0fcbc35fb38edc41fa0926358
3
+ metadata.gz: 7a643789ecef4023afa1da9c2a6a91a08fa372cce870a334d95bee2a5b11cf25
4
+ data.tar.gz: e6a28d99ac2bd2507e17b8c47dc9e7d7d24aadb86670be92bd99207f2e97e737
5
5
  SHA512:
6
- metadata.gz: 30d1143cd4710c837e37481c8fbbbf385f1e56bfd4804a20bf9665b0349cabe2c4dcdb25e355b107770ad3f95715c56da4c5836c4b1c88b55837fae26bb6a07f
7
- data.tar.gz: b913a8f5aca115b6370640b27ece8c95099289876490a3d417a656b71b5d16788a9964220efcfb47f7e056ecc3beab0a3a85a2206927bffeae0d705282182d13
6
+ metadata.gz: 396beef6b7324c13f32a414d27a45ea1416f1261c63f27f34b54ee6639ad1c6162cada27ebb23118b12418d775e75e13819bf408c6c62ad5f55e3c226f9ead54
7
+ data.tar.gz: f45980ce17a4bb5b4549096025c2f8a2f05bb0a65692008f11ceb1e07e5d3435afd52e4746b7d8b78a5c5ebed2653894051bef83c645e8bf179b773c4e615c65
@@ -0,0 +1,529 @@
1
+ module NiceHttpHttpMethods
2
+
3
+ ######################################################
4
+ # Get data from path
5
+ #
6
+ # @param arg [Hash] containing at least key :path
7
+ # @param arg [String] the path
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
+ ######################################################
25
+ def get(arg)
26
+ begin
27
+ path, data, headers_t = manage_request(arg)
28
+
29
+ @start_time = Time.now if @start_time.nil?
30
+ if @use_mocks and arg.kind_of?(Hash) and arg.keys.include?(:mock_response)
31
+ data = ""
32
+ if arg[:mock_response].keys.include?(:data)
33
+ data = arg[:mock_response][:data]
34
+ if data.kind_of?(Hash) #to json
35
+ begin
36
+ require "json"
37
+ data = data.to_json
38
+ rescue
39
+ @logger.fatal "There was a problem converting to json: #{data}"
40
+ end
41
+ end
42
+ end
43
+ @logger.warn "Pay attention!!! This is a mock response:"
44
+ @start_time_net = Time.now if @start_time_net.nil?
45
+ manage_response(arg[:mock_response], data.to_s)
46
+ return @response
47
+ end
48
+ begin
49
+ if path.start_with?("http:") or path.start_with?("https:") #server included on path problably because of a redirection to a different server
50
+ require "uri"
51
+ uri = URI.parse(path)
52
+ ssl = false
53
+ ssl = true if path.include?("https:")
54
+
55
+ server = "http://"
56
+ server = "https://" if path.start_with?("https:")
57
+ if uri.port != 443
58
+ server += "#{uri.host}:#{uri.port}"
59
+ else
60
+ server += "#{uri.host}"
61
+ end
62
+
63
+ http_redir = nil
64
+ self.class.connections.each { |conn|
65
+ if conn.host == uri.host and conn.port == uri.port
66
+ http_redir = conn
67
+ break
68
+ end
69
+ }
70
+
71
+ if !http_redir.nil?
72
+ path, data, headers_t = manage_request(arg)
73
+ http_redir.cookies.merge!(@cookies)
74
+ http_redir.headers.merge!(headers_t)
75
+ #todo: remove only the server at the begining in case in query is the server it will be replaced when it should not be
76
+ resp = http_redir.get(path.gsub(server, ""))
77
+ @response = http_redir.response
78
+ else
79
+ @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."
80
+ end
81
+ else
82
+ @start_time_net = Time.now if @start_time_net.nil?
83
+ resp = @http.get(path, headers_t)
84
+ data = resp.body
85
+ manage_response(resp, data)
86
+ end
87
+ rescue Exception => stack
88
+ @logger.warn stack
89
+ @logger.warn "The connection seems to be closed in the host machine. Trying to reconnect"
90
+ @http.finish()
91
+ @http.start()
92
+ @start_time_net = Time.now if @start_time_net.nil?
93
+ resp = @http.get(path)
94
+ data = resp.body
95
+ manage_response(resp, data)
96
+ end
97
+ if @auto_redirect and @response[:code].to_i >= 300 and @response[:code].to_i < 400 and @response.include?(:location)
98
+ if @num_redirects <= 30
99
+ @num_redirects += 1
100
+ current_server = "http"
101
+ current_server += "s" if @ssl == true
102
+ current_server += "://#{@host}"
103
+ location = @response[:location].gsub(current_server, "")
104
+ @logger.info "(#{@num_redirects}) Redirecting NiceHttp to #{location}"
105
+ get(location)
106
+ else
107
+ @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"
108
+ @num_redirects = 0
109
+ end
110
+ else
111
+ @num_redirects = 0
112
+ end
113
+ return @response
114
+ rescue Exception => stack
115
+ @logger.fatal stack
116
+ return {fatal_error: stack.to_s, code: nil, message: nil, data: ""}
117
+ end
118
+ end
119
+
120
+ ######################################################
121
+ # Post data to path
122
+ # @param arguments [Hash] containing at least keys :data and :path.
123
+ # In case :data not supplied and :data_examples array supplied, it will be taken the first example as :data.
124
+ # @param arguments [Array<path, data, additional_headers>]
125
+ # path (string).
126
+ # data (json data for example).
127
+ # additional_headers (Hash key=>value).
128
+ # @return [Hash] response
129
+ # Including at least the symbol keys:
130
+ # :data = the response data body.
131
+ # :message = plain text response.
132
+ # :code = code response (200=ok,500=wrong...).
133
+ # All keys in response are lowercase.
134
+ # data, message and code can also be accessed as attributes like .message .code .data.
135
+ # In case of fatal error returns { fatal_error: "the error description", code: nil, message: nil, data: '' }
136
+ # @example
137
+ # resp = @http.post(Requests::Customer.update_customer)
138
+ # assert resp.code == 201
139
+ # @example
140
+ # resp = http.post( {
141
+ # path: "/api/users",
142
+ # data: {name: "morpheus", job: "leader"}
143
+ # } )
144
+ # pp resp.data.json
145
+ ######################################################
146
+ def post(*arguments)
147
+ begin
148
+ path, data, headers_t = manage_request(*arguments)
149
+ @start_time = Time.now if @start_time.nil?
150
+ if arguments.size > 0 and arguments[0].kind_of?(Hash)
151
+ arg = arguments[0]
152
+ if @use_mocks and arg.kind_of?(Hash) and arg.keys.include?(:mock_response)
153
+ data = ""
154
+ if arg[:mock_response].keys.include?(:data)
155
+ data = arg[:mock_response][:data]
156
+ if data.kind_of?(Hash) #to json
157
+ begin
158
+ require "json"
159
+ data = data.to_json
160
+ rescue
161
+ @logger.fatal "There was a problem converting to json: #{data}"
162
+ end
163
+ end
164
+ end
165
+ @logger.warn "Pay attention!!! This is a mock response:"
166
+ @start_time_net = Time.now if @start_time_net.nil?
167
+ manage_response(arg[:mock_response], data.to_s)
168
+ return @response
169
+ end
170
+ end
171
+
172
+ begin
173
+ @start_time_net = Time.now if @start_time_net.nil?
174
+ if headers_t["Content-Type"] == "multipart/form-data"
175
+ require "net/http/post/multipart"
176
+ headers_t.each { |key, value|
177
+ arguments[0][:data].add_field(key, value) #add to Headers
178
+ }
179
+ resp = @http.request(arguments[0][:data])
180
+ else
181
+ resp = @http.post(path, data, headers_t)
182
+ data = resp.body
183
+ end
184
+ rescue Exception => stack
185
+ @logger.warn stack
186
+ @logger.warn "The connection seems to be closed in the host machine. Trying to reconnect"
187
+ @http.finish()
188
+ @http.start()
189
+ @start_time_net = Time.now if @start_time_net.nil?
190
+ resp, data = @http.post(path, data, headers_t)
191
+ end
192
+ manage_response(resp, data)
193
+ if @auto_redirect and @response[:code].to_i >= 300 and @response[:code].to_i < 400 and @response.include?(:location)
194
+ if @num_redirects <= 30
195
+ @num_redirects += 1
196
+ current_server = "http"
197
+ current_server += "s" if @ssl == true
198
+ current_server += "://#{@host}"
199
+ location = @response[:location].gsub(current_server, "")
200
+ @logger.info "(#{@num_redirects}) Redirecting NiceHttp to #{location}"
201
+ get(location)
202
+ else
203
+ @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"
204
+ @num_redirects = 0
205
+ end
206
+ else
207
+ @num_redirects = 0
208
+ end
209
+ return @response
210
+ rescue Exception => stack
211
+ @logger.fatal stack
212
+ return {fatal_error: stack.to_s, code: nil, message: nil, data: ""}
213
+ end
214
+ end
215
+
216
+ ######################################################
217
+ # Put data to path
218
+ # @param arguments [Hash] containing at least keys :data and :path.
219
+ # In case :data not supplied and :data_examples array supplied, it will be taken the first example as :data.
220
+ # @param arguments [Array<path, data, additional_headers>]
221
+ # path (string).
222
+ # data (json data for example).
223
+ # additional_headers (Hash key=>value).
224
+ # @return [Hash] response
225
+ # Including at least the symbol keys:
226
+ # :data = the response data body.
227
+ # :message = plain text response.
228
+ # :code = code response (200=ok,500=wrong...).
229
+ # All keys in response are lowercase.
230
+ # data, message and code can also be accessed as attributes like .message .code .data.
231
+ # In case of fatal error returns { fatal_error: "the error description", code: nil, message: nil, data: '' }
232
+ # @example
233
+ # resp = @http.put(Requests::Customer.remove_phone)
234
+ ######################################################
235
+ def put(*arguments)
236
+ begin
237
+ path, data, headers_t = manage_request(*arguments)
238
+ @start_time = Time.now if @start_time.nil?
239
+ if arguments.size > 0 and arguments[0].kind_of?(Hash)
240
+ arg = arguments[0]
241
+ if @use_mocks and arg.kind_of?(Hash) and arg.keys.include?(:mock_response)
242
+ data = ""
243
+ if arg[:mock_response].keys.include?(:data)
244
+ data = arg[:mock_response][:data]
245
+ if data.kind_of?(Hash) #to json
246
+ begin
247
+ require "json"
248
+ data = data.to_json
249
+ rescue
250
+ @logger.fatal "There was a problem converting to json: #{data}"
251
+ end
252
+ end
253
+ end
254
+ @logger.warn "Pay attention!!! This is a mock response:"
255
+ @start_time_net = Time.now if @start_time_net.nil?
256
+ manage_response(arg[:mock_response], data.to_s)
257
+ return @response
258
+ end
259
+ end
260
+
261
+ begin
262
+ @start_time_net = Time.now if @start_time_net.nil?
263
+ resp = @http.send_request("PUT", path, data, headers_t)
264
+ data = resp.body
265
+ rescue Exception => stack
266
+ @logger.warn stack
267
+ @logger.warn "The connection seems to be closed in the host machine. Trying to reconnect"
268
+ @http.finish()
269
+ @http.start()
270
+ @start_time_net = Time.now if @start_time_net.nil?
271
+ resp, data = @http.send_request("PUT", path, data, headers_t)
272
+ end
273
+ manage_response(resp, data)
274
+
275
+ return @response
276
+ rescue Exception => stack
277
+ @logger.fatal stack
278
+ return {fatal_error: stack.to_s, code: nil, message: nil, data: ""}
279
+ end
280
+ end
281
+
282
+ ######################################################
283
+ # Patch data to path
284
+ # @param arguments [Hash] containing at least keys :data and :path.
285
+ # In case :data not supplied and :data_examples array supplied, it will be taken the first example as :data.
286
+ # @param arguments [Array<path, data, additional_headers>]
287
+ # path (string).
288
+ # data (json data for example).
289
+ # additional_headers (Hash key=>value).
290
+ # @return [Hash] response
291
+ # Including at least the symbol keys:
292
+ # :data = the response data body.
293
+ # :message = plain text response.
294
+ # :code = code response (200=ok,500=wrong...).
295
+ # All keys in response are lowercase.
296
+ # data, message and code can also be accessed as attributes like .message .code .data.
297
+ # In case of fatal error returns { fatal_error: "the error description", code: nil, message: nil, data: '' }
298
+ # @example
299
+ # resp = @http.patch(Requests::Customer.unrelease_account)
300
+ ######################################################
301
+ def patch(*arguments)
302
+ begin
303
+ path, data, headers_t = manage_request(*arguments)
304
+ @start_time = Time.now if @start_time.nil?
305
+ if arguments.size > 0 and arguments[0].kind_of?(Hash)
306
+ arg = arguments[0]
307
+ if @use_mocks and arg.kind_of?(Hash) and arg.keys.include?(:mock_response)
308
+ data = ""
309
+ if arg[:mock_response].keys.include?(:data)
310
+ data = arg[:mock_response][:data]
311
+ if data.kind_of?(Hash) #to json
312
+ begin
313
+ require "json"
314
+ data = data.to_json
315
+ rescue
316
+ @logger.fatal "There was a problem converting to json: #{data}"
317
+ end
318
+ end
319
+ end
320
+ @logger.warn "Pay attention!!! This is a mock response:"
321
+ @start_time_net = Time.now if @start_time_net.nil?
322
+ manage_response(arg[:mock_response], data.to_s)
323
+ return @response
324
+ end
325
+ end
326
+
327
+ begin
328
+ @start_time_net = Time.now if @start_time_net.nil?
329
+ resp = @http.patch(path, data, headers_t)
330
+ data = resp.body
331
+ rescue Exception => stack
332
+ @logger.warn stack
333
+ @logger.warn "The connection seems to be closed in the host machine. Trying to reconnect"
334
+ @http.finish()
335
+ @http.start()
336
+ @start_time_net = Time.now if @start_time_net.nil?
337
+ resp, data = @http.patch(path, data, headers_t)
338
+ end
339
+ manage_response(resp, data)
340
+ if @auto_redirect and @response[:code].to_i >= 300 and @response[:code].to_i < 400 and @response.include?(:location)
341
+ if @num_redirects <= 30
342
+ @num_redirects += 1
343
+ current_server = "http"
344
+ current_server += "s" if @ssl == true
345
+ current_server += "://#{@host}"
346
+ location = @response[:location].gsub(current_server, "")
347
+ @logger.info "(#{@num_redirects}) Redirecting NiceHttp to #{location}"
348
+ get(location)
349
+ else
350
+ @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"
351
+ @num_redirects = 0
352
+ end
353
+ else
354
+ @num_redirects = 0
355
+ end
356
+ return @response
357
+ rescue Exception => stack
358
+ @logger.fatal stack
359
+ return {fatal_error: stack.to_s, code: nil, message: nil, data: ""}
360
+ end
361
+ end
362
+
363
+ ######################################################
364
+ # Delete an existing resource
365
+ # @param arg [Hash] containing at least key :path
366
+ # @param arg [String] the path
367
+ #
368
+ # @return [Hash] response
369
+ # Including at least the symbol keys:
370
+ # :data = the response data body.
371
+ # :message = plain text response.
372
+ # :code = code response (200=ok,500=wrong...).
373
+ # All keys in response are lowercase.
374
+ # data, message and code can also be accessed as attributes like .message .code .data.
375
+ # In case of fatal error returns { fatal_error: "the error description", code: nil, message: nil, data: '' }
376
+ # @example
377
+ # resp = @http.delete(Requests::Customer.remove_session)
378
+ # assert resp.code == 204
379
+ ######################################################
380
+ def delete(argument)
381
+ begin
382
+ if argument.kind_of?(String)
383
+ argument = {:path => argument}
384
+ end
385
+ path, data, headers_t = manage_request(argument)
386
+ @start_time = Time.now if @start_time.nil?
387
+ if argument.kind_of?(Hash)
388
+ arg = argument
389
+ if @use_mocks and arg.kind_of?(Hash) and arg.keys.include?(:mock_response)
390
+ data = ""
391
+ if arg[:mock_response].keys.include?(:data)
392
+ data = arg[:mock_response][:data]
393
+ if data.kind_of?(Hash) #to json
394
+ begin
395
+ require "json"
396
+ data = data.to_json
397
+ rescue
398
+ @logger.fatal "There was a problem converting to json: #{data}"
399
+ end
400
+ end
401
+ end
402
+ @logger.warn "Pay attention!!! This is a mock response:"
403
+ @start_time_net = Time.now if @start_time_net.nil?
404
+ manage_response(arg[:mock_response], data.to_s)
405
+ return @response
406
+ end
407
+ end
408
+
409
+ begin
410
+ @start_time_net = Time.now if @start_time_net.nil?
411
+ resp = @http.delete(path, headers_t)
412
+ data = resp.body
413
+ rescue Exception => stack
414
+ @logger.warn stack
415
+ @logger.warn "The connection seems to be closed in the host machine. Trying to reconnect"
416
+ @http.finish()
417
+ @http.start()
418
+ @start_time_net = Time.now if @start_time_net.nil?
419
+ resp, data = @http.delete(path)
420
+ end
421
+ manage_response(resp, data)
422
+
423
+ return @response
424
+ rescue Exception => stack
425
+ @logger.fatal stack
426
+ return {fatal_error: stack.to_s, code: nil, message: nil, data: ""}
427
+ end
428
+ end
429
+
430
+ ######################################################
431
+ # Implementation of the http HEAD method.
432
+ # Asks for the response identical to the one that would correspond to a GET request, but without the response body.
433
+ # This is useful for retrieving meta-information written in response headers, without having to transport the entire content.
434
+ # @param arg [Hash] containing at least key :path
435
+ # @param arg [String] the path
436
+ #
437
+ # @return [Hash] response
438
+ # Including at least the symbol keys:
439
+ # :message = plain text response.
440
+ # :code = code response (200=ok,500=wrong...).
441
+ # All keys in response are lowercase.
442
+ # message and code can also be accessed as attributes like .message .code.
443
+ # In case of fatal error returns { fatal_error: "the error description", code: nil, message: nil }
444
+ ######################################################
445
+ def head(argument)
446
+ begin
447
+ if argument.kind_of?(String)
448
+ argument = {:path => argument}
449
+ end
450
+ path, data, headers_t = manage_request(argument)
451
+ @start_time = Time.now if @start_time.nil?
452
+ if argument.kind_of?(Hash)
453
+ arg = argument
454
+ if @use_mocks and arg.kind_of?(Hash) and arg.keys.include?(:mock_response)
455
+ @logger.warn "Pay attention!!! This is a mock response:"
456
+ @start_time_net = Time.now if @start_time_net.nil?
457
+ manage_response(arg[:mock_response], "")
458
+ return @response
459
+ end
460
+ end
461
+
462
+ begin
463
+ @start_time_net = Time.now if @start_time_net.nil?
464
+ resp = @http.head(path, headers_t)
465
+ data = resp.body
466
+ rescue Exception => stack
467
+ @logger.warn stack
468
+ @logger.warn "The connection seems to be closed in the host machine. Trying to reconnect"
469
+ @http.finish()
470
+ @http.start()
471
+ @start_time_net = Time.now if @start_time_net.nil?
472
+ resp, data = @http.head(path)
473
+ end
474
+ manage_response(resp, data)
475
+ return @response
476
+ rescue Exception => stack
477
+ @logger.fatal stack
478
+ return {fatal_error: stack.to_s, code: nil, message: nil}
479
+ end
480
+ end
481
+
482
+ ######################################################
483
+ # It will send the request depending on the :method declared on the request hash
484
+ # Take a look at https://github.com/MarioRuiz/Request-Hash
485
+ #
486
+ # @param request_hash [Hash] containing at least key :path and :method. The methods that are accepted are: :get, :head, :post, :put, :delete, :patch
487
+ #
488
+ # @return [Hash] response
489
+ # Including at least the symbol keys:
490
+ # :data = the response data body.
491
+ # :message = plain text response.
492
+ # :code = code response (200=ok,500=wrong...).
493
+ # All keys in response are lowercase.
494
+ # data, message and code can also be accessed as attributes like .message .code .data.
495
+ # In case of fatal error returns { fatal_error: "the error description", code: nil, message: nil, data: '' }
496
+ # @example
497
+ # resp = @http.send_request Requests::Customer.remove_session
498
+ # assert resp.code == 204
499
+ ######################################################
500
+ def send_request(request_hash)
501
+ unless request_hash.is_a?(Hash) and request_hash.key?(:method) and request_hash.key?(:path) and
502
+ request_hash[:method].is_a?(Symbol) and
503
+ [:get, :head, :post, :put, :delete, :patch].include?(request_hash[:method])
504
+
505
+ message = "send_request: it needs to be supplied a Request Hash that includes a :method and :path. "
506
+ message += "Supported methods: :get, :head, :post, :put, :delete, :patch"
507
+ @logger.fatal message
508
+ return {fatal_error: message, code: nil, message: nil}
509
+ else
510
+ case request_hash[:method]
511
+ when :get
512
+ resp = get request_hash
513
+ when :post
514
+ resp = post request_hash
515
+ when :head
516
+ resp = head request_hash
517
+ when :put
518
+ resp = put request_hash
519
+ when :delete
520
+ resp = delete request_hash
521
+ when :patch
522
+ resp = patch request_hash
523
+ end
524
+ return resp
525
+ end
526
+
527
+ end
528
+
529
+ end
@@ -0,0 +1,233 @@
1
+ module NiceHttpManageRequest
2
+
3
+ ######################################################
4
+ # private method to manage Request
5
+ # input:
6
+ # 3 args: path, data, headers
7
+ # 1 arg: Hash containg at least keys :path and :data
8
+ # In case :data not supplied and :data_examples array supplied, it will be taken the first example as :data.
9
+ # output:
10
+ # path, data, headers
11
+ ######################################################
12
+ def manage_request(*arguments)
13
+ require "json"
14
+ begin
15
+ content_type_included = false
16
+ path = ""
17
+ data = ""
18
+
19
+ @response = Hash.new()
20
+ headers_t = @headers.dup()
21
+ cookies_to_set_str = ""
22
+ if arguments.size == 3
23
+ path = arguments[0]
24
+ elsif arguments.size == 1 and arguments[0].kind_of?(Hash)
25
+ path = arguments[0][:path]
26
+ elsif arguments.size == 1 and arguments[0].kind_of?(String)
27
+ path = arguments[0].to_s()
28
+ end
29
+ path = (@prepath + path).gsub('//','/') unless path.nil? or path.start_with?('http:') or path.start_with?('https:')
30
+ @cookies.each { |cookie_path, cookies_hash|
31
+ cookie_path = "" if cookie_path == "/"
32
+ path_to_check = path
33
+ if path == "/" or path[-1] != "/"
34
+ path_to_check += "/"
35
+ end
36
+ if path_to_check.scan(/^#{cookie_path}\//).size > 0
37
+ cookies_hash.each { |key, value|
38
+ cookies_to_set_str += "#{key}=#{value}; "
39
+ }
40
+ end
41
+ }
42
+ headers_t["Cookie"] = cookies_to_set_str
43
+
44
+ method_s = caller[0].to_s().scan(/:in `(.*)'/).join
45
+
46
+ if arguments.size == 3
47
+ data = arguments[1]
48
+ if arguments[2].kind_of?(Hash)
49
+ headers_t.merge!(arguments[2])
50
+ end
51
+ elsif arguments.size == 1 and arguments[0].kind_of?(Hash)
52
+ if arguments[0][:data].nil?
53
+ if arguments[0].keys.include?(:data)
54
+ data = ""
55
+ elsif arguments[0].keys.include?(:data_examples) and
56
+ arguments[0][:data_examples].kind_of?(Array)
57
+ data = arguments[0][:data_examples][0] #the first example by default
58
+ else
59
+ data = ""
60
+ end
61
+ else
62
+ data = arguments[0][:data]
63
+ end
64
+ if arguments[0].include?(:headers)
65
+ headers_t.merge!(arguments[0][:headers])
66
+ end
67
+
68
+ if headers_t["Content-Type"].to_s() == "" and headers_t["content-type"].to_s() == "" and
69
+ headers_t[:"content-type"].to_s() == "" and headers_t[:"Content-Type"].to_s() == ""
70
+ content_type_included = false
71
+ elsif headers_t["content-type"].to_s() != ""
72
+ content_type_included = true
73
+ headers_t["Content-Type"] = headers_t["content-type"]
74
+ elsif headers_t[:"content-type"].to_s() != ""
75
+ content_type_included = true
76
+ headers_t["Content-Type"] = headers_t[:"content-type"]
77
+ headers_t.delete(:"content-type")
78
+ elsif headers_t[:"Content-Type"].to_s() != ""
79
+ content_type_included = true
80
+ headers_t["Content-Type"] = headers_t[:"Content-Type"]
81
+ headers_t.delete(:"Content-Type")
82
+ elsif headers_t["Content-Type"].to_s() != ""
83
+ content_type_included = true
84
+ end
85
+ if !content_type_included and data.kind_of?(Hash)
86
+ headers_t["Content-Type"] = "application/json"
87
+ content_type_included = true
88
+ end
89
+ # to be backwards compatible since before was :values
90
+ if arguments[0].include?(:values) and !arguments[0].include?(:values_for)
91
+ arguments[0][:values_for] = arguments[0][:values]
92
+ end
93
+ if content_type_included and (!headers_t["Content-Type"][/text\/xml/].nil? or
94
+ !headers_t["Content-Type"]["application/soap+xml"].nil? or
95
+ !headers_t["Content-Type"][/application\/jxml/].nil?)
96
+ if arguments[0].include?(:values_for)
97
+ arguments[0][:values_for].each { |key, value|
98
+ data = NiceHttpUtils.set_value_xml_tag(key.to_s(), data, value.to_s(), true)
99
+ }
100
+ end
101
+ elsif content_type_included and !headers_t["Content-Type"][/application\/json/].nil? and data.to_s() != ""
102
+ require "json"
103
+ if data.kind_of?(String)
104
+ if arguments[0].include?(:values_for)
105
+ arguments[0][:values_for].each { |key, value|
106
+ data.gsub!(/(( *|^)"?#{key.to_s()}"? *: *")(.*)(" *, *$)/, '\1' + value + '\4') # "key":"value", or key:"value",
107
+ data.gsub!(/(( *|^)"?#{key.to_s()}"? *: *")(.*)(" *$)/, '\1' + value + '\4') # "key":"value" or key:"value"
108
+ data.gsub!(/(( *|^)"?#{key.to_s()}"? *: *[^"])([^"].*)([^"] *, *$)/, '\1' + value + '\4') # "key":456, or key:456,
109
+ data.gsub!(/(( *|^)"?#{key.to_s()}"? *: *[^"])([^"].*)([^"] * *$)/, '\1' + value + '\4') # "key":456 or key:456
110
+ }
111
+ end
112
+ elsif data.kind_of?(Hash)
113
+ data_n = Hash.new()
114
+ data.each { |key, value|
115
+ data_n[key.to_s()] = value
116
+ }
117
+ if arguments[0].include?(:values_for)
118
+ #req[:values_for][:loginName] or req[:values_for]["loginName"]
119
+ new_values_hash = Hash.new()
120
+ arguments[0][:values_for].each { |kv, vv|
121
+ if data_n.keys.include?(kv.to_s())
122
+ new_values_hash[kv.to_s()] = vv
123
+ end
124
+ }
125
+ data_n.merge!(new_values_hash)
126
+ end
127
+ data = data_n.to_json()
128
+ elsif data.kind_of?(Array)
129
+ data_arr = Array.new()
130
+ data.each_with_index { |row, indx|
131
+ unless row.kind_of?(Hash)
132
+ @logger.fatal("Wrong format on request application/json, be sure is a Hash, Array of Hashes or JSON string")
133
+ return :error, :error, :error
134
+ end
135
+ data_n = Hash.new()
136
+ row.each { |key, value|
137
+ data_n[key.to_s()] = value
138
+ }
139
+ if arguments[0].include?(:values_for)
140
+ #req[:values_for][:loginName] or req[:values_for]["loginName"]
141
+ new_values_hash = Hash.new()
142
+ if arguments[0][:values_for].kind_of?(Hash) #values[:mykey][3]
143
+ arguments[0][:values_for].each { |kv, vv|
144
+ if data_n.keys.include?(kv.to_s()) and !vv[indx].nil?
145
+ new_values_hash[kv.to_s()] = vv[indx]
146
+ end
147
+ }
148
+ elsif arguments[0][:values_for].kind_of?(Array) #values[5][:mykey]
149
+ if !arguments[0][:values_for][indx].nil?
150
+ arguments[0][:values_for][indx].each { |kv, vv|
151
+ if data_n.keys.include?(kv.to_s())
152
+ new_values_hash[kv.to_s()] = vv
153
+ end
154
+ }
155
+ end
156
+ else
157
+ @logger.fatal("Wrong format on request application/json when supplying values, the data is an array of Hashes but the values supplied are not")
158
+ return :error, :error, :error
159
+ end
160
+ data_n.merge!(new_values_hash)
161
+ end
162
+ data_arr.push(data_n)
163
+ }
164
+ data = data_arr.to_json()
165
+ else
166
+ @logger.fatal("Wrong format on request application/json, be sure is a Hash, Array of Hashes or JSON string")
167
+ return :error, :error, :error
168
+ end
169
+ elsif content_type_included and arguments[0].include?(:values_for)
170
+ if arguments[0][:values_for].kind_of?(Hash) and arguments[0][:values_for].keys.size > 0
171
+ if !headers_t.nil? and headers_t.kind_of?(Hash) and headers_t["Content-Type"] != "application/x-www-form-urlencoded" and headers_t["content-type"] != "application/x-www-form-urlencoded"
172
+ @logger.warn(":values_for key given without a valid content-type or data for request. No values modified on the request")
173
+ end
174
+ end
175
+ end
176
+ elsif arguments.size == 1 and arguments[0].kind_of?(String)
177
+ #path=arguments[0].to_s()
178
+ data = ""
179
+ else
180
+ @logger.fatal("Invalid number of arguments or wrong arguments in #{method_s}")
181
+ return :error, :error, :error
182
+ end
183
+ if headers_t.keys.include?("Content-Type") and !headers_t["Content-Type"]["multipart/form-data"].nil? and headers_t["Content-Type"] != ["multipart/form-data"] #only for the case raw multipart request
184
+ encoding = "UTF-8"
185
+ data_s = ""
186
+ else
187
+ encoding = data.to_s().scan(/encoding='(.*)'/i).join
188
+ if encoding.to_s() == ""
189
+ encoding = data.to_s().scan(/charset='(.*)'/i).join
190
+ end
191
+ if encoding.to_s() == "" and headers_t.include?("Content-Type")
192
+ encoding = headers_t["Content-Type"].scan(/charset='?(.*)'?/i).join
193
+ if encoding.to_s() == ""
194
+ encoding = headers_t["Content-Type"].scan(/encoding='?(.*)'?/i).join
195
+ end
196
+ end
197
+
198
+ begin
199
+ data_s = JSON.pretty_generate(JSON.parse(data))
200
+ rescue
201
+ data_s = data
202
+ end
203
+ data_s = data_s.to_s().gsub("<", "&lt;")
204
+ end
205
+ if headers_t.keys.include?("Accept-Encoding")
206
+ headers_t["Accept-Encoding"].gsub!("gzip", "") #removed so the response is in plain text
207
+ end
208
+
209
+ headers_ts = ""
210
+ headers_t.each { |key, val| headers_ts += key.to_s + ":" + val.to_s() + ", " }
211
+ message = "#{method_s} REQUEST: \npath= " + path.to_s() + "\n"
212
+ message += "headers= " + headers_ts.to_s() + "\n"
213
+ message += "data= " + data_s.to_s() + "\n"
214
+ message = @message_server + "\n" + message
215
+ if path.to_s().scan(/^https?:\/\//).size > 0 and path.to_s().scan(/^https?:\/\/#{@host}/).size == 0
216
+ # the path is for another server than the current
217
+ else
218
+ self.class.last_request = message
219
+ @logger.info(message)
220
+ end
221
+
222
+ if data.to_s() != "" and encoding.to_s().upcase != "UTF-8" and encoding != ""
223
+ data = data.to_s().encode(encoding, "UTF-8")
224
+ end
225
+ return path, data, headers_t
226
+ rescue Exception => stack
227
+ @logger.fatal(stack)
228
+ @logger.fatal("manage_request Error on method #{method_s} . path:#{path.to_s()}. data:#{data.to_s()}. headers:#{headers_t.to_s()}")
229
+ return :error
230
+ end
231
+ end
232
+
233
+ end
@@ -0,0 +1,179 @@
1
+ module NiceHttpManageResponse
2
+
3
+ ######################################################
4
+ # private method to manage Response
5
+ # input:
6
+ # resp
7
+ # data
8
+ # output:
9
+ # @response updated
10
+ ######################################################
11
+ def manage_response(resp, data)
12
+ require "json"
13
+ begin
14
+ if @start_time.kind_of?(Time)
15
+ @response[:time_elapsed_total] = Time.now - @start_time
16
+ @start_time = nil
17
+ else
18
+ @response[:time_elapsed_total] = nil
19
+ end
20
+ if @start_time_net.kind_of?(Time)
21
+ @response[:time_elapsed] = Time.now - @start_time_net
22
+ @start_time_net = nil
23
+ else
24
+ @response[:time_elapsed] = nil
25
+ end
26
+ begin
27
+ # this is to be able to access all keys as symbols
28
+ new_resp = Hash.new()
29
+ resp.each { |key, value|
30
+ if key.kind_of?(String)
31
+ new_resp[key.to_sym] = value
32
+ end
33
+ }
34
+ new_resp.each { |key, value|
35
+ resp[key] = value
36
+ }
37
+ rescue
38
+ end
39
+ #for mock_responses to be able to add outside of the header like content-type for example
40
+ if resp.kind_of?(Hash) and !resp.has_key?(:header)
41
+ resp[:header] = {}
42
+ end
43
+ if resp.kind_of?(Hash)
44
+ resp.each { |k, v|
45
+ if k != :code and k != :message and k != :data and k != :'set-cookie' and k != :header
46
+ resp[:header][k] = v
47
+ end
48
+ }
49
+ resp[:header].each { |k, v|
50
+ resp.delete(k) if resp.has_key?(k)
51
+ }
52
+ end
53
+
54
+ method_s = caller[0].to_s().scan(/:in `(.*)'/).join
55
+ if resp.header.kind_of?(Hash) and (resp.header["content-type"].to_s() == "application/x-deflate" or resp.header[:"content-type"].to_s() == "application/x-deflate")
56
+ data = Zlib::Inflate.inflate(data)
57
+ end
58
+ encoding_response = ""
59
+ if resp.header.kind_of?(Hash) and (resp.header["content-type"].to_s() != "" or resp.header[:"content-type"].to_s() != "")
60
+ encoding_response = resp.header["content-type"].scan(/;charset=(.*)/i).join if resp.header.has_key?("content-type")
61
+ encoding_response = resp.header[:"content-type"].scan(/;charset=(.*)/i).join if resp.header.has_key?(:"content-type")
62
+ end
63
+ if encoding_response.to_s() == ""
64
+ encoding_response = "UTF-8"
65
+ end
66
+
67
+ if encoding_response.to_s() != "" and encoding_response.to_s().upcase != "UTF-8"
68
+ data.encode!("UTF-8", encoding_response.to_s())
69
+ end
70
+
71
+ if encoding_response != "" and encoding_response.to_s().upcase != "UTF-8"
72
+ @response[:message] = resp.message.to_s().encode("UTF-8", encoding_response.to_s())
73
+ #todo: response data in here for example is convert into string, verify if that is correct or needs to maintain the original data type (hash, array...)
74
+ resp.each { |key, val| @response[key.to_sym] = val.to_s().encode("UTF-8", encoding_response.to_s()) }
75
+ else
76
+ @response[:message] = resp.message
77
+ resp.each { |key, val|
78
+ @response[key.to_sym] = val
79
+ }
80
+ end
81
+
82
+ if !defined?(Net::HTTP::Post::Multipart) or (defined?(Net::HTTP::Post::Multipart) and !data.kind_of?(Net::HTTP::Post::Multipart))
83
+ @response[:data] = data
84
+ else
85
+ @response[:data] = ""
86
+ end
87
+
88
+ @response[:code] = resp.code
89
+
90
+ unless @response.nil?
91
+ message = "\nRESPONSE: \n" + @response[:code].to_s() + ":" + @response[:message].to_s()
92
+ #if @debug
93
+ self.class.last_response = message if @debug
94
+ @response.each { |key, value|
95
+ if value.to_s() != ""
96
+ value_orig = value
97
+ if key.kind_of?(Symbol)
98
+ if key == :code or key == :data or key == :header or key == :message
99
+ if key == :data
100
+ begin
101
+ JSON.parse(value_orig)
102
+ data_s = JSON.pretty_generate(JSON.parse(value_orig))
103
+ rescue
104
+ data_s = value_orig
105
+ end
106
+ if @debug
107
+ self.class.last_response += "\nresponse." + key.to_s() + " = '" + data_s.gsub("<", "&lt;") + "'\n"
108
+ end
109
+ if value_orig != value
110
+ message += "\nresponse." + key.to_s() + " = '" + value.gsub("<", "&lt;") + "'\n"
111
+ else
112
+ message += "\nresponse." + key.to_s() + " = '" + data_s.gsub("<", "&lt;") + "'\n"
113
+ end
114
+ else
115
+ if @debug
116
+ self.class.last_response += "\nresponse." + key.to_s() + " = '" + value.to_s().gsub("<", "&lt;") + "'"
117
+ message += "\nresponse." + key.to_s() + " = '" + value.to_s().gsub("<", "&lt;") + "'"
118
+ end
119
+ end
120
+ else
121
+ if @debug
122
+ self.class.last_response += "\nresponse[:" + key.to_s() + "] = '" + value.to_s().gsub("<", "&lt;") + "'"
123
+ end
124
+ message += "\nresponse[:" + key.to_s() + "] = '" + value.to_s().gsub("<", "&lt;") + "'"
125
+ end
126
+ elsif !@response.include?(key.to_sym)
127
+ if @debug
128
+ self.class.last_response += "\nresponse['" + key.to_s() + "'] = '" + value.to_s().gsub("<", "&lt;") + "'"
129
+ end
130
+ message += "\nresponse['" + key.to_s() + "'] = '" + value.to_s().gsub("<", "&lt;") + "'"
131
+ end
132
+ end
133
+ }
134
+ #end
135
+ @logger.info message
136
+ if @response.kind_of?(Hash)
137
+ if @response.keys.include?(:requestid)
138
+ @headers["requestId"] = @response[:requestid]
139
+ self.class.request_id = @response[:requestid]
140
+ @logger.info "requestId was found on the response header and it has been added to the headers for the next request"
141
+ end
142
+ end
143
+ end
144
+
145
+ if resp[:'set-cookie'].to_s() != ""
146
+ if resp.kind_of?(Hash) #mock_response
147
+ cookies_to_set = resp[:'set-cookie'].to_s().split(", ")
148
+ else #Net::Http
149
+ cookies_to_set = resp.get_fields("set-cookie")
150
+ end
151
+ cookies_to_set.each { |cookie|
152
+ cookie_pair = cookie.split("; ")[0].split("=")
153
+ cookie_path = cookie.scan(/; path=([^;]+)/i).join
154
+ @cookies[cookie_path] = Hash.new() unless @cookies.keys.include?(cookie_path)
155
+ @cookies[cookie_path][cookie_pair[0]] = cookie_pair[1]
156
+ }
157
+
158
+ @logger.info "set-cookie added to Cookie header as required"
159
+
160
+ if @headers.has_key?("X-CSRFToken")
161
+ csrftoken = resp[:"set-cookie"].to_s().scan(/csrftoken=([\da-z]+);/).join
162
+ if csrftoken.to_s() != ""
163
+ @headers["X-CSRFToken"] = csrftoken
164
+ @logger.info "X-CSRFToken exists on headers and has been overwritten"
165
+ end
166
+ else
167
+ csrftoken = resp[:"set-cookie"].to_s().scan(/csrftoken=([\da-z]+);/).join
168
+ if csrftoken.to_s() != ""
169
+ @headers["X-CSRFToken"] = csrftoken
170
+ @logger.info "X-CSRFToken added to header as required"
171
+ end
172
+ end
173
+ end
174
+ rescue Exception => stack
175
+ @logger.fatal stack
176
+ @logger.fatal "manage_response Error on method #{method_s} "
177
+ end
178
+ end
179
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nice_http
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.0
4
+ version: 1.5.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mario Ruiz
@@ -84,6 +84,9 @@ files:
84
84
  - LICENSE
85
85
  - README.md
86
86
  - lib/nice_http.rb
87
+ - lib/nice_http/http_methods.rb
88
+ - lib/nice_http/manage_request.rb
89
+ - lib/nice_http/manage_response.rb
87
90
  - lib/nice_http/utils.rb
88
91
  homepage: https://github.com/MarioRuiz/nice_http
89
92
  licenses: