nice_http 1.8.10 → 1.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: df4f8b1cf983332827d337db8371accf6d74e5ee33f0b9e226ba42c99ab8214c
4
- data.tar.gz: 1c69869b4508a7b70972b010673c28f18301765da25b209e00024bcaab8c2f1d
3
+ metadata.gz: 05ea4d762f4ce03ab7f89c6ca4aafd323c549c73f686f349dac356e43918ffa5
4
+ data.tar.gz: a9f1c491dabcd6e559f9454a10a7caeeddea4aac915d10be0548d5465fe1a256
5
5
  SHA512:
6
- metadata.gz: 46eb5827fee9728f51deb59a2fa5354427da8effb4cdc61e35e0ad71291bef5fa0ad002f2296ab1921b72c4d102384a7518754d35e7da44391c5df39818fa226
7
- data.tar.gz: 80a9201476a08a6f0c7a5bc97032c468032a4751a3d768665eddf9dbcbc21fd270942813ad8a53240178036afbf29d9bbaeea4e78c752bfa420c85370921d6eb
6
+ metadata.gz: 5744a1f61ef6835e7dca5fffa15617e7ecd842b28f4cdb7019f1583e95483d841ccdee5d07506d2e7d9d6b8e5ba6dc986e5425f89b20b91abec9ebfab555917c
7
+ data.tar.gz: f33f3d76090238a2f9b483a2791b295a908355072586d418f185c8326c3096700f3f89f5e477eb3e0191d256fd824ced3974d5ec628b34aba3ce0bd99179fa63
data/README.md CHANGED
@@ -27,6 +27,7 @@ Example that creates 1000 good random and unique requests to register an user an
27
27
  - [Create a connection](#Create-a-connection)
28
28
  - [Creating requests](#Creating-requests)
29
29
  - [Responses](#Responses)
30
+ - [Async Responses](#Async-Responses)
30
31
  - [Special settings](#Special-settings)
31
32
  - [Authentication requests](#Authentication-requests)
32
33
  - [Basic Authentication](#Basic-Authentication)
@@ -259,7 +260,18 @@ NiceHttp.requests = {
259
260
  }
260
261
  ```
261
262
 
262
- You can use `NiceHttp.requests` to specify certain `headers` or `data` that will apply on all requests sent.
263
+ You can use `NiceHttp.requests` to specify certain `headers`, `path` parameters or `data` that will apply on all requests sent.
264
+ ```ruby
265
+ NiceHttp.requests = {
266
+ path: 'api-version=2022-12-09&testing=true',
267
+ data: {
268
+ properties: {
269
+ language: 'eng-us'
270
+ }
271
+ }
272
+ }
273
+ ```
274
+
263
275
 
264
276
  ## Responses
265
277
 
@@ -271,7 +283,45 @@ The response will include at least the keys:
271
283
 
272
284
  *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)`
273
285
 
274
- Also interesting keys would be: *time_elapsed_total*, *time_elapsed* and many more available
286
+ Also interesting keys would be: *time_elapsed_total*, *time_elapsed* and many more available
287
+
288
+ ### Async responses
289
+
290
+ In case a 202 response and set the async settings, it will wait until the operation finishes and will return the result:
291
+
292
+ ```ruby
293
+ NiceHttp.async_wait_seconds = 10
294
+ NiceHttp.async_header = 'location'
295
+ NiceHttp.async_completed = 'percComplete'
296
+ NiceHttp.async_resource = 'resourceName'
297
+ NiceHttp.async_status = 'status'
298
+
299
+ http = NiceHttp.new('https://exampleSinatra.tcblues.repl.co')
300
+
301
+ response = http.get '/async'
302
+ pp response # =>
303
+ { :code=>"202",
304
+ :message=>"Accepted",
305
+ :location=>"https://exampleSinatra.tcblues.repl.co/operation/667",
306
+ :data=>"{\"result\":\"this is an async operation id: 667\"}",
307
+ :async=>
308
+ { :seconds=>4,
309
+ :data=>
310
+ "{'percComplete':100,'resourceName':'/resource/766','status':'Done','operationId':'667'}",
311
+ :status=>"Done",
312
+ :resource=>{:data=>"{'resourceId':'766','lolo':'lala'}"}
313
+ }
314
+ # plus other keys
315
+ }
316
+
317
+ p response.code # 202
318
+ p response.location # "https://exampleSinatra.tcblues.repl.co/operation/667"
319
+ p response.data.json # {:result=>"this is an async operation id: 667"}
320
+ p response.async.data.json # {:percComplete=>100, :resourceName=>"/resource/766", :status=>"Done",:operationId=>667}
321
+ p response.async.status # Done
322
+ p response.async.seconds # 4
323
+ p response.async.resource.data.json # {:resourceId=>"766", :lolo=>"lala"}
324
+ ```
275
325
 
276
326
 
277
327
  ## Special settings
@@ -734,7 +784,7 @@ Example posting a csv file:
734
784
 
735
785
  Bug reports are very welcome on GitHub at https://github.com/marioruiz/nice_http.
736
786
 
737
- If you want to contribute please follow [GitHub Flow](https://guides.github.com/introduction/flow/index.html)
787
+ If you want to contribute please follow [GitHub Flow](https://docs.github.com/en/get-started/quickstart/github-flow)
738
788
 
739
789
  ## License
740
790
 
@@ -0,0 +1,85 @@
1
+ class NiceHttp
2
+ ######################################################
3
+ # To add specific stats
4
+ # The stats will be added to NiceHttp.stats[:specific]
5
+ #
6
+ # @param name [Symbol] name to group your specific stats
7
+ # @param state [Symbol] state of the name supplied to group your specific stats
8
+ # @param started [Time] when the process you want the stats started
9
+ # @param finished [Time] when the process you want the stats finished
10
+ # @param item [Object] (Optional) The item to be added to :items key to store all items in an array
11
+ #
12
+ # @example
13
+ # started = Time.now
14
+ # @http.send_request Requests::Customer.add_customer
15
+ # 30.times do
16
+ # resp = @http.get(Requests::Customer.get_customer)
17
+ # break if resp.code == 200
18
+ # sleep 0.5
19
+ # end
20
+ # NiceHttp.add_stats(:customer, :create, started, Time.now)
21
+ ######################################################
22
+ def self.add_stats(name, state, started, finished, item = nil)
23
+ self.stats[:specific] ||= {}
24
+ self.stats[:specific][name] ||= { num: 0, started: started, finished: started, real_time_elapsed: 0, time_elapsed: { total: 0, maximum: 0, minimum: 100000, average: 0 } }
25
+ self.stats[:specific][name][:num] += 1
26
+
27
+ if started < self.stats[:specific][name][:finished]
28
+ self.stats[:specific][name][:real_time_elapsed] += (finished - self.stats[:specific][name][:finished])
29
+ else
30
+ self.stats[:specific][name][:real_time_elapsed] += (finished - started)
31
+ end
32
+ self.stats[:specific][name][:finished] = finished
33
+
34
+ time_elapsed = self.stats[:specific][name][:time_elapsed]
35
+ time_elapsed[:total] += finished - started
36
+ if time_elapsed[:maximum] < (finished - started)
37
+ time_elapsed[:maximum] = (finished - started)
38
+ if !item.nil?
39
+ time_elapsed[:item_maximum] = item
40
+ elsif Thread.current.name.to_s != ""
41
+ time_elapsed[:item_maximum] = Thread.current.name
42
+ end
43
+ end
44
+ if time_elapsed[:minimum] > (finished - started)
45
+ time_elapsed[:minimum] = (finished - started)
46
+ if !item.nil?
47
+ time_elapsed[:item_minimum] = item
48
+ elsif Thread.current.name.to_s != ""
49
+ time_elapsed[:item_minimum] = Thread.current.name
50
+ end
51
+ end
52
+ time_elapsed[:average] = time_elapsed[:total] / self.stats[:specific][name][:num]
53
+
54
+ self.stats[:specific][name][state] ||= { num: 0, started: started, finished: started, real_time_elapsed: 0, time_elapsed: { total: 0, maximum: 0, minimum: 1000, average: 0 }, items: [] }
55
+ self.stats[:specific][name][state][:num] += 1
56
+ if started < self.stats[:specific][name][state][:finished]
57
+ self.stats[:specific][name][state][:real_time_elapsed] += (finished - self.stats[:specific][name][state][:finished])
58
+ else
59
+ self.stats[:specific][name][state][:real_time_elapsed] += (finished - started)
60
+ end
61
+
62
+ self.stats[:specific][name][state][:finished] = finished
63
+
64
+ self.stats[:specific][name][state][:items] << item unless item.nil? or self.stats[:specific][name][state][:items].include?(item)
65
+ time_elapsed = self.stats[:specific][name][state][:time_elapsed]
66
+ time_elapsed[:total] += finished - started
67
+ if time_elapsed[:maximum] < (finished - started)
68
+ time_elapsed[:maximum] = (finished - started)
69
+ if !item.nil?
70
+ time_elapsed[:item_maximum] = item
71
+ elsif Thread.current.name.to_s != ""
72
+ time_elapsed[:item_maximum] = Thread.current.name
73
+ end
74
+ end
75
+ if time_elapsed[:minimum] > (finished - started)
76
+ time_elapsed[:minimum] = (finished - started)
77
+ if !item.nil?
78
+ time_elapsed[:item_minimum] = item
79
+ elsif Thread.current.name.to_s != ""
80
+ time_elapsed[:item_minimum] = Thread.current.name
81
+ end
82
+ end
83
+ time_elapsed[:average] = time_elapsed[:total] / self.stats[:specific][name][state][:num]
84
+ end
85
+ end
@@ -0,0 +1,39 @@
1
+ class NiceHttp
2
+ ######################################################
3
+ # Close HTTP connection
4
+ ######################################################
5
+ def close
6
+ begin
7
+ pos = 0
8
+ found = false
9
+ self.class.connections.each { |conn|
10
+ if conn.object_id == self.object_id
11
+ found = true
12
+ break
13
+ else
14
+ pos += 1
15
+ end
16
+ }
17
+ if found
18
+ self.class.connections.delete_at(pos)
19
+ end
20
+
21
+ unless @closed
22
+ if !@http.nil?
23
+ @http.finish()
24
+ @http = nil
25
+ @logger.info "the HTTP connection was closed: #{@message_server}"
26
+ else
27
+ @http = nil
28
+ @logger.fatal "It was not possible to close the HTTP connection: #{@message_server}"
29
+ end
30
+ @closed = true
31
+ else
32
+ @logger.warn "It was not possible to close the HTTP connection, already closed: #{@message_server}"
33
+ end
34
+ rescue Exception => stack
35
+ @logger.fatal stack
36
+ end
37
+ self.class.active -= 1
38
+ end
39
+ end
@@ -0,0 +1,30 @@
1
+ class NiceHttp
2
+ ######################################################
3
+ # Change the default values for NiceHttp supplying a Hash
4
+ #
5
+ # @param par [Hash] keys: :host, :port, :ssl, :timeout, :headers, :debug, :log, :log_path, :proxy_host, :proxy_port, :use_mocks, :auto_redirect, :values_for, :create_stats, :log_headers, :capture, :async_wait_seconds, :async_header, :async_completed, :async_resource, :async_status
6
+ ######################################################
7
+ def self.defaults=(par = {})
8
+ @host = par[:host] if par.key?(:host)
9
+ @port = par[:port] if par.key?(:port)
10
+ @ssl = par[:ssl] if par.key?(:ssl)
11
+ @timeout = par[:timeout] if par.key?(:timeout)
12
+ @headers = par[:headers].dup if par.key?(:headers)
13
+ @values_for = par[:values_for].dup if par.key?(:values_for)
14
+ @debug = par[:debug] if par.key?(:debug)
15
+ @log_path = par[:log_path] if par.key?(:log_path)
16
+ @log = par[:log] if par.key?(:log)
17
+ @log_headers = par[:log_headers] if par.key?(:log_headers)
18
+ @proxy_host = par[:proxy_host] if par.key?(:proxy_host)
19
+ @proxy_port = par[:proxy_port] if par.key?(:proxy_port)
20
+ @use_mocks = par[:use_mocks] if par.key?(:use_mocks)
21
+ @auto_redirect = par[:auto_redirect] if par.key?(:auto_redirect)
22
+ @create_stats = par[:create_stats] if par.key?(:create_stats)
23
+ @capture = par[:capture] if par.key?(:capture)
24
+ @async_wait_seconds = par[:async_wait_seconds] if par.key?(:async_wait_seconds)
25
+ @async_header = par[:async_header] if par.key?(:async_header)
26
+ @async_completed = par[:async_completed] if par.key?(:async_completed)
27
+ @async_resource = par[:async_resource] if par.key?(:async_resource)
28
+ @async_status = par[:async_status] if par.key?(:async_status)
29
+ end
30
+ end
@@ -0,0 +1,8 @@
1
+ class NiceHttp
2
+ ######################################################
3
+ # If inheriting from NiceHttp class
4
+ ######################################################
5
+ def self.inherited(subclass)
6
+ subclass.reset!
7
+ end
8
+ end
@@ -0,0 +1,253 @@
1
+ class NiceHttp
2
+ ######################################################
3
+ # Creates a new http connection.
4
+ #
5
+ # @param args [] If no parameter supplied, by default will access how is setup on defaults
6
+ # @example
7
+ # http = NiceHttp.new()
8
+ # @param args [String]. The url to create the connection.
9
+ # @example
10
+ # http = NiceHttp.new("https://www.example.com")
11
+ # @example
12
+ # http = NiceHttp.new("example.com:8999")
13
+ # @example
14
+ # http = NiceHttp.new("localhost:8322")
15
+ # @param args [Hash] containing these possible keys:
16
+ # host -- example.com. (default blank screen)
17
+ # port -- port for the connection. 80 (default)
18
+ # ssl -- true, false (default)
19
+ # timeout -- integer or nil (default)
20
+ # headers -- hash with the headers
21
+ # values_for -- hash with the values_for
22
+ # debug -- true, false (default)
23
+ # log_path -- string with path for the logs, empty string (default)
24
+ # log -- :no, :screen, :file, :fix_file (default).
25
+ # log_headers -- :all, :none, :partial (default).
26
+ # A string with a path can be supplied.
27
+ # If :fix_file: nice_http.log
28
+ # In case :file it will be generated a log file with name: nice_http_YY-mm-dd-HHMMSS.log
29
+ # proxy_host
30
+ # proxy_port
31
+ # async_wait_seconds -- integer (default 0)
32
+ # async_header -- string (default 'location')
33
+ # async_completed -- string (default empty string)
34
+ # async_resource -- string (default empty string)
35
+ # async_status -- string (default empty string)
36
+ # @example
37
+ # http2 = NiceHttp.new( host: "reqres.in", port: 443, ssl: true )
38
+ # @example
39
+ # my_server = {host: "example.com",
40
+ # port: 80,
41
+ # headers: {"api-key": "zdDDdjkck"}
42
+ # }
43
+ # http3 = NiceHttp.new my_server
44
+ ######################################################
45
+ def initialize(args = {})
46
+ require "net/http"
47
+ require "net/https"
48
+ @host = self.class.host
49
+ @port = self.class.port
50
+ @prepath = ""
51
+ @ssl = self.class.ssl
52
+ @timeout = self.class.timeout
53
+ @headers = self.class.headers.dup
54
+ @values_for = self.class.values_for.dup
55
+ @debug = self.class.debug
56
+ @log = self.class.log
57
+ @log_path = self.class.log_path
58
+ @log_headers = self.class.log_headers
59
+ @proxy_host = self.class.proxy_host
60
+ @proxy_port = self.class.proxy_port
61
+ @use_mocks = self.class.use_mocks
62
+ @auto_redirect = false #set it up at the end of initialize
63
+ auto_redirect = self.class.auto_redirect
64
+ @num_redirects = 0
65
+ @create_stats = self.class.create_stats
66
+ @capture = self.class.capture
67
+ @async_wait_seconds = self.class.async_wait_seconds
68
+ @async_header = self.class.async_header
69
+ @async_completed = self.class.async_completed
70
+ @async_resource = self.class.async_resource
71
+ @async_status = self.class.async_status
72
+
73
+ #todo: set only the cookies for the current domain
74
+ #key: path, value: hash with key is the name of the cookie and value the value
75
+ # we set the default value for non existing keys to empty Hash {} so in case of merge there is no problem
76
+ @cookies = Hash.new { |h, k| h[k] = {} }
77
+
78
+ if args.is_a?(String) # 'http://www.example.com'
79
+ uri = URI.parse(args)
80
+ @host = uri.host unless uri.host.nil?
81
+ @port = uri.port unless uri.port.nil?
82
+ @ssl = true if !uri.scheme.nil? && (uri.scheme == "https")
83
+ @prepath = uri.path unless uri.path == "/"
84
+ elsif args.is_a?(Hash) && !args.keys.empty?
85
+ @host = args[:host] if args.keys.include?(:host)
86
+ @port = args[:port] if args.keys.include?(:port)
87
+ @ssl = args[:ssl] if args.keys.include?(:ssl)
88
+ @timeout = args[:timeout] if args.keys.include?(:timeout)
89
+ @headers = args[:headers].dup if args.keys.include?(:headers)
90
+ @values_for = args[:values_for].dup if args.keys.include?(:values_for)
91
+ @debug = args[:debug] if args.keys.include?(:debug)
92
+ @log = args[:log] if args.keys.include?(:log)
93
+ @log_path = args[:log_path] if args.keys.include?(:log_path)
94
+ @log_headers = args[:log_headers] if args.keys.include?(:log_headers)
95
+ @proxy_host = args[:proxy_host] if args.keys.include?(:proxy_host)
96
+ @proxy_port = args[:proxy_port] if args.keys.include?(:proxy_port)
97
+ @use_mocks = args[:use_mocks] if args.keys.include?(:use_mocks)
98
+ auto_redirect = args[:auto_redirect] if args.keys.include?(:auto_redirect)
99
+ @async_wait_seconds = args[:async_wait_seconds] if args.keys.include?(:async_wait_seconds)
100
+ @async_header = args[:async_header] if args.keys.include?(:async_header)
101
+ @async_completed = args[:async_completed] if args.keys.include?(:async_completed)
102
+ @async_resource = args[:async_resource] if args.keys.include?(:async_resource)
103
+ @async_status = args[:async_status] if args.keys.include?(:async_status)
104
+ end
105
+
106
+ log_filename = ""
107
+ if @log.kind_of?(String) or @log == :fix_file or @log == :file or @log == :file_run
108
+ if @log.kind_of?(String)
109
+ log_filename = @log.dup
110
+ unless log_filename.start_with?(".")
111
+ if caller.first.start_with?(Dir.pwd)
112
+ folder = File.dirname(caller.first.scan(/(.+):\d/).join)
113
+ else
114
+ folder = File.dirname("#{Dir.pwd}/#{caller.first.scan(/(.+):\d/).join}")
115
+ end
116
+ folder += "/" unless log_filename.start_with?("/") or log_filename.match?(/^\w+:/)
117
+ log_filename = folder + log_filename
118
+ end
119
+ require "fileutils"
120
+ FileUtils.mkdir_p File.dirname(log_filename)
121
+ unless Dir.exist?(File.dirname(log_filename))
122
+ @logger = Logger.new nil
123
+ raise InfoMissing, :log, "Wrong directory specified for logs.\n"
124
+ end
125
+ elsif @log == :fix_file
126
+ log_filename = "nice_http.log"
127
+ elsif @log == :file
128
+ log_filename = "nice_http_#{Time.now.strftime("%Y-%m-%d-%H%M%S")}.log"
129
+ elsif @log == :file_run
130
+ log_filename = "#{caller.first.scan(/(.+):\d/).join}.log"
131
+ end
132
+ if Thread.current.name.to_s != ""
133
+ log_filename.gsub!(/\.log$/, "_#{Thread.current.name}.log")
134
+ end
135
+ unless @log_path.to_s == ""
136
+ log_filename.gsub!(Dir.pwd, ".")
137
+ dpath = @log_path.split("/")
138
+ dfile = log_filename.split("/")
139
+ log_filenamepath = ""
140
+ dfile.each_with_index do |d, i|
141
+ if d == dpath[i]
142
+ log_filenamepath << "#{d}/"
143
+ else
144
+ log_filename = @log_path + "#{log_filename.gsub(/^#{log_filenamepath}/, "")}"
145
+ break
146
+ end
147
+ end
148
+ log_filename = "./#{log_filename}" unless log_filename[0..1] == "./"
149
+ log_filename = ".#{log_filename}" unless log_filename[0] == "."
150
+
151
+ unless File.exist?(log_filename)
152
+ require "fileutils"
153
+ FileUtils.mkdir_p(File.dirname(log_filename))
154
+ end
155
+ end
156
+
157
+ if self.class.log_files.key?(log_filename) and File.exist?(log_filename)
158
+ @logger = self.class.log_files[log_filename]
159
+ else
160
+ begin
161
+ f = File.new(log_filename, "w")
162
+ f.sync = true
163
+ @logger = Logger.new f
164
+ rescue Exception => stack
165
+ @logger = Logger.new nil
166
+ raise InfoMissing, :log
167
+ end
168
+ self.class.log_files[log_filename] = @logger
169
+ end
170
+ elsif @log == :screen
171
+ @logger = Logger.new STDOUT
172
+ elsif @log == :no
173
+ @logger = Logger.new nil
174
+ else
175
+ raise InfoMissing, :log
176
+ end
177
+ @logger.level = Logger::INFO
178
+
179
+ if @host.to_s != "" and (@host.start_with?("http:") or @host.start_with?("https:"))
180
+ uri = URI.parse(@host)
181
+ @host = uri.host unless uri.host.nil?
182
+ @port = uri.port unless uri.port.nil?
183
+ @ssl = true if !uri.scheme.nil? && (uri.scheme == "https")
184
+ @prepath = uri.path unless uri.path == "/"
185
+ end
186
+ raise InfoMissing, :port if @port.to_s == ""
187
+ raise InfoMissing, :host if @host.to_s == ""
188
+ raise InfoMissing, :ssl unless @ssl.is_a?(TrueClass) or @ssl.is_a?(FalseClass)
189
+ raise InfoMissing, :timeout unless @timeout.is_a?(Integer) or @timeout.nil?
190
+ raise InfoMissing, :debug unless @debug.is_a?(TrueClass) or @debug.is_a?(FalseClass)
191
+ raise InfoMissing, :auto_redirect unless auto_redirect.is_a?(TrueClass) or auto_redirect.is_a?(FalseClass)
192
+ raise InfoMissing, :use_mocks unless @use_mocks.is_a?(TrueClass) or @use_mocks.is_a?(FalseClass)
193
+ raise InfoMissing, :headers unless @headers.is_a?(Hash)
194
+ raise InfoMissing, :values_for unless @values_for.is_a?(Hash)
195
+ raise InfoMissing, :log_headers unless [:all, :none, :partial].include?(@log_headers)
196
+ raise InfoMissing, :async_wait_seconds unless @async_wait_seconds.is_a?(Integer) or @async_wait_seconds.nil?
197
+ raise InfoMissing, :async_header unless @async_header.is_a?(String) or @async_header.nil?
198
+ raise InfoMissing, :async_completed unless @async_completed.is_a?(String) or @async_completed.nil?
199
+ raise InfoMissing, :async_resource unless @async_resource.is_a?(String) or @async_resource.nil?
200
+ raise InfoMissing, :async_status unless @async_status.is_a?(String) or @async_status.nil?
201
+
202
+ begin
203
+ if !@proxy_host.nil? && !@proxy_port.nil?
204
+ @http = Net::HTTP::Proxy(@proxy_host, @proxy_port).new(@host, @port)
205
+ @http.use_ssl = @ssl
206
+ @http.set_debug_output $stderr if @debug
207
+ @http.verify_mode = OpenSSL::SSL::VERIFY_NONE
208
+ unless @timeout.nil?
209
+ @http.open_timeout = @timeout
210
+ @http.read_timeout = @timeout
211
+ end
212
+ @http.start
213
+ else
214
+ @http = Net::HTTP.new(@host, @port)
215
+ @http.use_ssl = @ssl
216
+ @http.set_debug_output $stderr if @debug
217
+ @http.verify_mode = OpenSSL::SSL::VERIFY_NONE
218
+ unless @timeout.nil?
219
+ @http.open_timeout = @timeout
220
+ @http.read_timeout = @timeout
221
+ end
222
+ @http.start
223
+ end
224
+
225
+ @message_server = "(#{self.object_id}):"
226
+
227
+ log_message = "(#{self.object_id}): Http connection created. host:#{@host}, port:#{@port}, ssl:#{@ssl}, timeout:#{@timeout}, mode:#{@mode}, proxy_host: #{@proxy_host.to_s()}, proxy_port: #{@proxy_port.to_s()} "
228
+
229
+ @logger.info(log_message)
230
+ @message_server += " Http connection: "
231
+ if @ssl
232
+ @message_server += "https://"
233
+ else
234
+ @message_server += "http://"
235
+ end
236
+ @message_server += "#{@host}:#{@port}"
237
+ if @proxy_host.to_s != ""
238
+ @message_server += " proxy:#{@proxy_host}:#{@proxy_port}"
239
+ end
240
+ @auto_redirect = auto_redirect
241
+ # for the case we have headers following nice_hash implementation
242
+ @headers_orig = @headers.dup
243
+ @headers = @headers.generate
244
+
245
+ self.class.active += 1
246
+ self.class.connections.push(self)
247
+ rescue Exception => stack
248
+ puts stack
249
+ @logger.fatal stack
250
+ raise stack
251
+ end
252
+ end
253
+ end
@@ -0,0 +1,64 @@
1
+ module NiceHttpManageResponse
2
+ private
3
+
4
+ def create_stats(resp)
5
+ # all
6
+ set_stats(self.class.stats[:all])
7
+ # all method
8
+ unless self.class.stats[:all][:method].key?(@prev_request[:method])
9
+ self.class.stats[:all][:method][@prev_request[:method]] = {
10
+ response: {},
11
+ }
12
+ end
13
+ set_stats(self.class.stats[:all][:method][@prev_request[:method]])
14
+ # all method response
15
+ unless self.class.stats[:all][:method][@prev_request[:method]][:response].key?(resp.code)
16
+ self.class.stats[:all][:method][@prev_request[:method]][:response][resp.code] = {}
17
+ end
18
+ set_stats(self.class.stats[:all][:method][@prev_request[:method]][:response][resp.code])
19
+
20
+ # server
21
+ server = "#{@host}:#{@port}"
22
+ unless self.class.stats[:path].key?(server)
23
+ self.class.stats[:path][server] = {}
24
+ end
25
+ set_stats(self.class.stats[:path][server])
26
+ # server path
27
+ unless self.class.stats[:path][server].key?(@prev_request[:path])
28
+ self.class.stats[:path][server][@prev_request[:path]] = { method: {} }
29
+ end
30
+ set_stats(self.class.stats[:path][server][@prev_request[:path]])
31
+ # server path method
32
+ unless self.class.stats[:path][server][@prev_request[:path]][:method].key?(@prev_request[:method])
33
+ self.class.stats[:path][server][@prev_request[:path]][:method][@prev_request[:method]] = {
34
+ response: {},
35
+ }
36
+ end
37
+ set_stats(self.class.stats[:path][server][@prev_request[:path]][:method][@prev_request[:method]])
38
+ # server path method response
39
+ unless self.class.stats[:path][server][@prev_request[:path]][:method][@prev_request[:method]][:response].key?(resp.code)
40
+ self.class.stats[:path][server][@prev_request[:path]][:method][@prev_request[:method]][:response][resp.code] = {}
41
+ end
42
+ set_stats(self.class.stats[:path][server][@prev_request[:path]][:method][@prev_request[:method]][:response][resp.code])
43
+
44
+ if @prev_request.key?(:name)
45
+ # name
46
+ unless self.class.stats[:name].key?(@prev_request[:name])
47
+ self.class.stats[:name][@prev_request[:name]] = { method: {} }
48
+ end
49
+ set_stats(self.class.stats[:name][@prev_request[:name]])
50
+ # name method
51
+ unless self.class.stats[:name][@prev_request[:name]][:method].key?(@prev_request[:method])
52
+ self.class.stats[:name][@prev_request[:name]][:method][@prev_request[:method]] = {
53
+ response: {},
54
+ }
55
+ end
56
+ set_stats(self.class.stats[:name][@prev_request[:name]][:method][@prev_request[:method]])
57
+ # name method response
58
+ unless self.class.stats[:name][@prev_request[:name]][:method][@prev_request[:method]][:response].key?(resp.code)
59
+ self.class.stats[:name][@prev_request[:name]][:method][@prev_request[:method]][:response][resp.code] = {}
60
+ end
61
+ set_stats(self.class.stats[:name][@prev_request[:name]][:method][@prev_request[:method]][:response][resp.code])
62
+ end
63
+ end
64
+ end
@@ -35,6 +35,13 @@ module NiceHttpManageRequest
35
35
  path = arguments[0].to_s()
36
36
  end
37
37
  path = (@prepath + path).gsub("//", "/") unless path.nil? or path.start_with?("http:") or path.start_with?("https:")
38
+
39
+ if @defaults_request.key?(:path) and @defaults_request[:path].is_a?(String) and !@defaults_request[:path].empty?
40
+ path += "?" if !path.include?("?") and !@defaults_request[:path].include?("?")
41
+ path += '&' if path.match?(/\?.+$/) and @defaults_request[:path][0]!='&'
42
+ path += @defaults_request[:path]
43
+ end
44
+
38
45
  @cookies.each { |cookie_path, cookies_hash|
39
46
  cookie_path = "" if cookie_path == "/"
40
47
  path_to_check = path
@@ -112,7 +119,7 @@ module NiceHttpManageRequest
112
119
  !headers_t["Content-Type"][/application\/jxml/].nil?)
113
120
  if arguments[0].include?(:values_for)
114
121
  arguments[0][:values_for].each { |key, value|
115
- #todo: implement set_nested
122
+ #todo: implement set_nested
116
123
  data = NiceHttpUtils.set_value_xml_tag(key.to_s(), data, value.to_s(), true)
117
124
  }
118
125
  end
@@ -121,7 +128,7 @@ module NiceHttpManageRequest
121
128
  if data.kind_of?(String)
122
129
  if arguments[0].include?(:values_for)
123
130
  arguments[0][:values_for].each { |key, value|
124
- #todo: implement set_nested
131
+ #todo: implement set_nested
125
132
  data.gsub!(/"(#{key})":\s*"([^"]*)"/, '"\1": "' + value + '"') # "key":"value"
126
133
  data.gsub!(/(#{key}):\s*"([^"]*)"/, '\1: "' + value + '"') # key:"value"
127
134
  data.gsub!(/(#{key}):\s*'([^']*)'/, '\1: \'' + value + "'") # key:'value'
@@ -134,7 +141,7 @@ module NiceHttpManageRequest
134
141
  #lambdas on data only supports on root of the hash
135
142
  data.each do |k, v|
136
143
  if v.is_a?(Proc)
137
- data[k] = v.call
144
+ data[k] = v.call
138
145
  end
139
146
  end
140
147
  if arguments[0].include?(:values_for)
@@ -142,7 +149,7 @@ module NiceHttpManageRequest
142
149
  end
143
150
  data = data.to_json()
144
151
  elsif data.kind_of?(Array)
145
- #todo: implement set_nested
152
+ #todo: implement set_nested
146
153
  data_arr = Array.new()
147
154
  data.each_with_index { |row, indx|
148
155
  if arguments[0].include?(:values_for) and (row.is_a?(Array) or row.is_a?(Hash))
@@ -218,7 +225,7 @@ module NiceHttpManageRequest
218
225
  headers_t.each do |k, v|
219
226
  # for lambdas
220
227
  if v.is_a?(Proc)
221
- headers_t[k] = v.call
228
+ headers_t[k] = v.call
222
229
  end
223
230
  end
224
231
  @request[:headers] = headers_t
@@ -245,11 +252,11 @@ module NiceHttpManageRequest
245
252
  headers_t.each { |key, val| headers_ts += key.to_s + ":" + "''" + ", " }
246
253
  elsif @log_headers == :partial
247
254
  @logger.info "Just the last 10 characters on header values since option log_headers is set to :partial"
248
- headers_t.each { |key, val|
249
- if val.to_s.size>10
250
- headers_ts += key.to_s + ": ..." + (val.to_s[-10..-1] || val.to_s) + ", "
255
+ headers_t.each { |key, val|
256
+ if val.to_s.size > 10
257
+ headers_ts += key.to_s + ": ..." + (val.to_s[-10..-1] || val.to_s) + ", "
251
258
  else
252
- headers_ts += key.to_s + ":" + (val.to_s[-10..-1] || val.to_s) + ", "
259
+ headers_ts += key.to_s + ":" + (val.to_s[-10..-1] || val.to_s) + ", "
253
260
  end
254
261
  }
255
262
  else