nice_http 1.5.0 → 1.5.1

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