moesif_rack 2.1.0 → 2.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/LICENSE +1 -1
- data/README.md +1 -1
- data/lib/moesif_rack/moesif_helpers.rb +19 -0
- data/lib/moesif_rack/moesif_middleware.rb +4 -23
- data/moesif_capture_outgoing/httplog/adapters/net_http.rb +7 -2
- data/moesif_capture_outgoing/httplog/http_log.rb +25 -7
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 396b06aef61b8c6050b1fa34f6d8646a28556f605b7adb885a6f66f7d2815795
|
4
|
+
data.tar.gz: 1873d5dd9e5db0f562407cbd9a82420d783d894d7c7c23a6044d30993a7fea92
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9e16283ae468998106f1ab4289c234ccfa858c1b76d3a2c0932fa9d1e0e02929276741fd986afae9b63d81a43eac471d119d7d3eec2a2e49ee459f8d8c63eac3
|
7
|
+
data.tar.gz: 495ebf15c916fe0cf98ca26758e83f53580b74c69cc78e45224a5024b71064f48b011b99b50a26a33f69da4209587d381f080b55ba0069f1daaa434a553f9c75
|
data/LICENSE
CHANGED
data/README.md
CHANGED
@@ -262,7 +262,7 @@ Optional. int, default 200, Maximum batch size when sending to Moesif.
|
|
262
262
|
Optional. int in seconds Default 2. This is the maximum wait time (approximately) before triggering flushing of the queue and sending to Moesif.
|
263
263
|
|
264
264
|
#### __`event_queue_size`__
|
265
|
-
Optional. int, Default
|
265
|
+
Optional. int, Default 1000000, Maximum number of events to hold in queue before sending to Moesif. In case of network issues when not able to connect/send event to Moesif, skips adding new to event to queue to prevent memory overflow.
|
266
266
|
|
267
267
|
#### __`capture_outgoing_requests`__
|
268
268
|
Optional. Boolean, Default `false`. Set to `true` to capture all outgoing API calls from your app to third parties like Stripe, Github or to your own dependencies while using [Net::HTTP](https://ruby-doc.org/stdlib-2.6.3/libdoc/net/http/rdoc/Net/HTTP.html) package. The options below is applied to outgoing API calls. When the request is outgoing, for options functions that take request and response as input arguments, the request and response objects passed in are [Request](https://www.rubydoc.info/stdlib/net/Net/HTTPRequest) request and [Response](https://www.rubydoc.info/stdlib/net/Net/HTTPResponse) response objects.
|
@@ -38,4 +38,23 @@ class MoesifHelpers
|
|
38
38
|
log_debug 'failed to convert replacement body ' + e.to_s
|
39
39
|
[replacement_body.to_json.to_s]
|
40
40
|
end
|
41
|
+
|
42
|
+
def parse_multipart(multipart_form_data, content_type)
|
43
|
+
log_debug("try to parse multiple part #{content_type}")
|
44
|
+
|
45
|
+
sanitized_multipart_form_data = multipart_form_data.gsub(/\r?\n/, "\r\n")
|
46
|
+
|
47
|
+
io = StringIO.new(sanitized_multipart_form_data)
|
48
|
+
tempfile = Rack::Multipart::Parser::TEMPFILE_FACTORY
|
49
|
+
bufsize = Rack::Multipart::Parser::BUFSIZE
|
50
|
+
query_parser = Rack::Utils.default_query_parser
|
51
|
+
result = Rack::Multipart::Parser.parse(io, sanitized_multipart_form_data.length, content_type, tempfile, bufsize,
|
52
|
+
query_parser)
|
53
|
+
|
54
|
+
log_debug('multipart parse result')
|
55
|
+
log_debug(result.inspect)
|
56
|
+
|
57
|
+
# this is a hash should be treated as JSON down the road.
|
58
|
+
result.params
|
59
|
+
end
|
41
60
|
end
|
@@ -18,7 +18,7 @@ module MoesifRack
|
|
18
18
|
@app = app
|
19
19
|
raise 'application_id required for Moesif Middleware' unless options['application_id']
|
20
20
|
|
21
|
-
@api_client = MoesifApi::MoesifAPIClient.new(options['application_id'], 'moesif-rack/2.1
|
21
|
+
@api_client = MoesifApi::MoesifAPIClient.new(options['application_id'], 'moesif-rack/2.2.1')
|
22
22
|
@api_controller = @api_client.api
|
23
23
|
|
24
24
|
@api_version = options['api_version']
|
@@ -35,7 +35,7 @@ module MoesifRack
|
|
35
35
|
@disable_transaction_id = options['disable_transaction_id'] || false
|
36
36
|
@log_body = options.fetch('log_body', true)
|
37
37
|
@batch_size = options['batch_size'] || 200
|
38
|
-
@event_queue_size = options['event_queue_size'] ||
|
38
|
+
@event_queue_size = options['event_queue_size'] || 1000000
|
39
39
|
@batch_max_time = options['batch_max_time'] || 2
|
40
40
|
@events_queue = Queue.new
|
41
41
|
@event_response_config_etag = nil
|
@@ -59,7 +59,7 @@ module MoesifRack
|
|
59
59
|
|
60
60
|
@moesif_helpers.log_debug 'Start Capturing outgoing requests'
|
61
61
|
require_relative '../../moesif_capture_outgoing/httplog'
|
62
|
-
MoesifCaptureOutgoing.start_capture_outgoing(options, @app_config, @events_queue)
|
62
|
+
MoesifCaptureOutgoing.start_capture_outgoing(options, @app_config, @events_queue, @moesif_helpers)
|
63
63
|
end
|
64
64
|
|
65
65
|
def update_user(user_profile)
|
@@ -100,25 +100,6 @@ module MoesifRack
|
|
100
100
|
puts("#{Time.now} [Moesif Middleware] PID #{Process.pid} TID #{Thread.current.object_id} #{message}")
|
101
101
|
end
|
102
102
|
|
103
|
-
def parse_multipart(multipart_form_data, content_type)
|
104
|
-
@moesif_helpers.log_debug("try to parse multiple part #{content_type}")
|
105
|
-
|
106
|
-
sanitized_multipart_form_data = multipart_form_data.gsub(/\r?\n/, "\r\n")
|
107
|
-
|
108
|
-
io = StringIO.new(sanitized_multipart_form_data)
|
109
|
-
tempfile = Rack::Multipart::Parser::TEMPFILE_FACTORY
|
110
|
-
bufsize = Rack::Multipart::Parser::BUFSIZE
|
111
|
-
query_parser = Rack::Utils.default_query_parser
|
112
|
-
result = Rack::Multipart::Parser.parse(io, sanitized_multipart_form_data.length, content_type, tempfile, bufsize,
|
113
|
-
query_parser)
|
114
|
-
|
115
|
-
@moesif_helpers.log_debug('multipart parse result')
|
116
|
-
@moesif_helpers.log_debug(result.inspect)
|
117
|
-
|
118
|
-
# this is a hash shold be treated as JSON down the road.
|
119
|
-
result.params
|
120
|
-
end
|
121
|
-
|
122
103
|
def parse_body(body, headers)
|
123
104
|
begin
|
124
105
|
if body.instance_of?(Hash) || body.instance_of?(Array)
|
@@ -128,7 +109,7 @@ module MoesifRack
|
|
128
109
|
parsed_body = JSON.parse(body)
|
129
110
|
transfer_encoding = 'json'
|
130
111
|
elsif headers.key?('content-type') && (headers['content-type'].downcase.include? 'multipart/form-data')
|
131
|
-
parsed_body = parse_multipart(body, headers['content-type'])
|
112
|
+
parsed_body = @moesif_helpers.parse_multipart(body, headers['content-type'])
|
132
113
|
transfer_encoding = 'json'
|
133
114
|
elsif headers.key?('content-encoding') && (headers['content-encoding'].downcase.include? 'gzip')
|
134
115
|
uncompressed_string = decompress_body(body)
|
@@ -7,10 +7,14 @@ module Net
|
|
7
7
|
def request(request, body = nil, &block)
|
8
8
|
# Request Start Time
|
9
9
|
request_time = Time.now.utc.iso8601(3)
|
10
|
-
|
11
10
|
# URL
|
12
11
|
url = "https://#{@address}#{request.path}"
|
13
12
|
|
13
|
+
if (not request.body_stream.nil?) && MoesifCaptureOutgoing.should_capture_body
|
14
|
+
req_body_from_stream = request.body_stream.read
|
15
|
+
request.body_stream.rewind
|
16
|
+
end
|
17
|
+
|
14
18
|
# Response
|
15
19
|
@response = orig_request(request, body, &block)
|
16
20
|
|
@@ -18,7 +22,8 @@ module Net
|
|
18
22
|
response_time = Time.now.utc.iso8601(3)
|
19
23
|
|
20
24
|
# Log Event to Moesif
|
21
|
-
|
25
|
+
body_from_req_call = body
|
26
|
+
MoesifCaptureOutgoing.call(url, request, request_time, @response, response_time, body_from_req_call, req_body_from_stream) if started?
|
22
27
|
|
23
28
|
@response
|
24
29
|
end
|
@@ -7,7 +7,7 @@ require_relative '../../lib/moesif_rack/app_config'
|
|
7
7
|
|
8
8
|
module MoesifCaptureOutgoing
|
9
9
|
class << self
|
10
|
-
def start_capture_outgoing(options, app_config_manager, events_queue)
|
10
|
+
def start_capture_outgoing(options, app_config_manager, events_queue, moesif_helpers)
|
11
11
|
@moesif_options = options
|
12
12
|
raise 'application_id required for Moesif Middleware' unless @moesif_options['application_id']
|
13
13
|
|
@@ -28,10 +28,15 @@ module MoesifCaptureOutgoing
|
|
28
28
|
@events_queue = events_queue
|
29
29
|
@sampling_percentage = 100
|
30
30
|
@last_updated_time = Time.now.utc
|
31
|
+
@moesif_helpers = moesif_helpers
|
31
32
|
end
|
32
33
|
|
33
|
-
def
|
34
|
-
|
34
|
+
def should_capture_body
|
35
|
+
@moesif_options.nil? ? false : @moesif_options['capture_outgoing_requests'] && @log_body_outgoing
|
36
|
+
end
|
37
|
+
|
38
|
+
def call(url, request, request_time, response, response_time, body_from_req_call, req_body_from_stream)
|
39
|
+
send_moesif_event(url, request, request_time, response, response_time, body_from_req_call, req_body_from_stream)
|
35
40
|
end
|
36
41
|
|
37
42
|
def get_response_body(response)
|
@@ -44,18 +49,30 @@ module MoesifCaptureOutgoing
|
|
44
49
|
Rack::Utils::HTTP_STATUS_CODES.detect { |_k, v| v.to_s.casecmp(response_code_name.to_s).zero? }.first
|
45
50
|
end
|
46
51
|
|
47
|
-
def send_moesif_event(url, request, request_time, response, response_time)
|
52
|
+
def send_moesif_event(url, request, request_time, response, response_time, body_from_req_call, req_body_from_stream)
|
48
53
|
if url.downcase.include? 'moesif'
|
49
54
|
puts 'Skip sending as it is moesif Event' if @debug
|
50
55
|
else
|
51
56
|
response.code = transform_response_code(response.code) if response.code.is_a?(Symbol)
|
52
57
|
|
58
|
+
# Request headers
|
59
|
+
req_headers = request.each_header.collect.to_h
|
60
|
+
req_content_type = req_headers['content-type'].nil? ? req_headers['Content-Type'] : req_headers['content-type']
|
61
|
+
|
53
62
|
# Request Body
|
54
|
-
req_body_string = request.body.nil? || request.body.empty? ?
|
63
|
+
req_body_string = request.body.nil? || request.body.empty? ? body_from_req_call : request.body
|
55
64
|
req_body_transfer_encoding = nil
|
56
65
|
req_body = nil
|
57
66
|
|
58
|
-
if @log_body_outgoing && (
|
67
|
+
if @log_body_outgoing && (not req_content_type.nil?) && (req_content_type.downcase.include? 'multipart/form-data')
|
68
|
+
@moesif_helpers.log_debug 'outgoing request is multipart, parsing req_body_from_stream'
|
69
|
+
begin
|
70
|
+
req_body = @moesif_helpers.parse_multipart(req_body_from_stream, req_content_type)
|
71
|
+
rescue StandardError => e
|
72
|
+
@moesif_helpers.log_debug 'outgoing request is multipart, but failed to process req_body_from_stream: ' + req_body_from_stream.to_s + e.to_s
|
73
|
+
req_body = nil
|
74
|
+
end
|
75
|
+
elsif @log_body_outgoing && (req_body_string && req_body_string.length != 0)
|
59
76
|
begin
|
60
77
|
req_body = JSON.parse(req_body_string)
|
61
78
|
rescue StandardError
|
@@ -83,8 +100,9 @@ module MoesifCaptureOutgoing
|
|
83
100
|
event_req.time = request_time
|
84
101
|
event_req.uri = url
|
85
102
|
event_req.verb = request.method.to_s.upcase
|
86
|
-
event_req.headers =
|
103
|
+
event_req.headers = req_headers
|
87
104
|
event_req.api_version = nil
|
105
|
+
|
88
106
|
event_req.body = req_body
|
89
107
|
event_req.transfer_encoding = req_body_transfer_encoding
|
90
108
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: moesif_rack
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.1
|
4
|
+
version: 2.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Moesif, Inc
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2023-
|
12
|
+
date: 2023-11-01 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: test-unit
|