nice_http 1.8.10 → 1.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +53 -3
- data/lib/nice_http/add_stats.rb +85 -0
- data/lib/nice_http/close.rb +39 -0
- data/lib/nice_http/defaults.rb +30 -0
- data/lib/nice_http/inherited.rb +8 -0
- data/lib/nice_http/initialize.rb +253 -0
- data/lib/nice_http/manage/create_stats.rb +64 -0
- data/lib/nice_http/{manage_request.rb → manage/request.rb} +16 -9
- data/lib/nice_http/{manage_response.rb → manage/response.rb} +7 -111
- data/lib/nice_http/manage/set_stats.rb +43 -0
- data/lib/nice_http/manage/wait_async_operation.rb +43 -0
- data/lib/nice_http/methods/delete.rb +108 -0
- data/lib/nice_http/methods/get.rb +159 -0
- data/lib/nice_http/methods/head.rb +72 -0
- data/lib/nice_http/methods/patch.rb +103 -0
- data/lib/nice_http/methods/post.rb +122 -0
- data/lib/nice_http/methods/put.rb +87 -0
- data/lib/nice_http/methods/send_request.rb +47 -0
- data/lib/nice_http/reset.rb +54 -0
- data/lib/nice_http/save_stats.rb +37 -0
- data/lib/nice_http/utils/basic_authentication.rb +18 -0
- data/lib/nice_http/{utils.rb → utils/get_value_xml_tag.rb} +0 -45
- data/lib/nice_http/utils/set_value_xml_tag.rb +30 -0
- data/lib/nice_http.rb +33 -475
- metadata +24 -6
- data/lib/nice_http/http_methods.rb +0 -686
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 05ea4d762f4ce03ab7f89c6ca4aafd323c549c73f686f349dac356e43918ffa5
|
4
|
+
data.tar.gz: a9f1c491dabcd6e559f9454a10a7caeeddea4aac915d10be0548d5465fe1a256
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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://
|
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,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
|
-
|
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
|