nice_http 1.0.0 → 1.0.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 +4 -4
- data/lib/nice_http.rb +1098 -1098
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d94d6ba065b13e963583cfbed6501a6e458fad1106e7b833a87a468a7ff65941
|
4
|
+
data.tar.gz: 59008a785b4e774beb5e3ecfb80e79ddd8cb072a79519e1cf0589039246b4047
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 48494568e34e0c51274520b0f4917d2c7c6d196efb9328816f39c4fb41eb30bc2c63000e040b855c31111e49b82433fbd0885eb8848c481763b442f2b45f3dc2
|
7
|
+
data.tar.gz: d9862a9a07645239443d5cefbbf8a28e61d4f9611757a529d06fccf91356ee76500a0512fa03f38dc915e206de4f0eedc6f00c89fa041888a3eec22e77b311fa
|
data/lib/nice_http.rb
CHANGED
@@ -1,1098 +1,1098 @@
|
|
1
|
-
require 'logger'
|
2
|
-
require 'nice_hash'
|
3
|
-
require 'nice_http_utils'
|
4
|
-
|
5
|
-
class NiceHttp
|
6
|
-
class << self
|
7
|
-
attr_accessor :host, :port, :ssl, :headers, :debug, :log, :proxy_host, :proxy_port,
|
8
|
-
:last_request, :last_response, :request_id, :use_mocks, :connections,
|
9
|
-
:active, :auto_redirect
|
10
|
-
end
|
11
|
-
@host = nil
|
12
|
-
@port = 80
|
13
|
-
@ssl = false
|
14
|
-
@headers = {}
|
15
|
-
@debug = false
|
16
|
-
@log = :fix_file
|
17
|
-
@proxy_host = nil
|
18
|
-
@proxy_port = nil
|
19
|
-
@last_request=nil
|
20
|
-
@last_response=nil
|
21
|
-
@request_id=""
|
22
|
-
@use_mocks = false
|
23
|
-
@connections = []
|
24
|
-
@active=0
|
25
|
-
@auto_redirect = true
|
26
|
-
|
27
|
-
attr_reader :host, :port, :ssl, :debug, :log, :proxy_host, :proxy_port, :response, :num_redirects
|
28
|
-
attr_accessor :headers, :cookies, :use_mocks, :auto_redirect, :logger
|
29
|
-
|
30
|
-
def self.defaults=(par = {})
|
31
|
-
@host = par[:host] if par.key?(:host)
|
32
|
-
@port = par[:port] if par.key?(:port)
|
33
|
-
@ssl = par[:ssl] if par.key?(:ssl)
|
34
|
-
@headers = par[:headers] if par.key?(:headers)
|
35
|
-
@debug = par[:debug] if par.key?(:debug)
|
36
|
-
@log = par[:log] if par.key?(:log)
|
37
|
-
@proxy_host = par[:proxy_host] if par.key?(:proxy_host)
|
38
|
-
@proxy_port = par[:proxy_port] if par.key?(:proxy_port)
|
39
|
-
@proxy_port = par[:use_mocks] if par.key?(:use_mocks)
|
40
|
-
@auto_redirect = par[:auto_redirect] if par.key?(:auto_redirect)
|
41
|
-
end
|
42
|
-
|
43
|
-
######################################################
|
44
|
-
# input:
|
45
|
-
# no parameters:
|
46
|
-
# By default will access how is setup on defaults
|
47
|
-
# one parameter:
|
48
|
-
# String
|
49
|
-
# "https://www.example.com"
|
50
|
-
# "example.com:8999"
|
51
|
-
# "localhost:8322"
|
52
|
-
# Hash containing these possible keys
|
53
|
-
# host -- example.com. (default blank screen)
|
54
|
-
# port -- port for the connection. 80 (default)
|
55
|
-
# ssl -- true, false (default)
|
56
|
-
# headers -- hash with the header key:values
|
57
|
-
# debug -- true, false (default)
|
58
|
-
# log -- :no, :screen, :file, :fix_file (default).
|
59
|
-
# A string with a path can be supplied.
|
60
|
-
# If :fix_file: nice_http.log
|
61
|
-
# In case :file it will be generated a log file with name: nice_http_YY-mm-dd-HHMMSS.log
|
62
|
-
# proxy_host
|
63
|
-
# proxy_port
|
64
|
-
######################################################
|
65
|
-
def initialize(args = {})
|
66
|
-
require 'net/http'
|
67
|
-
require 'net/https'
|
68
|
-
@host = NiceHttp.host
|
69
|
-
@port = NiceHttp.port
|
70
|
-
@ssl = NiceHttp.ssl
|
71
|
-
@headers = NiceHttp.headers
|
72
|
-
@debug = NiceHttp.debug
|
73
|
-
@log = NiceHttp.log
|
74
|
-
@proxy_host = NiceHttp.proxy_host
|
75
|
-
@proxy_port = NiceHttp.proxy_port
|
76
|
-
@use_mocks = NiceHttp.use_mocks
|
77
|
-
@auto_redirect=false #set it up at the end of initialize
|
78
|
-
auto_redirect = NiceHttp.auto_redirect
|
79
|
-
@num_redirects=0
|
80
|
-
|
81
|
-
#todo: set only the cookies for the current domain
|
82
|
-
#key: path, value: hash with key is the name of the cookie and value the value
|
83
|
-
# we set the default value for non existing keys to empty Hash {} so in case of merge there is no problem
|
84
|
-
@cookies=Hash.new {|h, k| h[k] = {}}
|
85
|
-
|
86
|
-
begin
|
87
|
-
if args.is_a?(String)
|
88
|
-
uri = URI.parse(args)
|
89
|
-
@host = uri.host unless uri.host.nil?
|
90
|
-
@port = uri.port unless uri.port.nil?
|
91
|
-
@ssl = true if !uri.scheme.nil? && (uri.scheme == 'https')
|
92
|
-
elsif args.is_a?(Hash) && !args.keys.empty?
|
93
|
-
@host = args[:host] if args.keys.include?(:host)
|
94
|
-
@port = args[:port] if args.keys.include?(:port)
|
95
|
-
@ssl = args[:ssl] if args.keys.include?(:ssl)
|
96
|
-
@headers = args[:headers] if args.keys.include?(:headers)
|
97
|
-
@debug = args[:debug] if args.keys.include?(:debug)
|
98
|
-
@log = args[:log] if args.keys.include?(:log)
|
99
|
-
@proxy_host = args[:proxy_host] if args.keys.include?(:proxy_host)
|
100
|
-
@proxy_port = args[:proxy_port] if args.keys.include?(:proxy_port)
|
101
|
-
@use_mocks = args[:use_mocks] if args.keys.include?(:use_mocks)
|
102
|
-
@auto_redirect = args[:auto_redirect] if args.keys.include?(:auto_redirect)
|
103
|
-
end
|
104
|
-
|
105
|
-
if @host.to_s!="" and (@host.include?("http:") or @host.include?("https:"))
|
106
|
-
uri = URI.parse(@host)
|
107
|
-
@host = uri.host unless uri.host.nil?
|
108
|
-
@port = uri.port unless uri.port.nil?
|
109
|
-
@ssl = true if !uri.scheme.nil? && (uri.scheme == 'https')
|
110
|
-
end
|
111
|
-
|
112
|
-
if @host.nil? or @host.to_s=="" or @port.nil? or @port.to_s==""
|
113
|
-
message = "It was not possible to create the http connection!!!\n"
|
114
|
-
message += "Wrong host or port, remember to supply http:// or https:// in case you specify an url to create the http connection, for example:\n"
|
115
|
-
message += "http = NiceHttp.new('http://example.com')"
|
116
|
-
raise message
|
117
|
-
end
|
118
|
-
|
119
|
-
if !@proxy_host.nil? && !@proxy_port.nil?
|
120
|
-
@http = Net::HTTP::Proxy(@proxy_host, @proxy_port).new(@host, @port)
|
121
|
-
@http.use_ssl = @ssl
|
122
|
-
@http.set_debug_output $stderr if @debug
|
123
|
-
@http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
124
|
-
@http.start
|
125
|
-
else
|
126
|
-
@http = Net::HTTP.new(@host, @port)
|
127
|
-
@http.use_ssl = @ssl
|
128
|
-
@http.set_debug_output $stderr if @debug
|
129
|
-
@http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
130
|
-
@http.start
|
131
|
-
end
|
132
|
-
|
133
|
-
if @log.kind_of?(String)
|
134
|
-
@logger = Logger.new File.new(@log, "w")
|
135
|
-
elsif @log==:fix_file
|
136
|
-
@logger = Logger.new File.new("nice_http.log", "w")
|
137
|
-
elsif @log==:file
|
138
|
-
@logger = Logger.new File.new("nice_http_#{Time.now.strftime('%Y-%m-%d-%H%M%S')}.log", 'w')
|
139
|
-
elsif @log==:screen
|
140
|
-
@logger = Logger.new STDOUT
|
141
|
-
elsif @log==:no
|
142
|
-
@logger = Logger.new nil
|
143
|
-
end
|
144
|
-
@logger.level = Logger::INFO
|
145
|
-
|
146
|
-
@message_server="(#{self.object_id}):"
|
147
|
-
|
148
|
-
log_message="(#{self.object_id}): Http connection created. host:#{@host}, port:#{@port}, ssl:#{@ssl}, mode:#{@mode}, proxy_host: #{@proxy_host.to_s()}, proxy_port: #{@proxy_port.to_s()} "
|
149
|
-
|
150
|
-
@logger.info(log_message)
|
151
|
-
@message_server+=" Http connection: "
|
152
|
-
if @ssl then
|
153
|
-
@message_server+="https://"
|
154
|
-
else
|
155
|
-
@message_server+="http://"
|
156
|
-
end
|
157
|
-
@message_server+="#{@host}:#{@port}"
|
158
|
-
if @proxy_host.to_s!="" then
|
159
|
-
@message_server+=" proxy:#{@proxy_host}:#{@proxy_port}"
|
160
|
-
end
|
161
|
-
@auto_redirect = auto_redirect
|
162
|
-
rescue Exception => stack
|
163
|
-
if @logger.nil?
|
164
|
-
puts stack
|
165
|
-
@logger = Logger.new nil
|
166
|
-
else
|
167
|
-
@logger.fatal stack
|
168
|
-
end
|
169
|
-
end
|
170
|
-
|
171
|
-
NiceHttp.active+=1
|
172
|
-
NiceHttp.connections.push(self)
|
173
|
-
|
174
|
-
end
|
175
|
-
|
176
|
-
######################################################
|
177
|
-
# Get data from path
|
178
|
-
# input:
|
179
|
-
# 1 argument
|
180
|
-
# Hash containing at least key :path
|
181
|
-
# 1 argument
|
182
|
-
# path (string)
|
183
|
-
# output:
|
184
|
-
# response -> Hash including at least the symbol keys:
|
185
|
-
# :data = the response data body
|
186
|
-
# :message = plain text response
|
187
|
-
# :code = code response (200=ok,500=wrong...)
|
188
|
-
# *All keys in response are lowercase
|
189
|
-
# data, message and code can also be accessed as attributes like .message .code .data, for example:
|
190
|
-
# resp=@http.get(Requests::Customer.get_profile)
|
191
|
-
# assert resp.code==200
|
192
|
-
######################################################
|
193
|
-
def get(arg)
|
194
|
-
begin
|
195
|
-
path, data, headers_t=manage_request(arg)
|
196
|
-
@start_time = Time.now if @start_time.nil?
|
197
|
-
if @use_mocks and arg.kind_of?(Hash) and arg.keys.include?(:mock_response) then
|
198
|
-
data=""
|
199
|
-
if arg[:mock_response].keys.include?(:data) then
|
200
|
-
data=arg[:mock_response][:data]
|
201
|
-
if data.kind_of?(Hash) #to json
|
202
|
-
begin
|
203
|
-
require 'json'
|
204
|
-
data=data.to_json
|
205
|
-
rescue
|
206
|
-
@logger.fatal "There was a problem converting to json: #{data}"
|
207
|
-
end
|
208
|
-
end
|
209
|
-
end
|
210
|
-
@logger.warn "Pay attention!!! This is a mock response:"
|
211
|
-
@start_time_net = Time.now if @start_time_net.nil?
|
212
|
-
manage_response(arg[:mock_response], data.to_s)
|
213
|
-
return @response
|
214
|
-
end
|
215
|
-
begin
|
216
|
-
if path.start_with?("http:") or path.start_with?("https:") then #server included on path problably because of a redirection to a different server
|
217
|
-
require 'uri'
|
218
|
-
uri = URI.parse(path)
|
219
|
-
ssl=false
|
220
|
-
ssl=true if path.include?("https:")
|
221
|
-
|
222
|
-
|
223
|
-
server="http://"
|
224
|
-
server="https://" if path.include?("https:")
|
225
|
-
if uri.port!=443 then
|
226
|
-
server+="#{uri.host}:#{uri.port}"
|
227
|
-
else
|
228
|
-
server+="#{uri.host}"
|
229
|
-
end
|
230
|
-
|
231
|
-
http_redir=nil
|
232
|
-
NiceHttp.connections.each {|conn|
|
233
|
-
if conn.host == uri.host and conn.port==uri.port then
|
234
|
-
http_redir=conn
|
235
|
-
break
|
236
|
-
end
|
237
|
-
}
|
238
|
-
|
239
|
-
if !http_redir.nil?
|
240
|
-
path, data, headers_t=manage_request(arg)
|
241
|
-
http_redir.cookies.merge!(@cookies)
|
242
|
-
http_redir.headers.merge!(headers_t)
|
243
|
-
resp=http_redir.get(path.gsub(server, "")) #todo: remove only the server at the begining in case in query is the server it will be replaced when it should not be
|
244
|
-
@response=http_redir.response
|
245
|
-
else
|
246
|
-
@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."
|
247
|
-
end
|
248
|
-
|
249
|
-
else
|
250
|
-
@start_time_net = Time.now if @start_time_net.nil?
|
251
|
-
resp=@http.get(path, headers_t)
|
252
|
-
data=resp.body
|
253
|
-
manage_response(resp, data)
|
254
|
-
end
|
255
|
-
rescue Exception => stack
|
256
|
-
@logger.warn stack
|
257
|
-
@logger.warn "The connection seems to be closed in the host machine. Trying to reconnect"
|
258
|
-
@http.finish()
|
259
|
-
@http.start()
|
260
|
-
@start_time_net = Time.now if @start_time_net.nil?
|
261
|
-
resp=@http.get(path)
|
262
|
-
data=resp.body
|
263
|
-
manage_response(resp, data)
|
264
|
-
end
|
265
|
-
if @auto_redirect and @response[:code].to_i>=300 and @response[:code].to_i<400 and @response.include?(:location) then
|
266
|
-
if @num_redirects<=30 then
|
267
|
-
@num_redirects+=1
|
268
|
-
current_server="http"
|
269
|
-
current_server+="s" if @ssl==true
|
270
|
-
current_server+="://#{@host}"
|
271
|
-
location=@response[:location].gsub(current_server, "")
|
272
|
-
@logger.info "(#{@num_redirects}) Redirecting NiceHttp to #{location}"
|
273
|
-
get(location)
|
274
|
-
else
|
275
|
-
@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"
|
276
|
-
@num_redirects=0
|
277
|
-
end
|
278
|
-
else
|
279
|
-
@num_redirects=0
|
280
|
-
end
|
281
|
-
return @response
|
282
|
-
rescue Exception => stack
|
283
|
-
@logger.fatal stack
|
284
|
-
return :error
|
285
|
-
end
|
286
|
-
end
|
287
|
-
|
288
|
-
######################################################
|
289
|
-
# Post data to path
|
290
|
-
# input:
|
291
|
-
# 1 argument
|
292
|
-
# Hash containing at least keys :data, :path
|
293
|
-
# 3 arguments
|
294
|
-
# path (string)
|
295
|
-
# data (json data for example)
|
296
|
-
# additional_headers (Hash key=>value)
|
297
|
-
# output:
|
298
|
-
# response -> Hash including at least the symbol keys:
|
299
|
-
# :data = the response data body
|
300
|
-
# :message = plain text response
|
301
|
-
# :code = code response (200=ok,500=wrong...)
|
302
|
-
# *All keys in response are lowercase
|
303
|
-
# data, message and code can also be accessed as attributes like .message .code .data, for example:
|
304
|
-
# resp=@http.post(Requests::Customer.update_customer)
|
305
|
-
# assert resp.code==201
|
306
|
-
######################################################
|
307
|
-
def post(*arguments)
|
308
|
-
begin
|
309
|
-
path, data, headers_t=manage_request(*arguments)
|
310
|
-
@start_time = Time.now if @start_time.nil?
|
311
|
-
if arguments.size>0 and arguments[0].kind_of?(Hash) then
|
312
|
-
arg=arguments[0]
|
313
|
-
if @use_mocks and arg.kind_of?(Hash) and arg.keys.include?(:mock_response) then
|
314
|
-
data=""
|
315
|
-
if arg[:mock_response].keys.include?(:data) then
|
316
|
-
data=arg[:mock_response][:data]
|
317
|
-
if data.kind_of?(Hash) #to json
|
318
|
-
begin
|
319
|
-
require 'json'
|
320
|
-
data=data.to_json
|
321
|
-
rescue
|
322
|
-
@logger.fatal "There was a problem converting to json: #{data}"
|
323
|
-
end
|
324
|
-
end
|
325
|
-
end
|
326
|
-
@logger.warn "Pay attention!!! This is a mock response:"
|
327
|
-
@start_time_net = Time.now if @start_time_net.nil?
|
328
|
-
manage_response(arg[:mock_response], data.to_s)
|
329
|
-
return @response
|
330
|
-
end
|
331
|
-
end
|
332
|
-
|
333
|
-
begin
|
334
|
-
@start_time_net = Time.now if @start_time_net.nil?
|
335
|
-
if headers_t["Content-Type"] == "multipart/form-data" then
|
336
|
-
require 'net/http/post/multipart'
|
337
|
-
headers_t.each {|key, value|
|
338
|
-
arguments[0][:data].add_field(key, value) #add to Headers
|
339
|
-
}
|
340
|
-
resp=@http.request(arguments[0][:data])
|
341
|
-
else
|
342
|
-
resp=@http.post(path, data, headers_t)
|
343
|
-
data=resp.body
|
344
|
-
end
|
345
|
-
rescue Exception => stack
|
346
|
-
@logger.warn stack
|
347
|
-
@logger.warn "The connection seems to be closed in the host machine. Trying to reconnect"
|
348
|
-
@http.finish()
|
349
|
-
@http.start()
|
350
|
-
@start_time_net = Time.now if @start_time_net.nil?
|
351
|
-
resp, data=@http.post(path, data, headers_t)
|
352
|
-
end
|
353
|
-
manage_response(resp, data)
|
354
|
-
if @auto_redirect and @response[:code].to_i>=300 and @response[:code].to_i<400 and @response.include?(:location) then
|
355
|
-
if @num_redirects<=30 then
|
356
|
-
@num_redirects+=1
|
357
|
-
current_server="http"
|
358
|
-
current_server+="s" if @ssl==true
|
359
|
-
current_server+="://#{@host}"
|
360
|
-
location=@response[:location].gsub(current_server, "")
|
361
|
-
@logger.info "(#{@num_redirects}) Redirecting NiceHttp to #{location}"
|
362
|
-
get(location)
|
363
|
-
else
|
364
|
-
@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"
|
365
|
-
@num_redirects=0
|
366
|
-
end
|
367
|
-
else
|
368
|
-
@num_redirects=0
|
369
|
-
end
|
370
|
-
return @response
|
371
|
-
rescue Exception => stack
|
372
|
-
@logger.warn stack
|
373
|
-
return :error
|
374
|
-
end
|
375
|
-
|
376
|
-
end
|
377
|
-
|
378
|
-
|
379
|
-
######################################################
|
380
|
-
# Put data to path
|
381
|
-
# input:
|
382
|
-
# 1 argument
|
383
|
-
# Hash containing at least keys :data, :path
|
384
|
-
# 3 arguments
|
385
|
-
# path (string)
|
386
|
-
# data (json data for example)
|
387
|
-
# additional_headers (Hash key=>value)
|
388
|
-
# output:
|
389
|
-
# response -> Hash including at least the symbol keys:
|
390
|
-
# :data = the response data body
|
391
|
-
# :message = plain text response
|
392
|
-
# :code = code response (200=ok,500=wrong...)
|
393
|
-
# *All keys in response are lowercase
|
394
|
-
# data, message and code can also be accessed as attributes like .message .code .data, for example:
|
395
|
-
# resp=@http.put(Requests::Customer.remove_phone)
|
396
|
-
# assert resp.code==200
|
397
|
-
######################################################
|
398
|
-
def put(*arguments)
|
399
|
-
begin
|
400
|
-
path, data, headers_t=manage_request(*arguments)
|
401
|
-
@start_time = Time.now if @start_time.nil?
|
402
|
-
if arguments.size>0 and arguments[0].kind_of?(Hash) then
|
403
|
-
arg=arguments[0]
|
404
|
-
if @use_mocks and arg.kind_of?(Hash) and arg.keys.include?(:mock_response) then
|
405
|
-
data=""
|
406
|
-
if arg[:mock_response].keys.include?(:data) then
|
407
|
-
data=arg[:mock_response][:data]
|
408
|
-
if data.kind_of?(Hash) #to json
|
409
|
-
begin
|
410
|
-
require 'json'
|
411
|
-
data=data.to_json
|
412
|
-
rescue
|
413
|
-
@logger.fatal "There was a problem converting to json: #{data}"
|
414
|
-
end
|
415
|
-
end
|
416
|
-
end
|
417
|
-
@logger.warn "Pay attention!!! This is a mock response:"
|
418
|
-
@start_time_net = Time.now if @start_time_net.nil?
|
419
|
-
manage_response(arg[:mock_response], data.to_s)
|
420
|
-
return @response
|
421
|
-
end
|
422
|
-
end
|
423
|
-
|
424
|
-
begin
|
425
|
-
@start_time_net = Time.now if @start_time_net.nil?
|
426
|
-
resp=@http.send_request("PUT", path, data, headers_t)
|
427
|
-
data=resp.body
|
428
|
-
rescue Exception => stack
|
429
|
-
@logger.warn stack
|
430
|
-
@logger.warn "The connection seems to be closed in the host machine. Trying to reconnect"
|
431
|
-
@http.finish()
|
432
|
-
@http.start()
|
433
|
-
@start_time_net = Time.now if @start_time_net.nil?
|
434
|
-
resp, data=@http.send_request("PUT", path, data, headers_t)
|
435
|
-
end
|
436
|
-
manage_response(resp, data)
|
437
|
-
|
438
|
-
return @response
|
439
|
-
rescue Exception => stack
|
440
|
-
@logger.fatal stack, self
|
441
|
-
return :error
|
442
|
-
end
|
443
|
-
|
444
|
-
end
|
445
|
-
|
446
|
-
|
447
|
-
######################################################
|
448
|
-
# Patch data to path
|
449
|
-
# input:
|
450
|
-
# 1 argument
|
451
|
-
# Hash containing at least keys :data, :path
|
452
|
-
# 3 arguments
|
453
|
-
# path (string)
|
454
|
-
# data (json data for example)
|
455
|
-
# additional_headers (Hash key=>value)
|
456
|
-
# output:
|
457
|
-
# response -> Hash including at least the symbol keys:
|
458
|
-
# :data = the response data body
|
459
|
-
# :message = plain text response
|
460
|
-
# :code = code response (200=ok,500=wrong...)
|
461
|
-
# *All keys in response are lowercase
|
462
|
-
# data, message and code can also be accessed as attributes like .message .code .data, for example:
|
463
|
-
# resp=@http.patch(Requests::Customer.unrelease_account)
|
464
|
-
# assert resp.code==200
|
465
|
-
######################################################
|
466
|
-
def patch(*arguments)
|
467
|
-
begin
|
468
|
-
path, data, headers_t=manage_request(*arguments)
|
469
|
-
@start_time = Time.now if @start_time.nil?
|
470
|
-
if arguments.size>0 and arguments[0].kind_of?(Hash) then
|
471
|
-
arg=arguments[0]
|
472
|
-
if @use_mocks and arg.kind_of?(Hash) and arg.keys.include?(:mock_response) then
|
473
|
-
data=""
|
474
|
-
if arg[:mock_response].keys.include?(:data) then
|
475
|
-
data=arg[:mock_response][:data]
|
476
|
-
if data.kind_of?(Hash) #to json
|
477
|
-
begin
|
478
|
-
require 'json'
|
479
|
-
data=data.to_json
|
480
|
-
rescue
|
481
|
-
@logger.fatal "There was a problem converting to json: #{data}"
|
482
|
-
end
|
483
|
-
end
|
484
|
-
end
|
485
|
-
@logger.warn "Pay attention!!! This is a mock response:"
|
486
|
-
@start_time_net = Time.now if @start_time_net.nil?
|
487
|
-
manage_response(arg[:mock_response], data.to_s)
|
488
|
-
return @response
|
489
|
-
end
|
490
|
-
end
|
491
|
-
|
492
|
-
begin
|
493
|
-
@start_time_net = Time.now if @start_time_net.nil?
|
494
|
-
resp=@http.patch(path, data, headers_t)
|
495
|
-
data=resp.body
|
496
|
-
rescue Exception => stack
|
497
|
-
@logger.warn stack
|
498
|
-
@logger.warn "The connection seems to be closed in the host machine. Trying to reconnect"
|
499
|
-
@http.finish()
|
500
|
-
@http.start()
|
501
|
-
@start_time_net = Time.now if @start_time_net.nil?
|
502
|
-
resp, data=@http.patch(path, data, headers_t)
|
503
|
-
end
|
504
|
-
manage_response(resp, data)
|
505
|
-
if @auto_redirect and @response[:code].to_i>=300 and @response[:code].to_i<400 and @response.include?(:location) then
|
506
|
-
if @num_redirects<=30 then
|
507
|
-
@num_redirects+=1
|
508
|
-
current_server="http"
|
509
|
-
current_server+="s" if @ssl==true
|
510
|
-
current_server+="://#{@host}"
|
511
|
-
location=@response[:location].gsub(current_server, "")
|
512
|
-
@logger.info "(#{@num_redirects}) Redirecting NiceHttp to #{location}"
|
513
|
-
get(location)
|
514
|
-
else
|
515
|
-
@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"
|
516
|
-
@num_redirects=0
|
517
|
-
end
|
518
|
-
else
|
519
|
-
@num_redirects=0
|
520
|
-
end
|
521
|
-
return @response
|
522
|
-
rescue Exception => stack
|
523
|
-
@logger.fatal stack
|
524
|
-
return :error
|
525
|
-
end
|
526
|
-
|
527
|
-
end
|
528
|
-
|
529
|
-
|
530
|
-
######################################################
|
531
|
-
# Delete an existing resource
|
532
|
-
# input:
|
533
|
-
# 1 argument
|
534
|
-
# Hash containing at least key :path
|
535
|
-
# 1 argument
|
536
|
-
# String giving the path
|
537
|
-
# output:
|
538
|
-
# response -> Hash including at least the symbol keys:
|
539
|
-
# :data = the response data body
|
540
|
-
# :message = plain text response
|
541
|
-
# :code = code response (200=ok,500=wrong...)
|
542
|
-
# *All keys in response are lowercase
|
543
|
-
# data, message and code can also be accessed as attributes like .message .code .data, for example:
|
544
|
-
# resp=@http.delete(Requests::Customer.remove_session)
|
545
|
-
# assert resp.code==204
|
546
|
-
######################################################
|
547
|
-
def delete(argument)
|
548
|
-
begin
|
549
|
-
if argument.kind_of?(String) then
|
550
|
-
argument={:path => argument}
|
551
|
-
end
|
552
|
-
path, data, headers_t=manage_request(argument)
|
553
|
-
@start_time = Time.now if @start_time.nil?
|
554
|
-
if argument.kind_of?(Hash) then
|
555
|
-
arg=argument
|
556
|
-
if @use_mocks and arg.kind_of?(Hash) and arg.keys.include?(:mock_response) then
|
557
|
-
data=""
|
558
|
-
if arg[:mock_response].keys.include?(:data) then
|
559
|
-
data=arg[:mock_response][:data]
|
560
|
-
if data.kind_of?(Hash) #to json
|
561
|
-
begin
|
562
|
-
require 'json'
|
563
|
-
data=data.to_json
|
564
|
-
rescue
|
565
|
-
@logger.fatal "There was a problem converting to json: #{data}"
|
566
|
-
end
|
567
|
-
end
|
568
|
-
end
|
569
|
-
@logger.warn "Pay attention!!! This is a mock response:"
|
570
|
-
@start_time_net = Time.now if @start_time_net.nil?
|
571
|
-
manage_response(arg[:mock_response], data.to_s)
|
572
|
-
return @response
|
573
|
-
end
|
574
|
-
end
|
575
|
-
|
576
|
-
begin
|
577
|
-
@start_time_net = Time.now if @start_time_net.nil?
|
578
|
-
resp=@http.delete(path, headers_t)
|
579
|
-
data=resp.body
|
580
|
-
rescue Exception => stack
|
581
|
-
@logger.warn stack
|
582
|
-
@logger.warn "The connection seems to be closed in the host machine. Trying to reconnect"
|
583
|
-
@http.finish()
|
584
|
-
@http.start()
|
585
|
-
@start_time_net = Time.now if @start_time_net.nil?
|
586
|
-
resp, data=@http.delete(path)
|
587
|
-
end
|
588
|
-
manage_response(resp, data)
|
589
|
-
|
590
|
-
return @response
|
591
|
-
rescue Exception => stack
|
592
|
-
@logger.fatal stack
|
593
|
-
return :error
|
594
|
-
end
|
595
|
-
|
596
|
-
end
|
597
|
-
|
598
|
-
######################################################
|
599
|
-
# Implementation of the http HEAD method.
|
600
|
-
# Asks for the response identical to the one that would correspond to a GET request, but without the response body.
|
601
|
-
# This is useful for retrieving meta-information written in response headers, without having to transport the entire content.
|
602
|
-
# input:
|
603
|
-
# 1 argument
|
604
|
-
# Hash containing at least key :path
|
605
|
-
# 1 argument
|
606
|
-
# String giving the path
|
607
|
-
# output:
|
608
|
-
# response -> Hash including the symbol keys:
|
609
|
-
# :message = plain text response
|
610
|
-
# :code = code response (200=ok,500=wrong...)
|
611
|
-
# *All keys in response are lowercase
|
612
|
-
######################################################
|
613
|
-
def head(argument)
|
614
|
-
begin
|
615
|
-
if argument.kind_of?(String) then
|
616
|
-
argument={:path => argument}
|
617
|
-
end
|
618
|
-
path, data, headers_t=manage_request(argument)
|
619
|
-
@start_time = Time.now if @start_time.nil?
|
620
|
-
if argument.kind_of?(Hash) then
|
621
|
-
arg=argument
|
622
|
-
if @use_mocks and arg.kind_of?(Hash) and arg.keys.include?(:mock_response) then
|
623
|
-
data=""
|
624
|
-
if arg[:mock_response].keys.include?(:data) then
|
625
|
-
data=arg[:mock_response][:data]
|
626
|
-
if data.kind_of?(Hash) #to json
|
627
|
-
begin
|
628
|
-
require 'json'
|
629
|
-
data=data.to_json
|
630
|
-
rescue
|
631
|
-
@logger.fatal "There was a problem converting to json: #{data}"
|
632
|
-
end
|
633
|
-
end
|
634
|
-
end
|
635
|
-
@logger.warn "Pay attention!!! This is a mock response:"
|
636
|
-
@start_time_net = Time.now if @start_time_net.nil?
|
637
|
-
manage_response(arg[:mock_response], data.to_s)
|
638
|
-
return @response
|
639
|
-
end
|
640
|
-
end
|
641
|
-
|
642
|
-
begin
|
643
|
-
@start_time_net = Time.now if @start_time_net.nil?
|
644
|
-
resp=@http.head(path, headers_t)
|
645
|
-
data=resp.body
|
646
|
-
rescue Exception => stack
|
647
|
-
@logger.warn stack
|
648
|
-
@logger.warn "The connection seems to be closed in the host machine. Trying to reconnect"
|
649
|
-
@http.finish()
|
650
|
-
@http.start()
|
651
|
-
@start_time_net = Time.now if @start_time_net.nil?
|
652
|
-
resp, data=@http.head(path)
|
653
|
-
end
|
654
|
-
manage_response(resp, data)
|
655
|
-
return @response
|
656
|
-
rescue Exception => stack
|
657
|
-
@logger.fatal stack
|
658
|
-
return :error
|
659
|
-
end
|
660
|
-
end
|
661
|
-
|
662
|
-
|
663
|
-
######################################################
|
664
|
-
# Close HTTP connection
|
665
|
-
######################################################
|
666
|
-
def close
|
667
|
-
begin
|
668
|
-
pos=0
|
669
|
-
found=false
|
670
|
-
NiceHttp.connections.each {|conn|
|
671
|
-
if conn.object_id == self.object_id then
|
672
|
-
found=true
|
673
|
-
break
|
674
|
-
end
|
675
|
-
pos+=1
|
676
|
-
}
|
677
|
-
if found
|
678
|
-
NiceHttp.connections.delete_at(pos)
|
679
|
-
end
|
680
|
-
|
681
|
-
unless @closed
|
682
|
-
if !@http.nil? then
|
683
|
-
@http.finish()
|
684
|
-
@http=nil
|
685
|
-
@logger.info "the HTTP connection was closed: #{@message_server}"
|
686
|
-
else
|
687
|
-
@http=nil
|
688
|
-
@logger.fatal "It was not possible to close the HTTP connection: #{@message_server}"
|
689
|
-
end
|
690
|
-
@closed=true
|
691
|
-
else
|
692
|
-
@logger.warn "It was not possible to close the HTTP connection, already closed: #{@message_server}"
|
693
|
-
end
|
694
|
-
rescue Exception => stack
|
695
|
-
@logger.fatal stack
|
696
|
-
end
|
697
|
-
NiceHttp.active-=1
|
698
|
-
end
|
699
|
-
|
700
|
-
|
701
|
-
######################################################
|
702
|
-
# private method to manage Request
|
703
|
-
# input:
|
704
|
-
# 3 args: path, data, headers
|
705
|
-
# 1 arg: Hash containg at least keys :path and :data
|
706
|
-
# output:
|
707
|
-
# path, data, headers
|
708
|
-
######################################################
|
709
|
-
def manage_request(*arguments)
|
710
|
-
require 'json'
|
711
|
-
begin
|
712
|
-
content_type_included=false
|
713
|
-
path=""
|
714
|
-
data=""
|
715
|
-
|
716
|
-
@response=Hash.new()
|
717
|
-
headers_t=@headers.dup()
|
718
|
-
cookies_to_set_str=""
|
719
|
-
if arguments.size==3 then
|
720
|
-
path=arguments[0]
|
721
|
-
elsif arguments.size==1 and arguments[0].kind_of?(Hash) then
|
722
|
-
path=arguments[0][:path]
|
723
|
-
elsif arguments.size==1 and arguments[0].kind_of?(String) then
|
724
|
-
path=arguments[0].to_s()
|
725
|
-
end
|
726
|
-
@cookies.each {|cookie_path, cookies_hash|
|
727
|
-
cookie_path="" if cookie_path=="/"
|
728
|
-
path_to_check=path
|
729
|
-
if path=="/" or path[-1]!="/" then
|
730
|
-
path_to_check+="/"
|
731
|
-
end
|
732
|
-
if path_to_check.scan(/^#{cookie_path}\//).size>0 then
|
733
|
-
cookies_hash.each {|key, value|
|
734
|
-
cookies_to_set_str+="#{key}=#{value}; "
|
735
|
-
}
|
736
|
-
end
|
737
|
-
}
|
738
|
-
headers_t["Cookie"]=cookies_to_set_str
|
739
|
-
|
740
|
-
method_s=caller[0].to_s().scan(/:in `(.*)'/).join
|
741
|
-
|
742
|
-
if arguments.size==3 then
|
743
|
-
data=arguments[1]
|
744
|
-
if arguments[2].kind_of?(Hash) then
|
745
|
-
headers_t.merge!(arguments[2])
|
746
|
-
end
|
747
|
-
elsif arguments.size==1 and arguments[0].kind_of?(Hash) then
|
748
|
-
if arguments[0][:data].nil? then
|
749
|
-
if arguments[0].keys.include?(:data) then
|
750
|
-
data=""
|
751
|
-
elsif arguments[0].keys.include?(:data_examples) and
|
752
|
-
arguments[0][:data_examples].kind_of?(Array) then
|
753
|
-
data=arguments[0][:data_examples][0] #the first example by default
|
754
|
-
else
|
755
|
-
data=""
|
756
|
-
end
|
757
|
-
|
758
|
-
else
|
759
|
-
data=arguments[0][:data]
|
760
|
-
end
|
761
|
-
if arguments[0].include?(:headers) then
|
762
|
-
headers_t.merge!(arguments[0][:headers])
|
763
|
-
end
|
764
|
-
|
765
|
-
if headers_t["Content-Type"].to_s()=="" and headers_t["content-type"].to_s()=="" and
|
766
|
-
headers_t[:"content-type"].to_s()=="" and headers_t[:"Content-Type"].to_s()=="" then
|
767
|
-
content_type_included=false
|
768
|
-
elsif headers_t["content-type"].to_s()!="" then
|
769
|
-
content_type_included=true
|
770
|
-
headers_t["Content-Type"]=headers_t["content-type"]
|
771
|
-
elsif headers_t[:"content-type"].to_s()!="" then
|
772
|
-
content_type_included=true
|
773
|
-
headers_t["Content-Type"]=headers_t[:"content-type"]
|
774
|
-
headers_t.delete(:"content-type")
|
775
|
-
elsif headers_t[:"Content-Type"].to_s()!="" then
|
776
|
-
content_type_included=true
|
777
|
-
headers_t["Content-Type"]=headers_t[:"Content-Type"]
|
778
|
-
headers_t.delete(:"Content-Type")
|
779
|
-
elsif headers_t["Content-Type"].to_s()!="" then
|
780
|
-
content_type_included=true
|
781
|
-
end
|
782
|
-
|
783
|
-
if !content_type_included and data.kind_of?(Hash)
|
784
|
-
headers_t['Content-Type'] = 'application/json'
|
785
|
-
content_type_included=true
|
786
|
-
end
|
787
|
-
|
788
|
-
if content_type_included and (!headers_t["Content-Type"][/text\/xml/].nil? or
|
789
|
-
!headers_t["Content-Type"]["application/soap+xml"].nil? or
|
790
|
-
!headers_t["Content-Type"][/application\/jxml/].nil?) then
|
791
|
-
if arguments[0].include?(:values) then
|
792
|
-
arguments[0][:values].each {|key, value|
|
793
|
-
data=NiceHttpUtils.set_value_xml_tag(key.to_s(), data, value.to_s(), true)
|
794
|
-
}
|
795
|
-
end
|
796
|
-
elsif content_type_included and !headers_t["Content-Type"][/application\/json/].nil? and data.to_s()!="" then
|
797
|
-
require 'json'
|
798
|
-
if data.kind_of?(String) then
|
799
|
-
if arguments[0].include?(:values) then
|
800
|
-
arguments[0][:values].each {|key, value|
|
801
|
-
data.gsub!(/(( *|^)"?#{key.to_s()}"? *: *")(.*)(" *, *$)/, '\1' + value+ '\4') # "key":"value", or key:"value",
|
802
|
-
data.gsub!(/(( *|^)"?#{key.to_s()}"? *: *")(.*)(" *$)/, '\1' + value+ '\4') # "key":"value" or key:"value"
|
803
|
-
data.gsub!(/(( *|^)"?#{key.to_s()}"? *: *[^"])([^"].*)([^"] *, *$)/, '\1' + value+ '\4') # "key":456, or key:456,
|
804
|
-
data.gsub!(/(( *|^)"?#{key.to_s()}"? *: *[^"])([^"].*)([^"] * *$)/, '\1' + value+ '\4') # "key":456 or key:456
|
805
|
-
}
|
806
|
-
end
|
807
|
-
elsif data.kind_of?(Hash) then
|
808
|
-
data_n=Hash.new()
|
809
|
-
data.each {|key, value|
|
810
|
-
data_n[key.to_s()]=value
|
811
|
-
}
|
812
|
-
if arguments[0].include?(:values) then
|
813
|
-
#req[:values][:loginName] or req[:values]["loginName"]
|
814
|
-
new_values_hash=Hash.new()
|
815
|
-
arguments[0][:values].each {|kv, vv|
|
816
|
-
if data_n.keys.include?(kv.to_s()) then
|
817
|
-
new_values_hash[kv.to_s()]=vv
|
818
|
-
end
|
819
|
-
}
|
820
|
-
data_n.merge!(new_values_hash)
|
821
|
-
end
|
822
|
-
data=data_n.to_json()
|
823
|
-
elsif data.kind_of?(Array) then
|
824
|
-
data_arr=Array.new()
|
825
|
-
data.each_with_index {|row, indx|
|
826
|
-
unless row.kind_of?(Hash) then
|
827
|
-
@logger.fatal("Wrong format on request application/json, be sure is a Hash, Array of Hashes or JSON string")
|
828
|
-
return :error, :error, :error
|
829
|
-
end
|
830
|
-
data_n=Hash.new()
|
831
|
-
row.each {|key, value|
|
832
|
-
data_n[key.to_s()]=value
|
833
|
-
}
|
834
|
-
if arguments[0].include?(:values) then
|
835
|
-
#req[:values][:loginName] or req[:values]["loginName"]
|
836
|
-
new_values_hash=Hash.new()
|
837
|
-
if arguments[0][:values].kind_of?(Hash) then #values[:mykey][3]
|
838
|
-
arguments[0][:values].each {|kv, vv|
|
839
|
-
if data_n.keys.include?(kv.to_s()) and !vv[indx].nil? then
|
840
|
-
new_values_hash[kv.to_s()]=vv[indx]
|
841
|
-
end
|
842
|
-
}
|
843
|
-
elsif arguments[0][:values].kind_of?(Array) then #values[5][:mykey]
|
844
|
-
if !arguments[0][:values][indx].nil? then
|
845
|
-
arguments[0][:values][indx].each {|kv, vv|
|
846
|
-
if data_n.keys.include?(kv.to_s()) then
|
847
|
-
new_values_hash[kv.to_s()]=vv
|
848
|
-
end
|
849
|
-
}
|
850
|
-
end
|
851
|
-
else
|
852
|
-
@logger.fatal("Wrong format on request application/json when supplying values, the data is an array of Hashes but the values supplied are not")
|
853
|
-
return :error, :error, :error
|
854
|
-
end
|
855
|
-
data_n.merge!(new_values_hash)
|
856
|
-
end
|
857
|
-
data_arr.push(data_n)
|
858
|
-
}
|
859
|
-
data=data_arr.to_json()
|
860
|
-
else
|
861
|
-
@logger.fatal("Wrong format on request application/json, be sure is a Hash, Array of Hashes or JSON string")
|
862
|
-
return :error, :error, :error
|
863
|
-
end
|
864
|
-
elsif content_type_included and arguments[0].include?(:values) then
|
865
|
-
if arguments[0][:values].kind_of?(Hash) and arguments[0][:values].keys.size>0 then
|
866
|
-
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" then
|
867
|
-
@logger.warn(":values key given without a valid content-type or data for request. No values modified on the request")
|
868
|
-
end
|
869
|
-
end
|
870
|
-
end
|
871
|
-
elsif arguments.size==1 and arguments[0].kind_of?(String) then
|
872
|
-
#path=arguments[0].to_s()
|
873
|
-
data=""
|
874
|
-
else
|
875
|
-
@logger.fatal("Invalid number of arguments or wrong arguments in #{method_s}")
|
876
|
-
return :error, :error, :error
|
877
|
-
end
|
878
|
-
if headers_t.keys.include?("Content-Type") and !headers_t["Content-Type"]["multipart/form-data"].nil? and headers_t["Content-Type"]!=["multipart/form-data"] then #only for the case raw multipart request
|
879
|
-
encoding="UTF-8"
|
880
|
-
data_s=""
|
881
|
-
else
|
882
|
-
encoding=data.to_s().scan(/encoding='(.*)'/i).join
|
883
|
-
if encoding.to_s()=="" then
|
884
|
-
encoding=data.to_s().scan(/charset='(.*)'/i).join
|
885
|
-
end
|
886
|
-
if encoding.to_s()=="" and headers_t.include?("Content-Type") then
|
887
|
-
encoding=headers_t["Content-Type"].scan(/charset='?(.*)'?/i).join
|
888
|
-
if encoding.to_s()=="" then
|
889
|
-
encoding=headers_t["Content-Type"].scan(/encoding='?(.*)'?/i).join
|
890
|
-
end
|
891
|
-
end
|
892
|
-
|
893
|
-
begin
|
894
|
-
data_s=JSON.pretty_generate(JSON.parse(data))
|
895
|
-
rescue
|
896
|
-
data_s=data
|
897
|
-
end
|
898
|
-
data_s=data_s.to_s().gsub("<", "<")
|
899
|
-
end
|
900
|
-
if headers_t.keys.include?("Accept-Encoding")
|
901
|
-
headers_t["Accept-Encoding"].gsub!("gzip","")#removed so the response is in plain text
|
902
|
-
end
|
903
|
-
|
904
|
-
headers_ts=""
|
905
|
-
headers_t.each {|key, val| headers_ts+=key.to_s + ":" + val.to_s() + ", "}
|
906
|
-
message="#{method_s} REQUEST: \npath= " + path.to_s() + "\n"
|
907
|
-
message+="headers= " + headers_ts.to_s() + "\n"
|
908
|
-
message+="data= " + data_s.to_s() + "\n"
|
909
|
-
message=@message_server+"\n"+message
|
910
|
-
if path.to_s().scan(/^https?:\/\//).size>0 and path.to_s().scan(/^https?:\/\/#{@host}/).size==0 then
|
911
|
-
# the path is for another server than the current
|
912
|
-
else
|
913
|
-
NiceHttp.last_request=message
|
914
|
-
@logger.info(message)
|
915
|
-
end
|
916
|
-
|
917
|
-
if data.to_s()!="" and encoding.to_s().upcase!="UTF-8" and encoding!="" then
|
918
|
-
data=data.to_s().encode(encoding, "UTF-8")
|
919
|
-
end
|
920
|
-
return path, data, headers_t
|
921
|
-
rescue Exception => stack
|
922
|
-
@logger.fatal(stack)
|
923
|
-
@logger.fatal("manage_request Error on method #{method_s} . path:#{path.to_s()}. data:#{data.to_s()}. headers:#{headers_t.to_s()}")
|
924
|
-
return :error
|
925
|
-
end
|
926
|
-
end
|
927
|
-
|
928
|
-
######################################################
|
929
|
-
# private method to manage Response
|
930
|
-
# input:
|
931
|
-
# resp
|
932
|
-
# data
|
933
|
-
# output:
|
934
|
-
# @response updated
|
935
|
-
######################################################
|
936
|
-
def manage_response(resp, data)
|
937
|
-
require 'json'
|
938
|
-
begin
|
939
|
-
if @start_time.kind_of?(Time)
|
940
|
-
@response[:time_elapsed_total]=Time.now-@start_time
|
941
|
-
@start_time = nil
|
942
|
-
else
|
943
|
-
@response[:time_elapsed_total]=nil
|
944
|
-
end
|
945
|
-
if @start_time_net.kind_of?(Time)
|
946
|
-
@response[:time_elapsed]=Time.now-@start_time_net
|
947
|
-
@start_time_net = nil
|
948
|
-
else
|
949
|
-
@response[:time_elapsed]=nil
|
950
|
-
end
|
951
|
-
begin
|
952
|
-
# this is to be able to access all keys as symbols
|
953
|
-
new_resp=Hash.new()
|
954
|
-
resp.each {|key, value|
|
955
|
-
if key.kind_of?(String) then
|
956
|
-
new_resp[key.to_sym]=value
|
957
|
-
end
|
958
|
-
}
|
959
|
-
new_resp.each {|key, value|
|
960
|
-
resp[key]=value
|
961
|
-
}
|
962
|
-
rescue
|
963
|
-
end
|
964
|
-
#for mock_responses to be able to add outside of the header like content-type for example
|
965
|
-
if resp.kind_of?(Hash) and !resp.has_key?(:header) then
|
966
|
-
resp[:header]={}
|
967
|
-
end
|
968
|
-
if resp.kind_of?(Hash)
|
969
|
-
resp.each {|k, v|
|
970
|
-
if k!=:code and k!=:message and k!=:data and k!=:'set-cookie' and k!=:header
|
971
|
-
resp[:header][k]=v
|
972
|
-
end
|
973
|
-
}
|
974
|
-
resp[:header].each {|k, v|
|
975
|
-
resp.delete(k) if resp.has_key?(k)
|
976
|
-
}
|
977
|
-
end
|
978
|
-
|
979
|
-
method_s=caller[0].to_s().scan(/:in `(.*)'/).join
|
980
|
-
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") then
|
981
|
-
data=Zlib::Inflate.inflate(data)
|
982
|
-
end
|
983
|
-
encoding_response=""
|
984
|
-
if resp.header.kind_of?(Hash) and (resp.header["content-type"].to_s()!="" or resp.header[:"content-type"].to_s()!="") then
|
985
|
-
encoding_response=resp.header["content-type"].scan(/;charset=(.*)/i).join if resp.header.has_key?("content-type")
|
986
|
-
encoding_response=resp.header[:"content-type"].scan(/;charset=(.*)/i).join if resp.header.has_key?(:"content-type")
|
987
|
-
end
|
988
|
-
if encoding_response.to_s()=="" then
|
989
|
-
encoding_response="UTF-8"
|
990
|
-
end
|
991
|
-
|
992
|
-
if encoding_response.to_s()!="" and encoding_response.to_s().upcase!="UTF-8" then
|
993
|
-
data.encode!("UTF-8", encoding_response.to_s())
|
994
|
-
end
|
995
|
-
if encoding_response!="" and encoding_response.to_s().upcase!="UTF-8" then
|
996
|
-
@response[:message]=resp.message.to_s().encode("UTF-8", encoding_response.to_s())
|
997
|
-
#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...)
|
998
|
-
resp.each {|key, val| @response[key]=val.to_s().encode("UTF-8", encoding_response.to_s())}
|
999
|
-
else
|
1000
|
-
@response[:message]=resp.message
|
1001
|
-
resp.each {|key, val| @response[key]=val}
|
1002
|
-
end
|
1003
|
-
if !defined?(Net::HTTP::Post::Multipart) or (defined?(Net::HTTP::Post::Multipart) and !data.kind_of?(Net::HTTP::Post::Multipart))
|
1004
|
-
@response[:data]=data
|
1005
|
-
else
|
1006
|
-
@response[:data]=""
|
1007
|
-
end
|
1008
|
-
|
1009
|
-
@response[:code]=resp.code
|
1010
|
-
|
1011
|
-
unless @response.nil? then
|
1012
|
-
message="\nRESPONSE: \n" + @response[:code].to_s()+ ":" + @response[:message].to_s()
|
1013
|
-
if @debug then
|
1014
|
-
NiceHttp.last_response=message
|
1015
|
-
@response.each {|key, value|
|
1016
|
-
if value.to_s()!="" then
|
1017
|
-
value_orig=value
|
1018
|
-
if key.kind_of?(Symbol) then
|
1019
|
-
if key==:code or key==:data or key==:header or key==:message then
|
1020
|
-
if key==:data then
|
1021
|
-
begin
|
1022
|
-
JSON.parse(value_orig)
|
1023
|
-
data_s=JSON.pretty_generate(JSON.parse(value_orig))
|
1024
|
-
rescue
|
1025
|
-
data_s=value_orig
|
1026
|
-
end
|
1027
|
-
NiceHttp.last_response+="\nresponse." + key.to_s() + " = '" + data_s.gsub("<", "<") + "'\n"
|
1028
|
-
if value_orig != value then
|
1029
|
-
message+="\nresponse." + key.to_s() + " = '" + value.gsub("<", "<") + "'\n"
|
1030
|
-
else
|
1031
|
-
message+="\nresponse." + key.to_s() + " = '" + data_s.gsub("<", "<") + "'\n"
|
1032
|
-
end
|
1033
|
-
else
|
1034
|
-
NiceHttp.last_response+="\nresponse." + key.to_s() + " = '" + value.to_s().gsub("<", "<") + "'"
|
1035
|
-
message+="\nresponse." + key.to_s() + " = '" + value.to_s().gsub("<", "<") + "'"
|
1036
|
-
end
|
1037
|
-
else
|
1038
|
-
NiceHttp.last_response+="\nresponse[:" + key.to_s() + "] = '" + value.to_s().gsub("<", "<") + "'"
|
1039
|
-
message+="\nresponse[:" + key.to_s() + "] = '" + value.to_s().gsub("<", "<") + "'"
|
1040
|
-
end
|
1041
|
-
elsif !@response.include?(key.to_sym)
|
1042
|
-
NiceHttp.last_response+="\nresponse['" + key.to_s() + "'] = '" + value.to_s().gsub("<", "<") + "'"
|
1043
|
-
message+="\nresponse['" + key.to_s() + "'] = '" + value.to_s().gsub("<", "<") + "'"
|
1044
|
-
end
|
1045
|
-
end
|
1046
|
-
}
|
1047
|
-
|
1048
|
-
end
|
1049
|
-
@logger.info message
|
1050
|
-
if @response.kind_of?(Hash) then
|
1051
|
-
if @response.keys.include?(:requestid) then
|
1052
|
-
@headers["requestId"]=@response[:requestid]
|
1053
|
-
NiceHttp.request_id=@response[:requestid]
|
1054
|
-
@logger.info "requestId was found on the response header and it has been added to the headers for the next request"
|
1055
|
-
end
|
1056
|
-
end
|
1057
|
-
end
|
1058
|
-
|
1059
|
-
if resp[:'set-cookie'].to_s()!="" then
|
1060
|
-
if resp.kind_of?(Hash) then #mock_response
|
1061
|
-
cookies_to_set=resp[:'set-cookie'].to_s().split(", ")
|
1062
|
-
else #Net::Http
|
1063
|
-
cookies_to_set=resp.get_fields('set-cookie')
|
1064
|
-
end
|
1065
|
-
cookies_to_set.each {|cookie|
|
1066
|
-
cookie_pair=cookie.split('; ')[0].split("=")
|
1067
|
-
cookie_path=cookie.scan(/; path=([^;]+)/i).join
|
1068
|
-
@cookies[cookie_path]=Hash.new() unless @cookies.keys.include?(cookie_path)
|
1069
|
-
@cookies[cookie_path][cookie_pair[0]]=cookie_pair[1]
|
1070
|
-
}
|
1071
|
-
|
1072
|
-
@logger.info "set-cookie added to Cookie header as required"
|
1073
|
-
|
1074
|
-
if @headers.has_key?("X-CSRFToken") then
|
1075
|
-
csrftoken=resp[:"set-cookie"].to_s().scan(/csrftoken=([\da-z]+);/).join
|
1076
|
-
if csrftoken.to_s()!="" then
|
1077
|
-
@headers["X-CSRFToken"]=csrftoken
|
1078
|
-
@logger.info "X-CSRFToken exists on headers and has been overwritten"
|
1079
|
-
end
|
1080
|
-
else
|
1081
|
-
csrftoken=resp[:"set-cookie"].to_s().scan(/csrftoken=([\da-z]+);/).join
|
1082
|
-
if csrftoken.to_s()!="" then
|
1083
|
-
@headers["X-CSRFToken"]=csrftoken
|
1084
|
-
@logger.info "X-CSRFToken added to header as required"
|
1085
|
-
end
|
1086
|
-
|
1087
|
-
end
|
1088
|
-
end
|
1089
|
-
|
1090
|
-
rescue Exception => stack
|
1091
|
-
@logger.fatal stack
|
1092
|
-
@logger.fatal "manage_response Error on method #{method_s} "
|
1093
|
-
end
|
1094
|
-
end
|
1095
|
-
|
1096
|
-
private :manage_request, :manage_response
|
1097
|
-
end
|
1098
|
-
|
1
|
+
require 'logger'
|
2
|
+
require 'nice_hash'
|
3
|
+
require 'nice_http_utils'
|
4
|
+
|
5
|
+
class NiceHttp
|
6
|
+
class << self
|
7
|
+
attr_accessor :host, :port, :ssl, :headers, :debug, :log, :proxy_host, :proxy_port,
|
8
|
+
:last_request, :last_response, :request_id, :use_mocks, :connections,
|
9
|
+
:active, :auto_redirect
|
10
|
+
end
|
11
|
+
@host = nil
|
12
|
+
@port = 80
|
13
|
+
@ssl = false
|
14
|
+
@headers = {}
|
15
|
+
@debug = false
|
16
|
+
@log = :fix_file
|
17
|
+
@proxy_host = nil
|
18
|
+
@proxy_port = nil
|
19
|
+
@last_request=nil
|
20
|
+
@last_response=nil
|
21
|
+
@request_id=""
|
22
|
+
@use_mocks = false
|
23
|
+
@connections = []
|
24
|
+
@active=0
|
25
|
+
@auto_redirect = true
|
26
|
+
|
27
|
+
attr_reader :host, :port, :ssl, :debug, :log, :proxy_host, :proxy_port, :response, :num_redirects
|
28
|
+
attr_accessor :headers, :cookies, :use_mocks, :auto_redirect, :logger
|
29
|
+
|
30
|
+
def self.defaults=(par = {})
|
31
|
+
@host = par[:host] if par.key?(:host)
|
32
|
+
@port = par[:port] if par.key?(:port)
|
33
|
+
@ssl = par[:ssl] if par.key?(:ssl)
|
34
|
+
@headers = par[:headers] if par.key?(:headers)
|
35
|
+
@debug = par[:debug] if par.key?(:debug)
|
36
|
+
@log = par[:log] if par.key?(:log)
|
37
|
+
@proxy_host = par[:proxy_host] if par.key?(:proxy_host)
|
38
|
+
@proxy_port = par[:proxy_port] if par.key?(:proxy_port)
|
39
|
+
@proxy_port = par[:use_mocks] if par.key?(:use_mocks)
|
40
|
+
@auto_redirect = par[:auto_redirect] if par.key?(:auto_redirect)
|
41
|
+
end
|
42
|
+
|
43
|
+
######################################################
|
44
|
+
# input:
|
45
|
+
# no parameters:
|
46
|
+
# By default will access how is setup on defaults
|
47
|
+
# one parameter:
|
48
|
+
# String
|
49
|
+
# "https://www.example.com"
|
50
|
+
# "example.com:8999"
|
51
|
+
# "localhost:8322"
|
52
|
+
# Hash containing these possible keys
|
53
|
+
# host -- example.com. (default blank screen)
|
54
|
+
# port -- port for the connection. 80 (default)
|
55
|
+
# ssl -- true, false (default)
|
56
|
+
# headers -- hash with the header key:values
|
57
|
+
# debug -- true, false (default)
|
58
|
+
# log -- :no, :screen, :file, :fix_file (default).
|
59
|
+
# A string with a path can be supplied.
|
60
|
+
# If :fix_file: nice_http.log
|
61
|
+
# In case :file it will be generated a log file with name: nice_http_YY-mm-dd-HHMMSS.log
|
62
|
+
# proxy_host
|
63
|
+
# proxy_port
|
64
|
+
######################################################
|
65
|
+
def initialize(args = {})
|
66
|
+
require 'net/http'
|
67
|
+
require 'net/https'
|
68
|
+
@host = NiceHttp.host
|
69
|
+
@port = NiceHttp.port
|
70
|
+
@ssl = NiceHttp.ssl
|
71
|
+
@headers = NiceHttp.headers
|
72
|
+
@debug = NiceHttp.debug
|
73
|
+
@log = NiceHttp.log
|
74
|
+
@proxy_host = NiceHttp.proxy_host
|
75
|
+
@proxy_port = NiceHttp.proxy_port
|
76
|
+
@use_mocks = NiceHttp.use_mocks
|
77
|
+
@auto_redirect=false #set it up at the end of initialize
|
78
|
+
auto_redirect = NiceHttp.auto_redirect
|
79
|
+
@num_redirects=0
|
80
|
+
|
81
|
+
#todo: set only the cookies for the current domain
|
82
|
+
#key: path, value: hash with key is the name of the cookie and value the value
|
83
|
+
# we set the default value for non existing keys to empty Hash {} so in case of merge there is no problem
|
84
|
+
@cookies=Hash.new {|h, k| h[k] = {}}
|
85
|
+
|
86
|
+
begin
|
87
|
+
if args.is_a?(String)
|
88
|
+
uri = URI.parse(args)
|
89
|
+
@host = uri.host unless uri.host.nil?
|
90
|
+
@port = uri.port unless uri.port.nil?
|
91
|
+
@ssl = true if !uri.scheme.nil? && (uri.scheme == 'https')
|
92
|
+
elsif args.is_a?(Hash) && !args.keys.empty?
|
93
|
+
@host = args[:host] if args.keys.include?(:host)
|
94
|
+
@port = args[:port] if args.keys.include?(:port)
|
95
|
+
@ssl = args[:ssl] if args.keys.include?(:ssl)
|
96
|
+
@headers = args[:headers] if args.keys.include?(:headers)
|
97
|
+
@debug = args[:debug] if args.keys.include?(:debug)
|
98
|
+
@log = args[:log] if args.keys.include?(:log)
|
99
|
+
@proxy_host = args[:proxy_host] if args.keys.include?(:proxy_host)
|
100
|
+
@proxy_port = args[:proxy_port] if args.keys.include?(:proxy_port)
|
101
|
+
@use_mocks = args[:use_mocks] if args.keys.include?(:use_mocks)
|
102
|
+
@auto_redirect = args[:auto_redirect] if args.keys.include?(:auto_redirect)
|
103
|
+
end
|
104
|
+
|
105
|
+
if @host.to_s!="" and (@host.include?("http:") or @host.include?("https:"))
|
106
|
+
uri = URI.parse(@host)
|
107
|
+
@host = uri.host unless uri.host.nil?
|
108
|
+
@port = uri.port unless uri.port.nil?
|
109
|
+
@ssl = true if !uri.scheme.nil? && (uri.scheme == 'https')
|
110
|
+
end
|
111
|
+
|
112
|
+
if @host.nil? or @host.to_s=="" or @port.nil? or @port.to_s==""
|
113
|
+
message = "It was not possible to create the http connection!!!\n"
|
114
|
+
message += "Wrong host or port, remember to supply http:// or https:// in case you specify an url to create the http connection, for example:\n"
|
115
|
+
message += "http = NiceHttp.new('http://example.com')"
|
116
|
+
raise message
|
117
|
+
end
|
118
|
+
|
119
|
+
if !@proxy_host.nil? && !@proxy_port.nil?
|
120
|
+
@http = Net::HTTP::Proxy(@proxy_host, @proxy_port).new(@host, @port)
|
121
|
+
@http.use_ssl = @ssl
|
122
|
+
@http.set_debug_output $stderr if @debug
|
123
|
+
@http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
124
|
+
@http.start
|
125
|
+
else
|
126
|
+
@http = Net::HTTP.new(@host, @port)
|
127
|
+
@http.use_ssl = @ssl
|
128
|
+
@http.set_debug_output $stderr if @debug
|
129
|
+
@http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
130
|
+
@http.start
|
131
|
+
end
|
132
|
+
|
133
|
+
if @log.kind_of?(String)
|
134
|
+
@logger = Logger.new File.new(@log, "w")
|
135
|
+
elsif @log==:fix_file
|
136
|
+
@logger = Logger.new File.new("nice_http.log", "w")
|
137
|
+
elsif @log==:file
|
138
|
+
@logger = Logger.new File.new("nice_http_#{Time.now.strftime('%Y-%m-%d-%H%M%S')}.log", 'w')
|
139
|
+
elsif @log==:screen
|
140
|
+
@logger = Logger.new STDOUT
|
141
|
+
elsif @log==:no
|
142
|
+
@logger = Logger.new nil
|
143
|
+
end
|
144
|
+
@logger.level = Logger::INFO
|
145
|
+
|
146
|
+
@message_server="(#{self.object_id}):"
|
147
|
+
|
148
|
+
log_message="(#{self.object_id}): Http connection created. host:#{@host}, port:#{@port}, ssl:#{@ssl}, mode:#{@mode}, proxy_host: #{@proxy_host.to_s()}, proxy_port: #{@proxy_port.to_s()} "
|
149
|
+
|
150
|
+
@logger.info(log_message)
|
151
|
+
@message_server+=" Http connection: "
|
152
|
+
if @ssl then
|
153
|
+
@message_server+="https://"
|
154
|
+
else
|
155
|
+
@message_server+="http://"
|
156
|
+
end
|
157
|
+
@message_server+="#{@host}:#{@port}"
|
158
|
+
if @proxy_host.to_s!="" then
|
159
|
+
@message_server+=" proxy:#{@proxy_host}:#{@proxy_port}"
|
160
|
+
end
|
161
|
+
@auto_redirect = auto_redirect
|
162
|
+
rescue Exception => stack
|
163
|
+
if @logger.nil?
|
164
|
+
puts stack
|
165
|
+
@logger = Logger.new nil
|
166
|
+
else
|
167
|
+
@logger.fatal stack
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
NiceHttp.active+=1
|
172
|
+
NiceHttp.connections.push(self)
|
173
|
+
|
174
|
+
end
|
175
|
+
|
176
|
+
######################################################
|
177
|
+
# Get data from path
|
178
|
+
# input:
|
179
|
+
# 1 argument
|
180
|
+
# Hash containing at least key :path
|
181
|
+
# 1 argument
|
182
|
+
# path (string)
|
183
|
+
# output:
|
184
|
+
# response -> Hash including at least the symbol keys:
|
185
|
+
# :data = the response data body
|
186
|
+
# :message = plain text response
|
187
|
+
# :code = code response (200=ok,500=wrong...)
|
188
|
+
# *All keys in response are lowercase
|
189
|
+
# data, message and code can also be accessed as attributes like .message .code .data, for example:
|
190
|
+
# resp=@http.get(Requests::Customer.get_profile)
|
191
|
+
# assert resp.code==200
|
192
|
+
######################################################
|
193
|
+
def get(arg)
|
194
|
+
begin
|
195
|
+
path, data, headers_t=manage_request(arg)
|
196
|
+
@start_time = Time.now if @start_time.nil?
|
197
|
+
if @use_mocks and arg.kind_of?(Hash) and arg.keys.include?(:mock_response) then
|
198
|
+
data=""
|
199
|
+
if arg[:mock_response].keys.include?(:data) then
|
200
|
+
data=arg[:mock_response][:data]
|
201
|
+
if data.kind_of?(Hash) #to json
|
202
|
+
begin
|
203
|
+
require 'json'
|
204
|
+
data=data.to_json
|
205
|
+
rescue
|
206
|
+
@logger.fatal "There was a problem converting to json: #{data}"
|
207
|
+
end
|
208
|
+
end
|
209
|
+
end
|
210
|
+
@logger.warn "Pay attention!!! This is a mock response:"
|
211
|
+
@start_time_net = Time.now if @start_time_net.nil?
|
212
|
+
manage_response(arg[:mock_response], data.to_s)
|
213
|
+
return @response
|
214
|
+
end
|
215
|
+
begin
|
216
|
+
if path.start_with?("http:") or path.start_with?("https:") then #server included on path problably because of a redirection to a different server
|
217
|
+
require 'uri'
|
218
|
+
uri = URI.parse(path)
|
219
|
+
ssl=false
|
220
|
+
ssl=true if path.include?("https:")
|
221
|
+
|
222
|
+
|
223
|
+
server="http://"
|
224
|
+
server="https://" if path.include?("https:")
|
225
|
+
if uri.port!=443 then
|
226
|
+
server+="#{uri.host}:#{uri.port}"
|
227
|
+
else
|
228
|
+
server+="#{uri.host}"
|
229
|
+
end
|
230
|
+
|
231
|
+
http_redir=nil
|
232
|
+
NiceHttp.connections.each {|conn|
|
233
|
+
if conn.host == uri.host and conn.port==uri.port then
|
234
|
+
http_redir=conn
|
235
|
+
break
|
236
|
+
end
|
237
|
+
}
|
238
|
+
|
239
|
+
if !http_redir.nil?
|
240
|
+
path, data, headers_t=manage_request(arg)
|
241
|
+
http_redir.cookies.merge!(@cookies)
|
242
|
+
http_redir.headers.merge!(headers_t)
|
243
|
+
resp=http_redir.get(path.gsub(server, "")) #todo: remove only the server at the begining in case in query is the server it will be replaced when it should not be
|
244
|
+
@response=http_redir.response
|
245
|
+
else
|
246
|
+
@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."
|
247
|
+
end
|
248
|
+
|
249
|
+
else
|
250
|
+
@start_time_net = Time.now if @start_time_net.nil?
|
251
|
+
resp=@http.get(path, headers_t)
|
252
|
+
data=resp.body
|
253
|
+
manage_response(resp, data)
|
254
|
+
end
|
255
|
+
rescue Exception => stack
|
256
|
+
@logger.warn stack
|
257
|
+
@logger.warn "The connection seems to be closed in the host machine. Trying to reconnect"
|
258
|
+
@http.finish()
|
259
|
+
@http.start()
|
260
|
+
@start_time_net = Time.now if @start_time_net.nil?
|
261
|
+
resp=@http.get(path)
|
262
|
+
data=resp.body
|
263
|
+
manage_response(resp, data)
|
264
|
+
end
|
265
|
+
if @auto_redirect and @response[:code].to_i>=300 and @response[:code].to_i<400 and @response.include?(:location) then
|
266
|
+
if @num_redirects<=30 then
|
267
|
+
@num_redirects+=1
|
268
|
+
current_server="http"
|
269
|
+
current_server+="s" if @ssl==true
|
270
|
+
current_server+="://#{@host}"
|
271
|
+
location=@response[:location].gsub(current_server, "")
|
272
|
+
@logger.info "(#{@num_redirects}) Redirecting NiceHttp to #{location}"
|
273
|
+
get(location)
|
274
|
+
else
|
275
|
+
@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"
|
276
|
+
@num_redirects=0
|
277
|
+
end
|
278
|
+
else
|
279
|
+
@num_redirects=0
|
280
|
+
end
|
281
|
+
return @response
|
282
|
+
rescue Exception => stack
|
283
|
+
@logger.fatal stack
|
284
|
+
return :error
|
285
|
+
end
|
286
|
+
end
|
287
|
+
|
288
|
+
######################################################
|
289
|
+
# Post data to path
|
290
|
+
# input:
|
291
|
+
# 1 argument
|
292
|
+
# Hash containing at least keys :data, :path
|
293
|
+
# 3 arguments
|
294
|
+
# path (string)
|
295
|
+
# data (json data for example)
|
296
|
+
# additional_headers (Hash key=>value)
|
297
|
+
# output:
|
298
|
+
# response -> Hash including at least the symbol keys:
|
299
|
+
# :data = the response data body
|
300
|
+
# :message = plain text response
|
301
|
+
# :code = code response (200=ok,500=wrong...)
|
302
|
+
# *All keys in response are lowercase
|
303
|
+
# data, message and code can also be accessed as attributes like .message .code .data, for example:
|
304
|
+
# resp=@http.post(Requests::Customer.update_customer)
|
305
|
+
# assert resp.code==201
|
306
|
+
######################################################
|
307
|
+
def post(*arguments)
|
308
|
+
begin
|
309
|
+
path, data, headers_t=manage_request(*arguments)
|
310
|
+
@start_time = Time.now if @start_time.nil?
|
311
|
+
if arguments.size>0 and arguments[0].kind_of?(Hash) then
|
312
|
+
arg=arguments[0]
|
313
|
+
if @use_mocks and arg.kind_of?(Hash) and arg.keys.include?(:mock_response) then
|
314
|
+
data=""
|
315
|
+
if arg[:mock_response].keys.include?(:data) then
|
316
|
+
data=arg[:mock_response][:data]
|
317
|
+
if data.kind_of?(Hash) #to json
|
318
|
+
begin
|
319
|
+
require 'json'
|
320
|
+
data=data.to_json
|
321
|
+
rescue
|
322
|
+
@logger.fatal "There was a problem converting to json: #{data}"
|
323
|
+
end
|
324
|
+
end
|
325
|
+
end
|
326
|
+
@logger.warn "Pay attention!!! This is a mock response:"
|
327
|
+
@start_time_net = Time.now if @start_time_net.nil?
|
328
|
+
manage_response(arg[:mock_response], data.to_s)
|
329
|
+
return @response
|
330
|
+
end
|
331
|
+
end
|
332
|
+
|
333
|
+
begin
|
334
|
+
@start_time_net = Time.now if @start_time_net.nil?
|
335
|
+
if headers_t["Content-Type"] == "multipart/form-data" then
|
336
|
+
require 'net/http/post/multipart'
|
337
|
+
headers_t.each {|key, value|
|
338
|
+
arguments[0][:data].add_field(key, value) #add to Headers
|
339
|
+
}
|
340
|
+
resp=@http.request(arguments[0][:data])
|
341
|
+
else
|
342
|
+
resp=@http.post(path, data, headers_t)
|
343
|
+
data=resp.body
|
344
|
+
end
|
345
|
+
rescue Exception => stack
|
346
|
+
@logger.warn stack
|
347
|
+
@logger.warn "The connection seems to be closed in the host machine. Trying to reconnect"
|
348
|
+
@http.finish()
|
349
|
+
@http.start()
|
350
|
+
@start_time_net = Time.now if @start_time_net.nil?
|
351
|
+
resp, data=@http.post(path, data, headers_t)
|
352
|
+
end
|
353
|
+
manage_response(resp, data)
|
354
|
+
if @auto_redirect and @response[:code].to_i>=300 and @response[:code].to_i<400 and @response.include?(:location) then
|
355
|
+
if @num_redirects<=30 then
|
356
|
+
@num_redirects+=1
|
357
|
+
current_server="http"
|
358
|
+
current_server+="s" if @ssl==true
|
359
|
+
current_server+="://#{@host}"
|
360
|
+
location=@response[:location].gsub(current_server, "")
|
361
|
+
@logger.info "(#{@num_redirects}) Redirecting NiceHttp to #{location}"
|
362
|
+
get(location)
|
363
|
+
else
|
364
|
+
@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"
|
365
|
+
@num_redirects=0
|
366
|
+
end
|
367
|
+
else
|
368
|
+
@num_redirects=0
|
369
|
+
end
|
370
|
+
return @response
|
371
|
+
rescue Exception => stack
|
372
|
+
@logger.warn stack
|
373
|
+
return :error
|
374
|
+
end
|
375
|
+
|
376
|
+
end
|
377
|
+
|
378
|
+
|
379
|
+
######################################################
|
380
|
+
# Put data to path
|
381
|
+
# input:
|
382
|
+
# 1 argument
|
383
|
+
# Hash containing at least keys :data, :path
|
384
|
+
# 3 arguments
|
385
|
+
# path (string)
|
386
|
+
# data (json data for example)
|
387
|
+
# additional_headers (Hash key=>value)
|
388
|
+
# output:
|
389
|
+
# response -> Hash including at least the symbol keys:
|
390
|
+
# :data = the response data body
|
391
|
+
# :message = plain text response
|
392
|
+
# :code = code response (200=ok,500=wrong...)
|
393
|
+
# *All keys in response are lowercase
|
394
|
+
# data, message and code can also be accessed as attributes like .message .code .data, for example:
|
395
|
+
# resp=@http.put(Requests::Customer.remove_phone)
|
396
|
+
# assert resp.code==200
|
397
|
+
######################################################
|
398
|
+
def put(*arguments)
|
399
|
+
begin
|
400
|
+
path, data, headers_t=manage_request(*arguments)
|
401
|
+
@start_time = Time.now if @start_time.nil?
|
402
|
+
if arguments.size>0 and arguments[0].kind_of?(Hash) then
|
403
|
+
arg=arguments[0]
|
404
|
+
if @use_mocks and arg.kind_of?(Hash) and arg.keys.include?(:mock_response) then
|
405
|
+
data=""
|
406
|
+
if arg[:mock_response].keys.include?(:data) then
|
407
|
+
data=arg[:mock_response][:data]
|
408
|
+
if data.kind_of?(Hash) #to json
|
409
|
+
begin
|
410
|
+
require 'json'
|
411
|
+
data=data.to_json
|
412
|
+
rescue
|
413
|
+
@logger.fatal "There was a problem converting to json: #{data}"
|
414
|
+
end
|
415
|
+
end
|
416
|
+
end
|
417
|
+
@logger.warn "Pay attention!!! This is a mock response:"
|
418
|
+
@start_time_net = Time.now if @start_time_net.nil?
|
419
|
+
manage_response(arg[:mock_response], data.to_s)
|
420
|
+
return @response
|
421
|
+
end
|
422
|
+
end
|
423
|
+
|
424
|
+
begin
|
425
|
+
@start_time_net = Time.now if @start_time_net.nil?
|
426
|
+
resp=@http.send_request("PUT", path, data, headers_t)
|
427
|
+
data=resp.body
|
428
|
+
rescue Exception => stack
|
429
|
+
@logger.warn stack
|
430
|
+
@logger.warn "The connection seems to be closed in the host machine. Trying to reconnect"
|
431
|
+
@http.finish()
|
432
|
+
@http.start()
|
433
|
+
@start_time_net = Time.now if @start_time_net.nil?
|
434
|
+
resp, data=@http.send_request("PUT", path, data, headers_t)
|
435
|
+
end
|
436
|
+
manage_response(resp, data)
|
437
|
+
|
438
|
+
return @response
|
439
|
+
rescue Exception => stack
|
440
|
+
@logger.fatal stack, self
|
441
|
+
return :error
|
442
|
+
end
|
443
|
+
|
444
|
+
end
|
445
|
+
|
446
|
+
|
447
|
+
######################################################
|
448
|
+
# Patch data to path
|
449
|
+
# input:
|
450
|
+
# 1 argument
|
451
|
+
# Hash containing at least keys :data, :path
|
452
|
+
# 3 arguments
|
453
|
+
# path (string)
|
454
|
+
# data (json data for example)
|
455
|
+
# additional_headers (Hash key=>value)
|
456
|
+
# output:
|
457
|
+
# response -> Hash including at least the symbol keys:
|
458
|
+
# :data = the response data body
|
459
|
+
# :message = plain text response
|
460
|
+
# :code = code response (200=ok,500=wrong...)
|
461
|
+
# *All keys in response are lowercase
|
462
|
+
# data, message and code can also be accessed as attributes like .message .code .data, for example:
|
463
|
+
# resp=@http.patch(Requests::Customer.unrelease_account)
|
464
|
+
# assert resp.code==200
|
465
|
+
######################################################
|
466
|
+
def patch(*arguments)
|
467
|
+
begin
|
468
|
+
path, data, headers_t=manage_request(*arguments)
|
469
|
+
@start_time = Time.now if @start_time.nil?
|
470
|
+
if arguments.size>0 and arguments[0].kind_of?(Hash) then
|
471
|
+
arg=arguments[0]
|
472
|
+
if @use_mocks and arg.kind_of?(Hash) and arg.keys.include?(:mock_response) then
|
473
|
+
data=""
|
474
|
+
if arg[:mock_response].keys.include?(:data) then
|
475
|
+
data=arg[:mock_response][:data]
|
476
|
+
if data.kind_of?(Hash) #to json
|
477
|
+
begin
|
478
|
+
require 'json'
|
479
|
+
data=data.to_json
|
480
|
+
rescue
|
481
|
+
@logger.fatal "There was a problem converting to json: #{data}"
|
482
|
+
end
|
483
|
+
end
|
484
|
+
end
|
485
|
+
@logger.warn "Pay attention!!! This is a mock response:"
|
486
|
+
@start_time_net = Time.now if @start_time_net.nil?
|
487
|
+
manage_response(arg[:mock_response], data.to_s)
|
488
|
+
return @response
|
489
|
+
end
|
490
|
+
end
|
491
|
+
|
492
|
+
begin
|
493
|
+
@start_time_net = Time.now if @start_time_net.nil?
|
494
|
+
resp=@http.patch(path, data, headers_t)
|
495
|
+
data=resp.body
|
496
|
+
rescue Exception => stack
|
497
|
+
@logger.warn stack
|
498
|
+
@logger.warn "The connection seems to be closed in the host machine. Trying to reconnect"
|
499
|
+
@http.finish()
|
500
|
+
@http.start()
|
501
|
+
@start_time_net = Time.now if @start_time_net.nil?
|
502
|
+
resp, data=@http.patch(path, data, headers_t)
|
503
|
+
end
|
504
|
+
manage_response(resp, data)
|
505
|
+
if @auto_redirect and @response[:code].to_i>=300 and @response[:code].to_i<400 and @response.include?(:location) then
|
506
|
+
if @num_redirects<=30 then
|
507
|
+
@num_redirects+=1
|
508
|
+
current_server="http"
|
509
|
+
current_server+="s" if @ssl==true
|
510
|
+
current_server+="://#{@host}"
|
511
|
+
location=@response[:location].gsub(current_server, "")
|
512
|
+
@logger.info "(#{@num_redirects}) Redirecting NiceHttp to #{location}"
|
513
|
+
get(location)
|
514
|
+
else
|
515
|
+
@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"
|
516
|
+
@num_redirects=0
|
517
|
+
end
|
518
|
+
else
|
519
|
+
@num_redirects=0
|
520
|
+
end
|
521
|
+
return @response
|
522
|
+
rescue Exception => stack
|
523
|
+
@logger.fatal stack
|
524
|
+
return :error
|
525
|
+
end
|
526
|
+
|
527
|
+
end
|
528
|
+
|
529
|
+
|
530
|
+
######################################################
|
531
|
+
# Delete an existing resource
|
532
|
+
# input:
|
533
|
+
# 1 argument
|
534
|
+
# Hash containing at least key :path
|
535
|
+
# 1 argument
|
536
|
+
# String giving the path
|
537
|
+
# output:
|
538
|
+
# response -> Hash including at least the symbol keys:
|
539
|
+
# :data = the response data body
|
540
|
+
# :message = plain text response
|
541
|
+
# :code = code response (200=ok,500=wrong...)
|
542
|
+
# *All keys in response are lowercase
|
543
|
+
# data, message and code can also be accessed as attributes like .message .code .data, for example:
|
544
|
+
# resp=@http.delete(Requests::Customer.remove_session)
|
545
|
+
# assert resp.code==204
|
546
|
+
######################################################
|
547
|
+
def delete(argument)
|
548
|
+
begin
|
549
|
+
if argument.kind_of?(String) then
|
550
|
+
argument={:path => argument}
|
551
|
+
end
|
552
|
+
path, data, headers_t=manage_request(argument)
|
553
|
+
@start_time = Time.now if @start_time.nil?
|
554
|
+
if argument.kind_of?(Hash) then
|
555
|
+
arg=argument
|
556
|
+
if @use_mocks and arg.kind_of?(Hash) and arg.keys.include?(:mock_response) then
|
557
|
+
data=""
|
558
|
+
if arg[:mock_response].keys.include?(:data) then
|
559
|
+
data=arg[:mock_response][:data]
|
560
|
+
if data.kind_of?(Hash) #to json
|
561
|
+
begin
|
562
|
+
require 'json'
|
563
|
+
data=data.to_json
|
564
|
+
rescue
|
565
|
+
@logger.fatal "There was a problem converting to json: #{data}"
|
566
|
+
end
|
567
|
+
end
|
568
|
+
end
|
569
|
+
@logger.warn "Pay attention!!! This is a mock response:"
|
570
|
+
@start_time_net = Time.now if @start_time_net.nil?
|
571
|
+
manage_response(arg[:mock_response], data.to_s)
|
572
|
+
return @response
|
573
|
+
end
|
574
|
+
end
|
575
|
+
|
576
|
+
begin
|
577
|
+
@start_time_net = Time.now if @start_time_net.nil?
|
578
|
+
resp=@http.delete(path, headers_t)
|
579
|
+
data=resp.body
|
580
|
+
rescue Exception => stack
|
581
|
+
@logger.warn stack
|
582
|
+
@logger.warn "The connection seems to be closed in the host machine. Trying to reconnect"
|
583
|
+
@http.finish()
|
584
|
+
@http.start()
|
585
|
+
@start_time_net = Time.now if @start_time_net.nil?
|
586
|
+
resp, data=@http.delete(path)
|
587
|
+
end
|
588
|
+
manage_response(resp, data)
|
589
|
+
|
590
|
+
return @response
|
591
|
+
rescue Exception => stack
|
592
|
+
@logger.fatal stack
|
593
|
+
return :error
|
594
|
+
end
|
595
|
+
|
596
|
+
end
|
597
|
+
|
598
|
+
######################################################
|
599
|
+
# Implementation of the http HEAD method.
|
600
|
+
# Asks for the response identical to the one that would correspond to a GET request, but without the response body.
|
601
|
+
# This is useful for retrieving meta-information written in response headers, without having to transport the entire content.
|
602
|
+
# input:
|
603
|
+
# 1 argument
|
604
|
+
# Hash containing at least key :path
|
605
|
+
# 1 argument
|
606
|
+
# String giving the path
|
607
|
+
# output:
|
608
|
+
# response -> Hash including the symbol keys:
|
609
|
+
# :message = plain text response
|
610
|
+
# :code = code response (200=ok,500=wrong...)
|
611
|
+
# *All keys in response are lowercase
|
612
|
+
######################################################
|
613
|
+
def head(argument)
|
614
|
+
begin
|
615
|
+
if argument.kind_of?(String) then
|
616
|
+
argument={:path => argument}
|
617
|
+
end
|
618
|
+
path, data, headers_t=manage_request(argument)
|
619
|
+
@start_time = Time.now if @start_time.nil?
|
620
|
+
if argument.kind_of?(Hash) then
|
621
|
+
arg=argument
|
622
|
+
if @use_mocks and arg.kind_of?(Hash) and arg.keys.include?(:mock_response) then
|
623
|
+
data=""
|
624
|
+
if arg[:mock_response].keys.include?(:data) then
|
625
|
+
data=arg[:mock_response][:data]
|
626
|
+
if data.kind_of?(Hash) #to json
|
627
|
+
begin
|
628
|
+
require 'json'
|
629
|
+
data=data.to_json
|
630
|
+
rescue
|
631
|
+
@logger.fatal "There was a problem converting to json: #{data}"
|
632
|
+
end
|
633
|
+
end
|
634
|
+
end
|
635
|
+
@logger.warn "Pay attention!!! This is a mock response:"
|
636
|
+
@start_time_net = Time.now if @start_time_net.nil?
|
637
|
+
manage_response(arg[:mock_response], data.to_s)
|
638
|
+
return @response
|
639
|
+
end
|
640
|
+
end
|
641
|
+
|
642
|
+
begin
|
643
|
+
@start_time_net = Time.now if @start_time_net.nil?
|
644
|
+
resp=@http.head(path, headers_t)
|
645
|
+
data=resp.body
|
646
|
+
rescue Exception => stack
|
647
|
+
@logger.warn stack
|
648
|
+
@logger.warn "The connection seems to be closed in the host machine. Trying to reconnect"
|
649
|
+
@http.finish()
|
650
|
+
@http.start()
|
651
|
+
@start_time_net = Time.now if @start_time_net.nil?
|
652
|
+
resp, data=@http.head(path)
|
653
|
+
end
|
654
|
+
manage_response(resp, data)
|
655
|
+
return @response
|
656
|
+
rescue Exception => stack
|
657
|
+
@logger.fatal stack
|
658
|
+
return :error
|
659
|
+
end
|
660
|
+
end
|
661
|
+
|
662
|
+
|
663
|
+
######################################################
|
664
|
+
# Close HTTP connection
|
665
|
+
######################################################
|
666
|
+
def close
|
667
|
+
begin
|
668
|
+
pos=0
|
669
|
+
found=false
|
670
|
+
NiceHttp.connections.each {|conn|
|
671
|
+
if conn.object_id == self.object_id then
|
672
|
+
found=true
|
673
|
+
break
|
674
|
+
end
|
675
|
+
pos+=1
|
676
|
+
}
|
677
|
+
if found
|
678
|
+
NiceHttp.connections.delete_at(pos)
|
679
|
+
end
|
680
|
+
|
681
|
+
unless @closed
|
682
|
+
if !@http.nil? then
|
683
|
+
@http.finish()
|
684
|
+
@http=nil
|
685
|
+
@logger.info "the HTTP connection was closed: #{@message_server}"
|
686
|
+
else
|
687
|
+
@http=nil
|
688
|
+
@logger.fatal "It was not possible to close the HTTP connection: #{@message_server}"
|
689
|
+
end
|
690
|
+
@closed=true
|
691
|
+
else
|
692
|
+
@logger.warn "It was not possible to close the HTTP connection, already closed: #{@message_server}"
|
693
|
+
end
|
694
|
+
rescue Exception => stack
|
695
|
+
@logger.fatal stack
|
696
|
+
end
|
697
|
+
NiceHttp.active-=1
|
698
|
+
end
|
699
|
+
|
700
|
+
|
701
|
+
######################################################
|
702
|
+
# private method to manage Request
|
703
|
+
# input:
|
704
|
+
# 3 args: path, data, headers
|
705
|
+
# 1 arg: Hash containg at least keys :path and :data
|
706
|
+
# output:
|
707
|
+
# path, data, headers
|
708
|
+
######################################################
|
709
|
+
def manage_request(*arguments)
|
710
|
+
require 'json'
|
711
|
+
begin
|
712
|
+
content_type_included=false
|
713
|
+
path=""
|
714
|
+
data=""
|
715
|
+
|
716
|
+
@response=Hash.new()
|
717
|
+
headers_t=@headers.dup()
|
718
|
+
cookies_to_set_str=""
|
719
|
+
if arguments.size==3 then
|
720
|
+
path=arguments[0]
|
721
|
+
elsif arguments.size==1 and arguments[0].kind_of?(Hash) then
|
722
|
+
path=arguments[0][:path]
|
723
|
+
elsif arguments.size==1 and arguments[0].kind_of?(String) then
|
724
|
+
path=arguments[0].to_s()
|
725
|
+
end
|
726
|
+
@cookies.each {|cookie_path, cookies_hash|
|
727
|
+
cookie_path="" if cookie_path=="/"
|
728
|
+
path_to_check=path
|
729
|
+
if path=="/" or path[-1]!="/" then
|
730
|
+
path_to_check+="/"
|
731
|
+
end
|
732
|
+
if path_to_check.scan(/^#{cookie_path}\//).size>0 then
|
733
|
+
cookies_hash.each {|key, value|
|
734
|
+
cookies_to_set_str+="#{key}=#{value}; "
|
735
|
+
}
|
736
|
+
end
|
737
|
+
}
|
738
|
+
headers_t["Cookie"]=cookies_to_set_str
|
739
|
+
|
740
|
+
method_s=caller[0].to_s().scan(/:in `(.*)'/).join
|
741
|
+
|
742
|
+
if arguments.size==3 then
|
743
|
+
data=arguments[1]
|
744
|
+
if arguments[2].kind_of?(Hash) then
|
745
|
+
headers_t.merge!(arguments[2])
|
746
|
+
end
|
747
|
+
elsif arguments.size==1 and arguments[0].kind_of?(Hash) then
|
748
|
+
if arguments[0][:data].nil? then
|
749
|
+
if arguments[0].keys.include?(:data) then
|
750
|
+
data=""
|
751
|
+
elsif arguments[0].keys.include?(:data_examples) and
|
752
|
+
arguments[0][:data_examples].kind_of?(Array) then
|
753
|
+
data=arguments[0][:data_examples][0] #the first example by default
|
754
|
+
else
|
755
|
+
data=""
|
756
|
+
end
|
757
|
+
|
758
|
+
else
|
759
|
+
data=arguments[0][:data]
|
760
|
+
end
|
761
|
+
if arguments[0].include?(:headers) then
|
762
|
+
headers_t.merge!(arguments[0][:headers])
|
763
|
+
end
|
764
|
+
|
765
|
+
if headers_t["Content-Type"].to_s()=="" and headers_t["content-type"].to_s()=="" and
|
766
|
+
headers_t[:"content-type"].to_s()=="" and headers_t[:"Content-Type"].to_s()=="" then
|
767
|
+
content_type_included=false
|
768
|
+
elsif headers_t["content-type"].to_s()!="" then
|
769
|
+
content_type_included=true
|
770
|
+
headers_t["Content-Type"]=headers_t["content-type"]
|
771
|
+
elsif headers_t[:"content-type"].to_s()!="" then
|
772
|
+
content_type_included=true
|
773
|
+
headers_t["Content-Type"]=headers_t[:"content-type"]
|
774
|
+
headers_t.delete(:"content-type")
|
775
|
+
elsif headers_t[:"Content-Type"].to_s()!="" then
|
776
|
+
content_type_included=true
|
777
|
+
headers_t["Content-Type"]=headers_t[:"Content-Type"]
|
778
|
+
headers_t.delete(:"Content-Type")
|
779
|
+
elsif headers_t["Content-Type"].to_s()!="" then
|
780
|
+
content_type_included=true
|
781
|
+
end
|
782
|
+
|
783
|
+
if !content_type_included and data.kind_of?(Hash)
|
784
|
+
headers_t['Content-Type'] = 'application/json'
|
785
|
+
content_type_included=true
|
786
|
+
end
|
787
|
+
|
788
|
+
if content_type_included and (!headers_t["Content-Type"][/text\/xml/].nil? or
|
789
|
+
!headers_t["Content-Type"]["application/soap+xml"].nil? or
|
790
|
+
!headers_t["Content-Type"][/application\/jxml/].nil?) then
|
791
|
+
if arguments[0].include?(:values) then
|
792
|
+
arguments[0][:values].each {|key, value|
|
793
|
+
data=NiceHttpUtils.set_value_xml_tag(key.to_s(), data, value.to_s(), true)
|
794
|
+
}
|
795
|
+
end
|
796
|
+
elsif content_type_included and !headers_t["Content-Type"][/application\/json/].nil? and data.to_s()!="" then
|
797
|
+
require 'json'
|
798
|
+
if data.kind_of?(String) then
|
799
|
+
if arguments[0].include?(:values) then
|
800
|
+
arguments[0][:values].each {|key, value|
|
801
|
+
data.gsub!(/(( *|^)"?#{key.to_s()}"? *: *")(.*)(" *, *$)/, '\1' + value+ '\4') # "key":"value", or key:"value",
|
802
|
+
data.gsub!(/(( *|^)"?#{key.to_s()}"? *: *")(.*)(" *$)/, '\1' + value+ '\4') # "key":"value" or key:"value"
|
803
|
+
data.gsub!(/(( *|^)"?#{key.to_s()}"? *: *[^"])([^"].*)([^"] *, *$)/, '\1' + value+ '\4') # "key":456, or key:456,
|
804
|
+
data.gsub!(/(( *|^)"?#{key.to_s()}"? *: *[^"])([^"].*)([^"] * *$)/, '\1' + value+ '\4') # "key":456 or key:456
|
805
|
+
}
|
806
|
+
end
|
807
|
+
elsif data.kind_of?(Hash) then
|
808
|
+
data_n=Hash.new()
|
809
|
+
data.each {|key, value|
|
810
|
+
data_n[key.to_s()]=value
|
811
|
+
}
|
812
|
+
if arguments[0].include?(:values) then
|
813
|
+
#req[:values][:loginName] or req[:values]["loginName"]
|
814
|
+
new_values_hash=Hash.new()
|
815
|
+
arguments[0][:values].each {|kv, vv|
|
816
|
+
if data_n.keys.include?(kv.to_s()) then
|
817
|
+
new_values_hash[kv.to_s()]=vv
|
818
|
+
end
|
819
|
+
}
|
820
|
+
data_n.merge!(new_values_hash)
|
821
|
+
end
|
822
|
+
data=data_n.to_json()
|
823
|
+
elsif data.kind_of?(Array) then
|
824
|
+
data_arr=Array.new()
|
825
|
+
data.each_with_index {|row, indx|
|
826
|
+
unless row.kind_of?(Hash) then
|
827
|
+
@logger.fatal("Wrong format on request application/json, be sure is a Hash, Array of Hashes or JSON string")
|
828
|
+
return :error, :error, :error
|
829
|
+
end
|
830
|
+
data_n=Hash.new()
|
831
|
+
row.each {|key, value|
|
832
|
+
data_n[key.to_s()]=value
|
833
|
+
}
|
834
|
+
if arguments[0].include?(:values) then
|
835
|
+
#req[:values][:loginName] or req[:values]["loginName"]
|
836
|
+
new_values_hash=Hash.new()
|
837
|
+
if arguments[0][:values].kind_of?(Hash) then #values[:mykey][3]
|
838
|
+
arguments[0][:values].each {|kv, vv|
|
839
|
+
if data_n.keys.include?(kv.to_s()) and !vv[indx].nil? then
|
840
|
+
new_values_hash[kv.to_s()]=vv[indx]
|
841
|
+
end
|
842
|
+
}
|
843
|
+
elsif arguments[0][:values].kind_of?(Array) then #values[5][:mykey]
|
844
|
+
if !arguments[0][:values][indx].nil? then
|
845
|
+
arguments[0][:values][indx].each {|kv, vv|
|
846
|
+
if data_n.keys.include?(kv.to_s()) then
|
847
|
+
new_values_hash[kv.to_s()]=vv
|
848
|
+
end
|
849
|
+
}
|
850
|
+
end
|
851
|
+
else
|
852
|
+
@logger.fatal("Wrong format on request application/json when supplying values, the data is an array of Hashes but the values supplied are not")
|
853
|
+
return :error, :error, :error
|
854
|
+
end
|
855
|
+
data_n.merge!(new_values_hash)
|
856
|
+
end
|
857
|
+
data_arr.push(data_n)
|
858
|
+
}
|
859
|
+
data=data_arr.to_json()
|
860
|
+
else
|
861
|
+
@logger.fatal("Wrong format on request application/json, be sure is a Hash, Array of Hashes or JSON string")
|
862
|
+
return :error, :error, :error
|
863
|
+
end
|
864
|
+
elsif content_type_included and arguments[0].include?(:values) then
|
865
|
+
if arguments[0][:values].kind_of?(Hash) and arguments[0][:values].keys.size>0 then
|
866
|
+
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" then
|
867
|
+
@logger.warn(":values key given without a valid content-type or data for request. No values modified on the request")
|
868
|
+
end
|
869
|
+
end
|
870
|
+
end
|
871
|
+
elsif arguments.size==1 and arguments[0].kind_of?(String) then
|
872
|
+
#path=arguments[0].to_s()
|
873
|
+
data=""
|
874
|
+
else
|
875
|
+
@logger.fatal("Invalid number of arguments or wrong arguments in #{method_s}")
|
876
|
+
return :error, :error, :error
|
877
|
+
end
|
878
|
+
if headers_t.keys.include?("Content-Type") and !headers_t["Content-Type"]["multipart/form-data"].nil? and headers_t["Content-Type"]!=["multipart/form-data"] then #only for the case raw multipart request
|
879
|
+
encoding="UTF-8"
|
880
|
+
data_s=""
|
881
|
+
else
|
882
|
+
encoding=data.to_s().scan(/encoding='(.*)'/i).join
|
883
|
+
if encoding.to_s()=="" then
|
884
|
+
encoding=data.to_s().scan(/charset='(.*)'/i).join
|
885
|
+
end
|
886
|
+
if encoding.to_s()=="" and headers_t.include?("Content-Type") then
|
887
|
+
encoding=headers_t["Content-Type"].scan(/charset='?(.*)'?/i).join
|
888
|
+
if encoding.to_s()=="" then
|
889
|
+
encoding=headers_t["Content-Type"].scan(/encoding='?(.*)'?/i).join
|
890
|
+
end
|
891
|
+
end
|
892
|
+
|
893
|
+
begin
|
894
|
+
data_s=JSON.pretty_generate(JSON.parse(data))
|
895
|
+
rescue
|
896
|
+
data_s=data
|
897
|
+
end
|
898
|
+
data_s=data_s.to_s().gsub("<", "<")
|
899
|
+
end
|
900
|
+
if headers_t.keys.include?("Accept-Encoding")
|
901
|
+
headers_t["Accept-Encoding"].gsub!("gzip","")#removed so the response is in plain text
|
902
|
+
end
|
903
|
+
|
904
|
+
headers_ts=""
|
905
|
+
headers_t.each {|key, val| headers_ts+=key.to_s + ":" + val.to_s() + ", "}
|
906
|
+
message="#{method_s} REQUEST: \npath= " + path.to_s() + "\n"
|
907
|
+
message+="headers= " + headers_ts.to_s() + "\n"
|
908
|
+
message+="data= " + data_s.to_s() + "\n"
|
909
|
+
message=@message_server+"\n"+message
|
910
|
+
if path.to_s().scan(/^https?:\/\//).size>0 and path.to_s().scan(/^https?:\/\/#{@host}/).size==0 then
|
911
|
+
# the path is for another server than the current
|
912
|
+
else
|
913
|
+
NiceHttp.last_request=message
|
914
|
+
@logger.info(message)
|
915
|
+
end
|
916
|
+
|
917
|
+
if data.to_s()!="" and encoding.to_s().upcase!="UTF-8" and encoding!="" then
|
918
|
+
data=data.to_s().encode(encoding, "UTF-8")
|
919
|
+
end
|
920
|
+
return path, data, headers_t
|
921
|
+
rescue Exception => stack
|
922
|
+
@logger.fatal(stack)
|
923
|
+
@logger.fatal("manage_request Error on method #{method_s} . path:#{path.to_s()}. data:#{data.to_s()}. headers:#{headers_t.to_s()}")
|
924
|
+
return :error
|
925
|
+
end
|
926
|
+
end
|
927
|
+
|
928
|
+
######################################################
|
929
|
+
# private method to manage Response
|
930
|
+
# input:
|
931
|
+
# resp
|
932
|
+
# data
|
933
|
+
# output:
|
934
|
+
# @response updated
|
935
|
+
######################################################
|
936
|
+
def manage_response(resp, data)
|
937
|
+
require 'json'
|
938
|
+
begin
|
939
|
+
if @start_time.kind_of?(Time)
|
940
|
+
@response[:time_elapsed_total]=Time.now-@start_time
|
941
|
+
@start_time = nil
|
942
|
+
else
|
943
|
+
@response[:time_elapsed_total]=nil
|
944
|
+
end
|
945
|
+
if @start_time_net.kind_of?(Time)
|
946
|
+
@response[:time_elapsed]=Time.now-@start_time_net
|
947
|
+
@start_time_net = nil
|
948
|
+
else
|
949
|
+
@response[:time_elapsed]=nil
|
950
|
+
end
|
951
|
+
begin
|
952
|
+
# this is to be able to access all keys as symbols
|
953
|
+
new_resp=Hash.new()
|
954
|
+
resp.each {|key, value|
|
955
|
+
if key.kind_of?(String) then
|
956
|
+
new_resp[key.to_sym]=value
|
957
|
+
end
|
958
|
+
}
|
959
|
+
new_resp.each {|key, value|
|
960
|
+
resp[key]=value
|
961
|
+
}
|
962
|
+
rescue
|
963
|
+
end
|
964
|
+
#for mock_responses to be able to add outside of the header like content-type for example
|
965
|
+
if resp.kind_of?(Hash) and !resp.has_key?(:header) then
|
966
|
+
resp[:header]={}
|
967
|
+
end
|
968
|
+
if resp.kind_of?(Hash)
|
969
|
+
resp.each {|k, v|
|
970
|
+
if k!=:code and k!=:message and k!=:data and k!=:'set-cookie' and k!=:header
|
971
|
+
resp[:header][k]=v
|
972
|
+
end
|
973
|
+
}
|
974
|
+
resp[:header].each {|k, v|
|
975
|
+
resp.delete(k) if resp.has_key?(k)
|
976
|
+
}
|
977
|
+
end
|
978
|
+
|
979
|
+
method_s=caller[0].to_s().scan(/:in `(.*)'/).join
|
980
|
+
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") then
|
981
|
+
data=Zlib::Inflate.inflate(data)
|
982
|
+
end
|
983
|
+
encoding_response=""
|
984
|
+
if resp.header.kind_of?(Hash) and (resp.header["content-type"].to_s()!="" or resp.header[:"content-type"].to_s()!="") then
|
985
|
+
encoding_response=resp.header["content-type"].scan(/;charset=(.*)/i).join if resp.header.has_key?("content-type")
|
986
|
+
encoding_response=resp.header[:"content-type"].scan(/;charset=(.*)/i).join if resp.header.has_key?(:"content-type")
|
987
|
+
end
|
988
|
+
if encoding_response.to_s()=="" then
|
989
|
+
encoding_response="UTF-8"
|
990
|
+
end
|
991
|
+
|
992
|
+
if encoding_response.to_s()!="" and encoding_response.to_s().upcase!="UTF-8" then
|
993
|
+
data.encode!("UTF-8", encoding_response.to_s())
|
994
|
+
end
|
995
|
+
if encoding_response!="" and encoding_response.to_s().upcase!="UTF-8" then
|
996
|
+
@response[:message]=resp.message.to_s().encode("UTF-8", encoding_response.to_s())
|
997
|
+
#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...)
|
998
|
+
resp.each {|key, val| @response[key]=val.to_s().encode("UTF-8", encoding_response.to_s())}
|
999
|
+
else
|
1000
|
+
@response[:message]=resp.message
|
1001
|
+
resp.each {|key, val| @response[key]=val}
|
1002
|
+
end
|
1003
|
+
if !defined?(Net::HTTP::Post::Multipart) or (defined?(Net::HTTP::Post::Multipart) and !data.kind_of?(Net::HTTP::Post::Multipart))
|
1004
|
+
@response[:data]=data
|
1005
|
+
else
|
1006
|
+
@response[:data]=""
|
1007
|
+
end
|
1008
|
+
|
1009
|
+
@response[:code]=resp.code
|
1010
|
+
|
1011
|
+
unless @response.nil? then
|
1012
|
+
message="\nRESPONSE: \n" + @response[:code].to_s()+ ":" + @response[:message].to_s()
|
1013
|
+
if @debug then
|
1014
|
+
NiceHttp.last_response=message
|
1015
|
+
@response.each {|key, value|
|
1016
|
+
if value.to_s()!="" then
|
1017
|
+
value_orig=value
|
1018
|
+
if key.kind_of?(Symbol) then
|
1019
|
+
if key==:code or key==:data or key==:header or key==:message then
|
1020
|
+
if key==:data then
|
1021
|
+
begin
|
1022
|
+
JSON.parse(value_orig)
|
1023
|
+
data_s=JSON.pretty_generate(JSON.parse(value_orig))
|
1024
|
+
rescue
|
1025
|
+
data_s=value_orig
|
1026
|
+
end
|
1027
|
+
NiceHttp.last_response+="\nresponse." + key.to_s() + " = '" + data_s.gsub("<", "<") + "'\n"
|
1028
|
+
if value_orig != value then
|
1029
|
+
message+="\nresponse." + key.to_s() + " = '" + value.gsub("<", "<") + "'\n"
|
1030
|
+
else
|
1031
|
+
message+="\nresponse." + key.to_s() + " = '" + data_s.gsub("<", "<") + "'\n"
|
1032
|
+
end
|
1033
|
+
else
|
1034
|
+
NiceHttp.last_response+="\nresponse." + key.to_s() + " = '" + value.to_s().gsub("<", "<") + "'"
|
1035
|
+
message+="\nresponse." + key.to_s() + " = '" + value.to_s().gsub("<", "<") + "'"
|
1036
|
+
end
|
1037
|
+
else
|
1038
|
+
NiceHttp.last_response+="\nresponse[:" + key.to_s() + "] = '" + value.to_s().gsub("<", "<") + "'"
|
1039
|
+
message+="\nresponse[:" + key.to_s() + "] = '" + value.to_s().gsub("<", "<") + "'"
|
1040
|
+
end
|
1041
|
+
elsif !@response.include?(key.to_sym)
|
1042
|
+
NiceHttp.last_response+="\nresponse['" + key.to_s() + "'] = '" + value.to_s().gsub("<", "<") + "'"
|
1043
|
+
message+="\nresponse['" + key.to_s() + "'] = '" + value.to_s().gsub("<", "<") + "'"
|
1044
|
+
end
|
1045
|
+
end
|
1046
|
+
}
|
1047
|
+
|
1048
|
+
end
|
1049
|
+
@logger.info message
|
1050
|
+
if @response.kind_of?(Hash) then
|
1051
|
+
if @response.keys.include?(:requestid) then
|
1052
|
+
@headers["requestId"]=@response[:requestid]
|
1053
|
+
NiceHttp.request_id=@response[:requestid]
|
1054
|
+
@logger.info "requestId was found on the response header and it has been added to the headers for the next request"
|
1055
|
+
end
|
1056
|
+
end
|
1057
|
+
end
|
1058
|
+
|
1059
|
+
if resp[:'set-cookie'].to_s()!="" then
|
1060
|
+
if resp.kind_of?(Hash) then #mock_response
|
1061
|
+
cookies_to_set=resp[:'set-cookie'].to_s().split(", ")
|
1062
|
+
else #Net::Http
|
1063
|
+
cookies_to_set=resp.get_fields('set-cookie')
|
1064
|
+
end
|
1065
|
+
cookies_to_set.each {|cookie|
|
1066
|
+
cookie_pair=cookie.split('; ')[0].split("=")
|
1067
|
+
cookie_path=cookie.scan(/; path=([^;]+)/i).join
|
1068
|
+
@cookies[cookie_path]=Hash.new() unless @cookies.keys.include?(cookie_path)
|
1069
|
+
@cookies[cookie_path][cookie_pair[0]]=cookie_pair[1]
|
1070
|
+
}
|
1071
|
+
|
1072
|
+
@logger.info "set-cookie added to Cookie header as required"
|
1073
|
+
|
1074
|
+
if @headers.has_key?("X-CSRFToken") then
|
1075
|
+
csrftoken=resp[:"set-cookie"].to_s().scan(/csrftoken=([\da-z]+);/).join
|
1076
|
+
if csrftoken.to_s()!="" then
|
1077
|
+
@headers["X-CSRFToken"]=csrftoken
|
1078
|
+
@logger.info "X-CSRFToken exists on headers and has been overwritten"
|
1079
|
+
end
|
1080
|
+
else
|
1081
|
+
csrftoken=resp[:"set-cookie"].to_s().scan(/csrftoken=([\da-z]+);/).join
|
1082
|
+
if csrftoken.to_s()!="" then
|
1083
|
+
@headers["X-CSRFToken"]=csrftoken
|
1084
|
+
@logger.info "X-CSRFToken added to header as required"
|
1085
|
+
end
|
1086
|
+
|
1087
|
+
end
|
1088
|
+
end
|
1089
|
+
|
1090
|
+
rescue Exception => stack
|
1091
|
+
@logger.fatal stack
|
1092
|
+
@logger.fatal "manage_response Error on method #{method_s} "
|
1093
|
+
end
|
1094
|
+
end
|
1095
|
+
|
1096
|
+
private :manage_request, :manage_response
|
1097
|
+
end
|
1098
|
+
|