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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 69afd6b0a828ebfe415dac81b3120919369c69ed0b21cce328a81d4daf4556e2
4
- data.tar.gz: 986c5276e9728e00b511b37926442a9e91ac37682b4405803df237820381b3b9
3
+ metadata.gz: 396b06aef61b8c6050b1fa34f6d8646a28556f605b7adb885a6f66f7d2815795
4
+ data.tar.gz: 1873d5dd9e5db0f562407cbd9a82420d783d894d7c7c23a6044d30993a7fea92
5
5
  SHA512:
6
- metadata.gz: cc02ceae02f2ded23338546e83846020b7f94b2c973492c983dd436ca56be844d1301110fa184b233d9cea34a36412dcf58ea9bd0c6775e827d03f47081c7345
7
- data.tar.gz: fcd53c6dd3c51f5074debde812b307fedf7d7d77ebbef8712b4a1713536951ccb6fcf76e5b3edec09666a59a8a107d4ac807149a109b83658c4db07cda2b3b0a
6
+ metadata.gz: 9e16283ae468998106f1ab4289c234ccfa858c1b76d3a2c0932fa9d1e0e02929276741fd986afae9b63d81a43eac471d119d7d3eec2a2e49ee459f8d8c63eac3
7
+ data.tar.gz: 495ebf15c916fe0cf98ca26758e83f53580b74c69cc78e45224a5024b71064f48b011b99b50a26a33f69da4209587d381f080b55ba0069f1daaa434a553f9c75
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2021 Moesif, Inc
1
+ Copyright (c) 2023 Moesif, Inc
2
2
 
3
3
  Licensed under the Apache License, Version 2.0 (the "License");
4
4
  you may not use this file except in compliance with the License.
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 1000, 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.
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.0')
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'] || 1000
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
- MoesifCaptureOutgoing.call(url, request, request_time, @response, response_time) if started?
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 call(url, request, request_time, response, response_time)
34
- send_moesif_event(url, request, request_time, response, response_time)
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? ? nil : request.body
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 && (req_body_string && req_body_string.length != 0)
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 = request.each_header.collect.to_h
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.0
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-08-16 00:00:00.000000000 Z
12
+ date: 2023-11-01 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: test-unit