nice_http 0.9.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 77545459842646b2d83717b31df4c18aae071945933f5cde92e19ecbdedfc5a6
4
+ data.tar.gz: 80d78b75f647c47677b4e410e5fc7fcf8d8f4f1a58c3ac17221118d62b05c020
5
+ SHA512:
6
+ metadata.gz: 07b94face51a72fe46cb7b40341ea4849aa0ba1231004b1b65dd4a37956db36e3ef4c054e9a1bc635f725ebc6019cc003dbe76bf3479eafd9cb7cb37f9b0c51b
7
+ data.tar.gz: c7d403e1e46ab3052b076baf474ef6907e66ac8f84a082ecebe78d759bf39016e6d048327da258ccce2e07e6e56ef41cdb6f6f630317cbb56cd630aa9eb7f8f9
@@ -0,0 +1,5 @@
1
+ --readme README.md
2
+ --title 'nice_http - NiceHttp -- simplest library for accessing and testing HTTP and REST resources.'
3
+ --charset utf-8
4
+ --markup markdown
5
+ 'lib/*.rb' - '*.md' - 'LICENSE'
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2017 Mario Ruiz
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,217 @@
1
+ # NiceHttp
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/nice_http.svg)](https://rubygems.org/gems/nice_http)
4
+
5
+ NiceHttp the simplest library for accessing and testing HTTP and REST resources.
6
+
7
+ Manage different hosts on the fly. Easily get the value you want from the JSON strings. Use hashes on your requests.
8
+
9
+ Also you can use mock responses by using :mock_response key on the request hash and enable the use_mocks option on NiceHttp.
10
+
11
+ NiceHttp will take care of the redirections and the cookies, and for security tests you will be able to modify the cookies or disable and control the redirections by yourself.
12
+
13
+ To be able to generate random requests take a look at the documentation for nice_hash gem: https://github.com/MarioRuiz/nice_hash
14
+
15
+ ## Installation
16
+
17
+ Install it yourself as:
18
+
19
+ $ gem install nice_http
20
+
21
+
22
+ ## A very simple first example
23
+
24
+ ```ruby
25
+ require 'nice_http'
26
+
27
+ http = NiceHttp.new('https://reqres.in')
28
+
29
+ resp = http.get("/api/users?page=2")
30
+
31
+ pp resp.code
32
+ pp resp.data.json
33
+
34
+ resp = http.get("/api/users/2")
35
+
36
+ pp resp.data.json(:first_name, :last_name)
37
+
38
+ resp = http.post( {
39
+ path: "/api/users",
40
+ data: {"name": "morpheus", "job": "leader"}
41
+ } )
42
+
43
+ pp resp.data.json
44
+ ```
45
+
46
+ ## Create a connection
47
+
48
+ The simplest way is just by supplying the value as an argument:
49
+
50
+ ```ruby
51
+
52
+ # as an url
53
+ http1 = NiceHttp.new("https://example.com")
54
+
55
+ # as parameters
56
+ http2 = NiceHttp.new( host: "reqres.in", port: 443, ssl: true )
57
+
58
+ # as a hash
59
+ http3 = NiceHttp.new my_reqres_server
60
+
61
+
62
+ ```
63
+
64
+
65
+ You can specify all the defaults you will be using when creating connections by using the NiceHttp methods, in this example, http1 and http2 will be connecting to regres.in and http3 to example.com:
66
+
67
+ ```ruby
68
+
69
+ NiceHttp.host = 'reqres.in'
70
+ NiceHttp.ssl = true
71
+ NiceHttp.port = 443
72
+ NiceHttp.debug = false
73
+ NiceHttp.log = "./my_logs.log"
74
+
75
+ http1 = NiceHttp.new()
76
+
77
+ http2 = NiceHttp.new()
78
+
79
+ http3 = NiceHttp.new("https://example.com")
80
+
81
+ ```
82
+
83
+ ## Creating requests
84
+
85
+ You can use hash requests to simplify the management of your requests, for example creating a file specifying all the requests for your Customers API.
86
+
87
+ The keys you can use:
88
+
89
+ *path*: relative or absolute path, for example: "/api2/customers/update.do"
90
+
91
+ *headers*: specific headers for the request. It will include a hash with the values.
92
+
93
+ *data*: the data to be sent for example a JSON string. In case of supplying a Hash, Nice Http will assume that is a JSON and will convert it to a JSON string before sending the request and will add to the headers: 'Content-Type': 'application/json'
94
+
95
+ *mock_response*: In case of use_mocks=true then NiceHttp will return this response
96
+
97
+
98
+ Let's guess you have a file with this data for your requests on */requests/example.rb*:
99
+
100
+ ```ruby
101
+
102
+ module Requests
103
+
104
+ module Example
105
+
106
+ # simple get request example
107
+ def self.list_of_users()
108
+ {
109
+ path: "/api/users?page=2"
110
+ }
111
+ end
112
+
113
+ # post request example using a request hash that will be converted automatically to a json string
114
+ def self.create_user_hash()
115
+ {
116
+ path: "/api/users",
117
+ data: {
118
+ name: "morpheus",
119
+ job: "leader"
120
+ }
121
+ }
122
+ end
123
+
124
+ # post request example using a JSON string
125
+ def self.create_user_raw()
126
+ {
127
+ path: "/api/users",
128
+ headers: {"Content-Type": "application/json"},
129
+ data: '{"name": "morpheus","job": "leader"}'
130
+ }
131
+ end
132
+
133
+ end
134
+
135
+ end
136
+
137
+ ```
138
+
139
+
140
+ Then in your code you can require this request file and use it like this:
141
+
142
+ ```ruby
143
+
144
+ resp = http.get Requests::Example.list_of_users
145
+
146
+ pp resp.code
147
+
148
+ resp = http.post Requests::Example.create_user_hash
149
+
150
+ pp resp.data.json
151
+
152
+
153
+ resp = http.post Requests::Example.create_user_raw
154
+
155
+ pp resp.data.json(:job)
156
+
157
+
158
+ ```
159
+
160
+
161
+ In case you want to modify the request before sending it, for example just changing one field but the rest will be the same, you can supply a new key :values in the request hash that will contain a hash with the keys to be changed and NiceHttp will perform the necessary changes at any level:
162
+
163
+ ```ruby
164
+
165
+
166
+ req = Requests::Example.create_user_hash
167
+ req[:values] = {job: "developer"}
168
+
169
+ resp = http.post req
170
+
171
+ pp resp.data.json
172
+ #response: {:name=>"morpheus", :job=>"developer", :id=>"192", :createdAt=>"2018-12-14T14:41:54.371Z"}
173
+
174
+
175
+ ```
176
+
177
+ ## Responses
178
+
179
+ The response will include at least the keys:
180
+
181
+ *code*: the http code response, for example: 200
182
+
183
+ *message*: the http message response, for example: "OK"
184
+
185
+ *data*: the data response structure. In case of json we can get it as a hash by using: `resp.data.json`. Also you can filter the json structure and get what you want: `resp.data.json(:loginname, :address)`
186
+
187
+ Also interesting keys would be: *time_elapsed_total*, *time_elapsed* and many more available
188
+
189
+
190
+ ## Special settings
191
+
192
+ *debug*: (true or false) it will set the connecition on debug mode so you will be able to see the whole communication with the server in detail
193
+
194
+ *log*: (:no, :screen, :file, :fix_file, "filename") it will log the basic communication for inspect. In case you want to add extra info to your logs you can do it for example adding to your code: http.logger.info "example extra log"
195
+
196
+ *headers*: Hash containing the headers for the communication
197
+
198
+ *cookies*: Hash containing the cookies for the communication
199
+
200
+ *proxy_port, proxy_host*: in case you want to use a proxy for the connection
201
+
202
+ *use_mocks*: (true or false) in case of true if the request hash contains a mock_response key it will be returning that response instead of trying to send the request.
203
+
204
+ *auto_redirect*: (true or false) in case of true it will take care of the auto redirections.
205
+
206
+
207
+
208
+ ## Contributing
209
+
210
+ Bug reports and pull requests are welcome on GitHub at https://github.com/marioruiz/nice_http.
211
+
212
+
213
+ ## License
214
+
215
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
216
+
217
+
@@ -0,0 +1,1083 @@
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 !@proxy_host.nil? && !@proxy_port.nil?
106
+ @http = Net::HTTP::Proxy(@proxy_host, @proxy_port).new(@host, @port)
107
+ @http.use_ssl = @ssl
108
+ @http.set_debug_output $stderr if @debug
109
+ @http.verify_mode = OpenSSL::SSL::VERIFY_NONE
110
+ @http.start
111
+ else
112
+ @http = Net::HTTP.new(@host, @port)
113
+ @http.use_ssl = @ssl
114
+ @http.set_debug_output $stderr if @debug
115
+ @http.verify_mode = OpenSSL::SSL::VERIFY_NONE
116
+ @http.start
117
+ end
118
+
119
+ if @log.kind_of?(String)
120
+ @logger = Logger.new File.new(@log, "w")
121
+ elsif @log==:fix_file
122
+ @logger = Logger.new File.new("nice_http.log", "w")
123
+ elsif @log==:file
124
+ @logger = Logger.new File.new("nice_http_#{Time.now.strftime('%Y-%m-%d-%H%M%S')}.log", 'w')
125
+ elsif @log==:screen
126
+ @logger = Logger.new STDOUT
127
+ elsif @log==:no
128
+ @logger = Logger.new nil
129
+ end
130
+ @logger.level = Logger::INFO
131
+
132
+ @message_server="(#{self.object_id}):"
133
+
134
+ 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()} "
135
+
136
+ @logger.info(log_message)
137
+ @message_server+=" Http connection: "
138
+ if @ssl then
139
+ @message_server+="https://"
140
+ else
141
+ @message_server+="http://"
142
+ end
143
+ @message_server+="#{@host}:#{@port}"
144
+ if @proxy_host.to_s!="" then
145
+ @message_server+=" proxy:#{@proxy_host}:#{@proxy_port}"
146
+ end
147
+ @auto_redirect = auto_redirect
148
+ rescue Exception => stack
149
+ if @logger.nil?
150
+ puts stack
151
+ else
152
+ @logger.fatal stack
153
+ end
154
+ end
155
+
156
+ NiceHttp.active+=1
157
+ NiceHttp.connections.push(self)
158
+
159
+ end
160
+
161
+ ######################################################
162
+ # Get data from path
163
+ # input:
164
+ # 1 argument
165
+ # Hash containing at least key :path
166
+ # 1 argument
167
+ # path (string)
168
+ # output:
169
+ # response -> Hash including at least the symbol keys:
170
+ # :data = the response data body
171
+ # :message = plain text response
172
+ # :code = code response (200=ok,500=wrong...)
173
+ # *All keys in response are lowercase
174
+ # data, message and code can also be accessed as attributes like .message .code .data, for example:
175
+ # resp=@http.get(Requests::Customer.get_profile)
176
+ # assert resp.code==200
177
+ ######################################################
178
+ def get(arg)
179
+ begin
180
+ path, data, headers_t=manage_request(arg)
181
+ @start_time = Time.now if @start_time.nil?
182
+ if @use_mocks and arg.kind_of?(Hash) and arg.keys.include?(:mock_response) then
183
+ data=""
184
+ if arg[:mock_response].keys.include?(:data) then
185
+ data=arg[:mock_response][:data]
186
+ if data.kind_of?(Hash) #to json
187
+ begin
188
+ require 'json'
189
+ data=data.to_json
190
+ rescue
191
+ @logger.fatal "There was a problem converting to json: #{data}"
192
+ end
193
+ end
194
+ end
195
+ @logger.warn "Pay attention!!! This is a mock response:"
196
+ @start_time_net = Time.now if @start_time_net.nil?
197
+ manage_response(arg[:mock_response], data.to_s)
198
+ return @response
199
+ end
200
+ begin
201
+ if path.include?("http:") or path.include?("https:") then #server included on path problably because of a redirection to a different server
202
+ require 'uri'
203
+ uri = URI.parse(path)
204
+ ssl=false
205
+ ssl=true if path.include?("https:")
206
+
207
+
208
+ server="http://"
209
+ server="https://" if path.include?("https:")
210
+ if uri.port!=443 then
211
+ server+="#{uri.host}:#{uri.port}"
212
+ else
213
+ server+="#{uri.host}"
214
+ end
215
+
216
+ http_redir=nil
217
+ NiceHttp.connections.each {|conn|
218
+ if conn.host == uri.host and conn.port==uri.port then
219
+ http_redir=conn
220
+ break
221
+ end
222
+ }
223
+
224
+ if !http_redir.nil?
225
+ path, data, headers_t=manage_request(arg)
226
+ http_redir.cookies.merge!(@cookies)
227
+ http_redir.headers.merge!(headers_t)
228
+ 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
229
+ @response=http_redir.response
230
+ else
231
+ @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."
232
+ end
233
+
234
+ else
235
+ @start_time_net = Time.now if @start_time_net.nil?
236
+ resp=@http.get(path, headers_t)
237
+ data=resp.body
238
+ manage_response(resp, data)
239
+ end
240
+ rescue Exception => stack
241
+ @logger.warn stack
242
+ @logger.warn "The connection seems to be closed in the host machine. Trying to reconnect"
243
+ @http.finish()
244
+ @http.start()
245
+ @start_time_net = Time.now if @start_time_net.nil?
246
+ resp=@http.get(path)
247
+ data=resp.body
248
+ manage_response(resp, data)
249
+ end
250
+ if @auto_redirect and @response[:code].to_i>=300 and @response[:code].to_i<400 and @response.include?(:location) then
251
+ if @num_redirects<=30 then
252
+ @num_redirects+=1
253
+ current_server="http"
254
+ current_server+="s" if @ssl==true
255
+ current_server+="://#{@host}"
256
+ location=@response[:location].gsub(current_server, "")
257
+ @logger.info "(#{@num_redirects}) Redirecting NiceHttp to #{location}"
258
+ get(location)
259
+ else
260
+ @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"
261
+ @num_redirects=0
262
+ end
263
+ else
264
+ @num_redirects=0
265
+ end
266
+ return @response
267
+ rescue Exception => stack
268
+ @logger.fatal stack
269
+ return :error
270
+ end
271
+ end
272
+
273
+ ######################################################
274
+ # Post data to path
275
+ # input:
276
+ # 1 argument
277
+ # Hash containing at least keys :data, :path
278
+ # 3 arguments
279
+ # path (string)
280
+ # data (json data for example)
281
+ # additional_headers (Hash key=>value)
282
+ # output:
283
+ # response -> Hash including at least the symbol keys:
284
+ # :data = the response data body
285
+ # :message = plain text response
286
+ # :code = code response (200=ok,500=wrong...)
287
+ # *All keys in response are lowercase
288
+ # data, message and code can also be accessed as attributes like .message .code .data, for example:
289
+ # resp=@http.post(Requests::Customer.update_customer)
290
+ # assert resp.code==201
291
+ ######################################################
292
+ def post(*arguments)
293
+ begin
294
+ path, data, headers_t=manage_request(*arguments)
295
+ @start_time = Time.now if @start_time.nil?
296
+ if arguments.size>0 and arguments[0].kind_of?(Hash) then
297
+ arg=arguments[0]
298
+ if @use_mocks and arg.kind_of?(Hash) and arg.keys.include?(:mock_response) then
299
+ data=""
300
+ if arg[:mock_response].keys.include?(:data) then
301
+ data=arg[:mock_response][:data]
302
+ if data.kind_of?(Hash) #to json
303
+ begin
304
+ require 'json'
305
+ data=data.to_json
306
+ rescue
307
+ @logger.fatal "There was a problem converting to json: #{data}"
308
+ end
309
+ end
310
+ end
311
+ @logger.warn "Pay attention!!! This is a mock response:"
312
+ @start_time_net = Time.now if @start_time_net.nil?
313
+ manage_response(arg[:mock_response], data.to_s)
314
+ return @response
315
+ end
316
+ end
317
+
318
+ begin
319
+ @start_time_net = Time.now if @start_time_net.nil?
320
+ if headers_t["Content-Type"] == "multipart/form-data" then
321
+ require 'net/http/post/multipart'
322
+ headers_t.each {|key, value|
323
+ arguments[0][:data].add_field(key, value) #add to Headers
324
+ }
325
+ resp=@http.request(arguments[0][:data])
326
+ else
327
+ resp=@http.post(path, data, headers_t)
328
+ data=resp.body
329
+ end
330
+ rescue Exception => stack
331
+ @logger.warn stack
332
+ @logger.warn "The connection seems to be closed in the host machine. Trying to reconnect"
333
+ @http.finish()
334
+ @http.start()
335
+ @start_time_net = Time.now if @start_time_net.nil?
336
+ resp, data=@http.post(path, data, headers_t)
337
+ end
338
+ manage_response(resp, data)
339
+ if @auto_redirect and @response[:code].to_i>=300 and @response[:code].to_i<400 and @response.include?(:location) then
340
+ if @num_redirects<=30 then
341
+ @num_redirects+=1
342
+ current_server="http"
343
+ current_server+="s" if @ssl==true
344
+ current_server+="://#{@host}"
345
+ location=@response[:location].gsub(current_server, "")
346
+ @logger.info "(#{@num_redirects}) Redirecting NiceHttp to #{location}"
347
+ get(location)
348
+ else
349
+ @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"
350
+ @num_redirects=0
351
+ end
352
+ else
353
+ @num_redirects=0
354
+ end
355
+ return @response
356
+ rescue Exception => stack
357
+ @logger.warn stack
358
+ return :error
359
+ end
360
+
361
+ end
362
+
363
+
364
+ ######################################################
365
+ # Put data to path
366
+ # input:
367
+ # 1 argument
368
+ # Hash containing at least keys :data, :path
369
+ # 3 arguments
370
+ # path (string)
371
+ # data (json data for example)
372
+ # additional_headers (Hash key=>value)
373
+ # output:
374
+ # response -> Hash including at least the symbol keys:
375
+ # :data = the response data body
376
+ # :message = plain text response
377
+ # :code = code response (200=ok,500=wrong...)
378
+ # *All keys in response are lowercase
379
+ # data, message and code can also be accessed as attributes like .message .code .data, for example:
380
+ # resp=@http.put(Requests::Customer.remove_phone)
381
+ # assert resp.code==200
382
+ ######################################################
383
+ def put(*arguments)
384
+ begin
385
+ path, data, headers_t=manage_request(*arguments)
386
+ @start_time = Time.now if @start_time.nil?
387
+ if arguments.size>0 and arguments[0].kind_of?(Hash) then
388
+ arg=arguments[0]
389
+ if @use_mocks and arg.kind_of?(Hash) and arg.keys.include?(:mock_response) then
390
+ data=""
391
+ if arg[:mock_response].keys.include?(:data) then
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.send_request("PUT", path, data, 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.send_request("PUT", path, data, headers_t)
420
+ end
421
+ manage_response(resp, data)
422
+
423
+ return @response
424
+ rescue Exception => stack
425
+ @logger.fatal stack, self
426
+ return :error
427
+ end
428
+
429
+ end
430
+
431
+
432
+ ######################################################
433
+ # Patch data to path
434
+ # input:
435
+ # 1 argument
436
+ # Hash containing at least keys :data, :path
437
+ # 3 arguments
438
+ # path (string)
439
+ # data (json data for example)
440
+ # additional_headers (Hash key=>value)
441
+ # output:
442
+ # response -> Hash including at least the symbol keys:
443
+ # :data = the response data body
444
+ # :message = plain text response
445
+ # :code = code response (200=ok,500=wrong...)
446
+ # *All keys in response are lowercase
447
+ # data, message and code can also be accessed as attributes like .message .code .data, for example:
448
+ # resp=@http.patch(Requests::Customer.unrelease_account)
449
+ # assert resp.code==200
450
+ ######################################################
451
+ def patch(*arguments)
452
+ begin
453
+ path, data, headers_t=manage_request(*arguments)
454
+ @start_time = Time.now if @start_time.nil?
455
+ if arguments.size>0 and arguments[0].kind_of?(Hash) then
456
+ arg=arguments[0]
457
+ if @use_mocks and arg.kind_of?(Hash) and arg.keys.include?(:mock_response) then
458
+ data=""
459
+ if arg[:mock_response].keys.include?(:data) then
460
+ data=arg[:mock_response][:data]
461
+ if data.kind_of?(Hash) #to json
462
+ begin
463
+ require 'json'
464
+ data=data.to_json
465
+ rescue
466
+ @logger.fatal "There was a problem converting to json: #{data}"
467
+ end
468
+ end
469
+ end
470
+ @logger.warn "Pay attention!!! This is a mock response:"
471
+ @start_time_net = Time.now if @start_time_net.nil?
472
+ manage_response(arg[:mock_response], data.to_s)
473
+ return @response
474
+ end
475
+ end
476
+
477
+ begin
478
+ @start_time_net = Time.now if @start_time_net.nil?
479
+ resp=@http.patch(path, data, headers_t)
480
+ data=resp.body
481
+ rescue Exception => stack
482
+ @logger.warn stack
483
+ @logger.warn "The connection seems to be closed in the host machine. Trying to reconnect"
484
+ @http.finish()
485
+ @http.start()
486
+ @start_time_net = Time.now if @start_time_net.nil?
487
+ resp, data=@http.patch(path, data, headers_t)
488
+ end
489
+ manage_response(resp, data)
490
+ if @auto_redirect and @response[:code].to_i>=300 and @response[:code].to_i<400 and @response.include?(:location) then
491
+ if @num_redirects<=30 then
492
+ @num_redirects+=1
493
+ current_server="http"
494
+ current_server+="s" if @ssl==true
495
+ current_server+="://#{@host}"
496
+ location=@response[:location].gsub(current_server, "")
497
+ @logger.info "(#{@num_redirects}) Redirecting NiceHttp to #{location}"
498
+ get(location)
499
+ else
500
+ @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"
501
+ @num_redirects=0
502
+ end
503
+ else
504
+ @num_redirects=0
505
+ end
506
+ return @response
507
+ rescue Exception => stack
508
+ @logger.fatal stack
509
+ return :error
510
+ end
511
+
512
+ end
513
+
514
+
515
+ ######################################################
516
+ # Delete an existing resource
517
+ # input:
518
+ # 1 argument
519
+ # Hash containing at least key :path
520
+ # 1 argument
521
+ # String giving the path
522
+ # output:
523
+ # response -> Hash including at least the symbol keys:
524
+ # :data = the response data body
525
+ # :message = plain text response
526
+ # :code = code response (200=ok,500=wrong...)
527
+ # *All keys in response are lowercase
528
+ # data, message and code can also be accessed as attributes like .message .code .data, for example:
529
+ # resp=@http.delete(Requests::Customer.remove_session)
530
+ # assert resp.code==204
531
+ ######################################################
532
+ def delete(argument)
533
+ begin
534
+ if argument.kind_of?(String) then
535
+ argument={:path => argument}
536
+ end
537
+ path, data, headers_t=manage_request(argument)
538
+ @start_time = Time.now if @start_time.nil?
539
+ if argument.kind_of?(Hash) then
540
+ arg=argument
541
+ if @use_mocks and arg.kind_of?(Hash) and arg.keys.include?(:mock_response) then
542
+ data=""
543
+ if arg[:mock_response].keys.include?(:data) then
544
+ data=arg[:mock_response][:data]
545
+ if data.kind_of?(Hash) #to json
546
+ begin
547
+ require 'json'
548
+ data=data.to_json
549
+ rescue
550
+ @logger.fatal "There was a problem converting to json: #{data}"
551
+ end
552
+ end
553
+ end
554
+ @logger.warn "Pay attention!!! This is a mock response:"
555
+ @start_time_net = Time.now if @start_time_net.nil?
556
+ manage_response(arg[:mock_response], data.to_s)
557
+ return @response
558
+ end
559
+ end
560
+
561
+ begin
562
+ @start_time_net = Time.now if @start_time_net.nil?
563
+ resp=@http.delete(path, headers_t)
564
+ data=resp.body
565
+ rescue Exception => stack
566
+ @logger.warn stack
567
+ @logger.warn "The connection seems to be closed in the host machine. Trying to reconnect"
568
+ @http.finish()
569
+ @http.start()
570
+ @start_time_net = Time.now if @start_time_net.nil?
571
+ resp, data=@http.delete(path)
572
+ end
573
+ manage_response(resp, data)
574
+
575
+ return @response
576
+ rescue Exception => stack
577
+ @logger.fatal stack
578
+ return :error
579
+ end
580
+
581
+ end
582
+
583
+ ######################################################
584
+ # Implementation of the http HEAD method.
585
+ # Asks for the response identical to the one that would correspond to a GET request, but without the response body.
586
+ # This is useful for retrieving meta-information written in response headers, without having to transport the entire content.
587
+ # input:
588
+ # 1 argument
589
+ # Hash containing at least key :path
590
+ # 1 argument
591
+ # String giving the path
592
+ # output:
593
+ # response -> Hash including the symbol keys:
594
+ # :message = plain text response
595
+ # :code = code response (200=ok,500=wrong...)
596
+ # *All keys in response are lowercase
597
+ ######################################################
598
+ def head(argument)
599
+ begin
600
+ if argument.kind_of?(String) then
601
+ argument={:path => argument}
602
+ end
603
+ path, data, headers_t=manage_request(argument)
604
+ @start_time = Time.now if @start_time.nil?
605
+ if argument.kind_of?(Hash) then
606
+ arg=argument
607
+ if @use_mocks and arg.kind_of?(Hash) and arg.keys.include?(:mock_response) then
608
+ data=""
609
+ if arg[:mock_response].keys.include?(:data) then
610
+ data=arg[:mock_response][:data]
611
+ if data.kind_of?(Hash) #to json
612
+ begin
613
+ require 'json'
614
+ data=data.to_json
615
+ rescue
616
+ @logger.fatal "There was a problem converting to json: #{data}"
617
+ end
618
+ end
619
+ end
620
+ @logger.warn "Pay attention!!! This is a mock response:"
621
+ @start_time_net = Time.now if @start_time_net.nil?
622
+ manage_response(arg[:mock_response], data.to_s)
623
+ return @response
624
+ end
625
+ end
626
+
627
+ begin
628
+ @start_time_net = Time.now if @start_time_net.nil?
629
+ resp=@http.head(path, headers_t)
630
+ data=resp.body
631
+ rescue Exception => stack
632
+ @logger.warn stack
633
+ @logger.warn "The connection seems to be closed in the host machine. Trying to reconnect"
634
+ @http.finish()
635
+ @http.start()
636
+ @start_time_net = Time.now if @start_time_net.nil?
637
+ resp, data=@http.head(path)
638
+ end
639
+ manage_response(resp, data)
640
+ return @response
641
+ rescue Exception => stack
642
+ @logger.fatal stack
643
+ return :error
644
+ end
645
+ end
646
+
647
+
648
+ ######################################################
649
+ # Close HTTP connection
650
+ ######################################################
651
+ def close
652
+ begin
653
+ pos=0
654
+ found=false
655
+ NiceHttp.connections.each {|conn|
656
+ if conn.object_id == self.object_id then
657
+ found=true
658
+ break
659
+ end
660
+ pos+=1
661
+ }
662
+ if found
663
+ NiceHttp.connections.delete_at(pos)
664
+ end
665
+
666
+ unless @closed
667
+ if !@http.nil? then
668
+ @http.finish()
669
+ @http=nil
670
+ @logger.info "the HTTP connection was closed: #{@message_server}"
671
+ else
672
+ @http=nil
673
+ @logger.fatal "It was not possible to close the HTTP connection: #{@message_server}"
674
+ end
675
+ @closed=true
676
+ else
677
+ @logger.warn "It was not possible to close the HTTP connection, already closed: #{@message_server}"
678
+ end
679
+ rescue Exception => stack
680
+ @logger.fatal stack
681
+ end
682
+ NiceHttp.active-=1
683
+ end
684
+
685
+
686
+ ######################################################
687
+ # private method to manage Request
688
+ # input:
689
+ # 3 args: path, data, headers
690
+ # 1 arg: Hash containg at least keys :path and :data
691
+ # output:
692
+ # path, data, headers
693
+ ######################################################
694
+ def manage_request(*arguments)
695
+ require 'json'
696
+ begin
697
+ content_type_included=false
698
+ path=""
699
+ data=""
700
+
701
+ @response=Hash.new()
702
+ headers_t=@headers.dup()
703
+ cookies_to_set_str=""
704
+ if arguments.size==3 then
705
+ path=arguments[0]
706
+ elsif arguments.size==1 and arguments[0].kind_of?(Hash) then
707
+ path=arguments[0][:path]
708
+ elsif arguments.size==1 and arguments[0].kind_of?(String) then
709
+ path=arguments[0].to_s()
710
+ end
711
+ @cookies.each {|cookie_path, cookies_hash|
712
+ cookie_path="" if cookie_path=="/"
713
+ path_to_check=path
714
+ if path=="/" or path[-1]!="/" then
715
+ path_to_check+="/"
716
+ end
717
+ if path_to_check.scan(/^#{cookie_path}\//).size>0 then
718
+ cookies_hash.each {|key, value|
719
+ cookies_to_set_str+="#{key}=#{value}; "
720
+ }
721
+ end
722
+ }
723
+ headers_t["Cookie"]=cookies_to_set_str
724
+
725
+ method_s=caller[0].to_s().scan(/:in `(.*)'/).join
726
+
727
+ if arguments.size==3 then
728
+ data=arguments[1]
729
+ if arguments[2].kind_of?(Hash) then
730
+ headers_t.merge!(arguments[2])
731
+ end
732
+ elsif arguments.size==1 and arguments[0].kind_of?(Hash) then
733
+ if arguments[0][:data].nil? then
734
+ if arguments[0].keys.include?(:data) then
735
+ data=""
736
+ elsif arguments[0].keys.include?(:data_examples) and
737
+ arguments[0][:data_examples].kind_of?(Array) then
738
+ data=arguments[0][:data_examples][0] #the first example by default
739
+ else
740
+ data=""
741
+ end
742
+
743
+ else
744
+ data=arguments[0][:data]
745
+ end
746
+ if arguments[0].include?(:headers) then
747
+ headers_t.merge!(arguments[0][:headers])
748
+ end
749
+
750
+ if headers_t["Content-Type"].to_s()=="" and headers_t["content-type"].to_s()=="" and
751
+ headers_t[:"content-type"].to_s()=="" and headers_t[:"Content-Type"].to_s()=="" then
752
+ content_type_included=false
753
+ elsif headers_t["content-type"].to_s()!="" then
754
+ content_type_included=true
755
+ headers_t["Content-Type"]=headers_t["content-type"]
756
+ elsif headers_t[:"content-type"].to_s()!="" then
757
+ content_type_included=true
758
+ headers_t["Content-Type"]=headers_t[:"content-type"]
759
+ headers_t.delete(:"content-type")
760
+ elsif headers_t[:"Content-Type"].to_s()!="" then
761
+ content_type_included=true
762
+ headers_t["Content-Type"]=headers_t[:"Content-Type"]
763
+ headers_t.delete(:"Content-Type")
764
+ elsif headers_t["Content-Type"].to_s()!="" then
765
+ content_type_included=true
766
+ end
767
+
768
+ if !content_type_included and data.kind_of?(Hash)
769
+ headers_t['Content-Type'] = 'application/json'
770
+ content_type_included=true
771
+ end
772
+
773
+ if content_type_included and (!headers_t["Content-Type"][/text\/xml/].nil? or
774
+ !headers_t["Content-Type"]["application/soap+xml"].nil? or
775
+ !headers_t["Content-Type"][/application\/jxml/].nil?) then
776
+ if arguments[0].include?(:values) then
777
+ arguments[0][:values].each {|key, value|
778
+ data=NiceHttpUtils.set_value_xml_tag(key.to_s(), data, value.to_s(), true)
779
+ }
780
+ end
781
+ elsif content_type_included and !headers_t["Content-Type"][/application\/json/].nil? and data.to_s()!="" then
782
+ require 'json'
783
+ if data.kind_of?(String) then
784
+ if arguments[0].include?(:values) then
785
+ arguments[0][:values].each {|key, value|
786
+ data.gsub!(/(( *|^)"?#{key.to_s()}"? *: *")(.*)(" *, *$)/, '\1' + value+ '\4') # "key":"value", or key:"value",
787
+ data.gsub!(/(( *|^)"?#{key.to_s()}"? *: *")(.*)(" *$)/, '\1' + value+ '\4') # "key":"value" or key:"value"
788
+ data.gsub!(/(( *|^)"?#{key.to_s()}"? *: *[^"])([^"].*)([^"] *, *$)/, '\1' + value+ '\4') # "key":456, or key:456,
789
+ data.gsub!(/(( *|^)"?#{key.to_s()}"? *: *[^"])([^"].*)([^"] * *$)/, '\1' + value+ '\4') # "key":456 or key:456
790
+ }
791
+ end
792
+ elsif data.kind_of?(Hash) then
793
+ data_n=Hash.new()
794
+ data.each {|key, value|
795
+ data_n[key.to_s()]=value
796
+ }
797
+ if arguments[0].include?(:values) then
798
+ #req[:values][:loginName] or req[:values]["loginName"]
799
+ new_values_hash=Hash.new()
800
+ arguments[0][:values].each {|kv, vv|
801
+ if data_n.keys.include?(kv.to_s()) then
802
+ new_values_hash[kv.to_s()]=vv
803
+ end
804
+ }
805
+ data_n.merge!(new_values_hash)
806
+ end
807
+ data=data_n.to_json()
808
+ elsif data.kind_of?(Array) then
809
+ data_arr=Array.new()
810
+ data.each_with_index {|row, indx|
811
+ unless row.kind_of?(Hash) then
812
+ @logger.fatal("Wrong format on request application/json, be sure is a Hash, Array of Hashes or JSON string")
813
+ return :error, :error, :error
814
+ end
815
+ data_n=Hash.new()
816
+ row.each {|key, value|
817
+ data_n[key.to_s()]=value
818
+ }
819
+ if arguments[0].include?(:values) then
820
+ #req[:values][:loginName] or req[:values]["loginName"]
821
+ new_values_hash=Hash.new()
822
+ if arguments[0][:values].kind_of?(Hash) then #values[:mykey][3]
823
+ arguments[0][:values].each {|kv, vv|
824
+ if data_n.keys.include?(kv.to_s()) and !vv[indx].nil? then
825
+ new_values_hash[kv.to_s()]=vv[indx]
826
+ end
827
+ }
828
+ elsif arguments[0][:values].kind_of?(Array) then #values[5][:mykey]
829
+ if !arguments[0][:values][indx].nil? then
830
+ arguments[0][:values][indx].each {|kv, vv|
831
+ if data_n.keys.include?(kv.to_s()) then
832
+ new_values_hash[kv.to_s()]=vv
833
+ end
834
+ }
835
+ end
836
+ else
837
+ @logger.fatal("Wrong format on request application/json when supplying values, the data is an array of Hashes but the values supplied are not")
838
+ return :error, :error, :error
839
+ end
840
+ data_n.merge!(new_values_hash)
841
+ end
842
+ data_arr.push(data_n)
843
+ }
844
+ data=data_arr.to_json()
845
+ else
846
+ @logger.fatal("Wrong format on request application/json, be sure is a Hash, Array of Hashes or JSON string")
847
+ return :error, :error, :error
848
+ end
849
+ elsif content_type_included and arguments[0].include?(:values) then
850
+ if arguments[0][:values].kind_of?(Hash) and arguments[0][:values].keys.size>0 then
851
+ 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
852
+ @logger.warn(":values key given without a valid content-type or data for request. No values modified on the request")
853
+ end
854
+ end
855
+ end
856
+ elsif arguments.size==1 and arguments[0].kind_of?(String) then
857
+ #path=arguments[0].to_s()
858
+ data=""
859
+ else
860
+ @logger.fatal("Invalid number of arguments or wrong arguments in #{method_s}")
861
+ return :error, :error, :error
862
+ end
863
+ 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
864
+ encoding="UTF-8"
865
+ data_s=""
866
+ else
867
+ encoding=data.to_s().scan(/encoding='(.*)'/i).join
868
+ if encoding.to_s()=="" then
869
+ encoding=data.to_s().scan(/charset='(.*)'/i).join
870
+ end
871
+ if encoding.to_s()=="" and headers_t.include?("Content-Type") then
872
+ encoding=headers_t["Content-Type"].scan(/charset='?(.*)'?/i).join
873
+ if encoding.to_s()=="" then
874
+ encoding=headers_t["Content-Type"].scan(/encoding='?(.*)'?/i).join
875
+ end
876
+ end
877
+
878
+ begin
879
+ data_s=JSON.pretty_generate(JSON.parse(data))
880
+ rescue
881
+ data_s=data
882
+ end
883
+ data_s=data_s.to_s().gsub("<", "&lt;")
884
+ end
885
+ if headers_t.keys.include?("Accept-Encoding")
886
+ headers_t["Accept-Encoding"].gsub!("gzip","")#removed so the response is in plain text
887
+ end
888
+
889
+ headers_ts=""
890
+ headers_t.each {|key, val| headers_ts+=key.to_s + ":" + val.to_s() + ", "}
891
+ message="#{method_s} REQUEST: \npath= " + path.to_s() + "\n"
892
+ message+="headers= " + headers_ts.to_s() + "\n"
893
+ message+="data= " + data_s.to_s() + "\n"
894
+ message=@message_server+"\n"+message
895
+ if path.to_s().scan(/^https?:\/\//).size>0 and path.to_s().scan(/^https?:\/\/#{@host}/).size==0 then
896
+ # the path is for another server than the current
897
+ else
898
+ NiceHttp.last_request=message
899
+ @logger.info(message)
900
+ end
901
+
902
+ if data.to_s()!="" and encoding.to_s().upcase!="UTF-8" and encoding!="" then
903
+ data=data.to_s().encode(encoding, "UTF-8")
904
+ end
905
+ return path, data, headers_t
906
+ rescue Exception => stack
907
+ @logger.fatal(stack)
908
+ @logger.fatal("manage_request Error on method #{method_s} . path:#{path.to_s()}. data:#{data.to_s()}. headers:#{headers_t.to_s()}")
909
+ return :error
910
+ end
911
+ end
912
+
913
+ ######################################################
914
+ # private method to manage Response
915
+ # input:
916
+ # resp
917
+ # data
918
+ # output:
919
+ # @response updated
920
+ ######################################################
921
+ def manage_response(resp, data)
922
+ require 'json'
923
+ begin
924
+ if @start_time.kind_of?(Time)
925
+ @response[:time_elapsed_total]=Time.now-@start_time
926
+ @start_time = nil
927
+ else
928
+ @response[:time_elapsed_total]=nil
929
+ end
930
+ if @start_time_net.kind_of?(Time)
931
+ @response[:time_elapsed]=Time.now-@start_time_net
932
+ @start_time_net = nil
933
+ else
934
+ @response[:time_elapsed]=nil
935
+ end
936
+ begin
937
+ # this is to be able to access all keys as symbols
938
+ new_resp=Hash.new()
939
+ resp.each {|key, value|
940
+ if key.kind_of?(String) then
941
+ new_resp[key.to_sym]=value
942
+ end
943
+ }
944
+ new_resp.each {|key, value|
945
+ resp[key]=value
946
+ }
947
+ rescue
948
+ end
949
+ #for mock_responses to be able to add outside of the header like content-type for example
950
+ if resp.kind_of?(Hash) and !resp.has_key?(:header) then
951
+ resp[:header]={}
952
+ end
953
+ if resp.kind_of?(Hash)
954
+ resp.each {|k, v|
955
+ if k!=:code and k!=:message and k!=:data and k!=:'set-cookie' and k!=:header
956
+ resp[:header][k]=v
957
+ end
958
+ }
959
+ resp[:header].each {|k, v|
960
+ resp.delete(k) if resp.has_key?(k)
961
+ }
962
+ end
963
+
964
+ method_s=caller[0].to_s().scan(/:in `(.*)'/).join
965
+ 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
966
+ data=Zlib::Inflate.inflate(data)
967
+ end
968
+ encoding_response=""
969
+ if resp.header.kind_of?(Hash) and (resp.header["content-type"].to_s()!="" or resp.header[:"content-type"].to_s()!="") then
970
+ encoding_response=resp.header["content-type"].scan(/;charset=(.*)/i).join if resp.header.has_key?("content-type")
971
+ encoding_response=resp.header[:"content-type"].scan(/;charset=(.*)/i).join if resp.header.has_key?(:"content-type")
972
+ end
973
+ if encoding_response.to_s()=="" then
974
+ encoding_response="UTF-8"
975
+ end
976
+
977
+ if encoding_response.to_s()!="" and encoding_response.to_s().upcase!="UTF-8" then
978
+ data.encode!("UTF-8", encoding_response.to_s())
979
+ end
980
+ if encoding_response!="" and encoding_response.to_s().upcase!="UTF-8" then
981
+ @response[:message]=resp.message.to_s().encode("UTF-8", encoding_response.to_s())
982
+ #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...)
983
+ resp.each {|key, val| @response[key]=val.to_s().encode("UTF-8", encoding_response.to_s())}
984
+ else
985
+ @response[:message]=resp.message
986
+ resp.each {|key, val| @response[key]=val}
987
+ end
988
+ if !defined?(Net::HTTP::Post::Multipart) or (defined?(Net::HTTP::Post::Multipart) and !data.kind_of?(Net::HTTP::Post::Multipart))
989
+ @response[:data]=data
990
+ else
991
+ @response[:data]=""
992
+ end
993
+
994
+ @response[:code]=resp.code
995
+
996
+ unless @response.nil? then
997
+ message="\nRESPONSE: \n" + @response[:code].to_s()+ ":" + @response[:message].to_s()
998
+ if @debug then
999
+ NiceHttp.last_response=message
1000
+ @response.each {|key, value|
1001
+ if value.to_s()!="" then
1002
+ value_orig=value
1003
+ if key.kind_of?(Symbol) then
1004
+ if key==:code or key==:data or key==:header or key==:message then
1005
+ if key==:data then
1006
+ begin
1007
+ JSON.parse(value_orig)
1008
+ data_s=JSON.pretty_generate(JSON.parse(value_orig))
1009
+ rescue
1010
+ data_s=value_orig
1011
+ end
1012
+ NiceHttp.last_response+="\nresponse." + key.to_s() + " = '" + data_s.gsub("<", "&lt;") + "'\n"
1013
+ if value_orig != value then
1014
+ message+="\nresponse." + key.to_s() + " = '" + value.gsub("<", "&lt;") + "'\n"
1015
+ else
1016
+ message+="\nresponse." + key.to_s() + " = '" + data_s.gsub("<", "&lt;") + "'\n"
1017
+ end
1018
+ else
1019
+ NiceHttp.last_response+="\nresponse." + key.to_s() + " = '" + value.to_s().gsub("<", "&lt;") + "'"
1020
+ message+="\nresponse." + key.to_s() + " = '" + value.to_s().gsub("<", "&lt;") + "'"
1021
+ end
1022
+ else
1023
+ NiceHttp.last_response+="\nresponse[:" + key.to_s() + "] = '" + value.to_s().gsub("<", "&lt;") + "'"
1024
+ message+="\nresponse[:" + key.to_s() + "] = '" + value.to_s().gsub("<", "&lt;") + "'"
1025
+ end
1026
+ elsif !@response.include?(key.to_sym)
1027
+ NiceHttp.last_response+="\nresponse['" + key.to_s() + "'] = '" + value.to_s().gsub("<", "&lt;") + "'"
1028
+ message+="\nresponse['" + key.to_s() + "'] = '" + value.to_s().gsub("<", "&lt;") + "'"
1029
+ end
1030
+ end
1031
+ }
1032
+
1033
+ end
1034
+ @logger.info message
1035
+ if @response.kind_of?(Hash) then
1036
+ if @response.keys.include?(:requestid) then
1037
+ @headers["requestId"]=@response[:requestid]
1038
+ NiceHttp.request_id=@response[:requestid]
1039
+ @logger.info "requestId was found on the response header and it has been added to the headers for the next request"
1040
+ end
1041
+ end
1042
+ end
1043
+
1044
+ if resp[:'set-cookie'].to_s()!="" then
1045
+ if resp.kind_of?(Hash) then #mock_response
1046
+ cookies_to_set=resp[:'set-cookie'].to_s().split(", ")
1047
+ else #Net::Http
1048
+ cookies_to_set=resp.get_fields('set-cookie')
1049
+ end
1050
+ cookies_to_set.each {|cookie|
1051
+ cookie_pair=cookie.split('; ')[0].split("=")
1052
+ cookie_path=cookie.scan(/; path=([^;]+)/i).join
1053
+ @cookies[cookie_path]=Hash.new() unless @cookies.keys.include?(cookie_path)
1054
+ @cookies[cookie_path][cookie_pair[0]]=cookie_pair[1]
1055
+ }
1056
+
1057
+ @logger.info "set-cookie added to Cookie header as required"
1058
+
1059
+ if @headers.has_key?("X-CSRFToken") then
1060
+ csrftoken=resp[:"set-cookie"].to_s().scan(/csrftoken=([\da-z]+);/).join
1061
+ if csrftoken.to_s()!="" then
1062
+ @headers["X-CSRFToken"]=csrftoken
1063
+ @logger.info "X-CSRFToken exists on headers and has been overwritten"
1064
+ end
1065
+ else
1066
+ csrftoken=resp[:"set-cookie"].to_s().scan(/csrftoken=([\da-z]+);/).join
1067
+ if csrftoken.to_s()!="" then
1068
+ @headers["X-CSRFToken"]=csrftoken
1069
+ @logger.info "X-CSRFToken added to header as required"
1070
+ end
1071
+
1072
+ end
1073
+ end
1074
+
1075
+ rescue Exception => stack
1076
+ @logger.fatal stack
1077
+ @logger.fatal "manage_response Error on method #{method_s} "
1078
+ end
1079
+ end
1080
+
1081
+ private :manage_request, :manage_response
1082
+ end
1083
+