contrast-agent 7.1.0 → 7.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/ext/extconf_common.rb +88 -14
  3. data/lib/contrast/agent/assess/policy/source_method.rb +13 -4
  4. data/lib/contrast/agent/assess/policy/trigger_method.rb +12 -18
  5. data/lib/contrast/agent/excluder/excluder.rb +64 -31
  6. data/lib/contrast/agent/protect/rule/base.rb +4 -6
  7. data/lib/contrast/agent/protect/rule/bot_blocker/bot_blocker.rb +1 -1
  8. data/lib/contrast/agent/protect/rule/bot_blocker/bot_blocker_input_classification.rb +2 -2
  9. data/lib/contrast/agent/protect/rule/cmdi/cmdi_backdoors.rb +1 -1
  10. data/lib/contrast/agent/protect/rule/cmdi/cmdi_base_rule.rb +1 -1
  11. data/lib/contrast/agent/protect/rule/deserialization/deserialization.rb +2 -2
  12. data/lib/contrast/agent/protect/rule/path_traversal/path_traversal_semantic_security_bypass.rb +1 -1
  13. data/lib/contrast/agent/protect/rule/sqli/sqli_semantic/sqli_dangerous_functions.rb +1 -1
  14. data/lib/contrast/agent/protect/rule/utils/filters.rb +6 -6
  15. data/lib/contrast/agent/protect/rule/xxe/xxe.rb +1 -1
  16. data/lib/contrast/agent/reporting/client/interface.rb +132 -0
  17. data/lib/contrast/agent/reporting/client/interface_base.rb +27 -0
  18. data/lib/contrast/agent/reporting/connection_status.rb +0 -1
  19. data/lib/contrast/agent/reporting/input_analysis/input_analysis_result.rb +6 -4
  20. data/lib/contrast/agent/reporting/reporter.rb +11 -26
  21. data/lib/contrast/agent/reporting/reporting_events/discovered_route.rb +1 -1
  22. data/lib/contrast/agent/reporting/reporting_utilities/audit.rb +10 -3
  23. data/lib/contrast/agent/reporting/reporting_utilities/reporter_client.rb +47 -6
  24. data/lib/contrast/agent/reporting/reporting_utilities/reporter_client_utils.rb +40 -31
  25. data/lib/contrast/agent/reporting/reporting_utilities/resend.rb +144 -0
  26. data/lib/contrast/agent/reporting/reporting_utilities/response_handler.rb +35 -13
  27. data/lib/contrast/agent/reporting/reporting_utilities/response_handler_mode.rb +14 -1
  28. data/lib/contrast/agent/reporting/reporting_utilities/response_handler_utils.rb +11 -11
  29. data/lib/contrast/agent/request/request.rb +27 -12
  30. data/lib/contrast/agent/telemetry/base.rb +18 -19
  31. data/lib/contrast/agent/telemetry/exception/obfuscate.rb +97 -0
  32. data/lib/contrast/agent/telemetry/exception.rb +1 -0
  33. data/lib/contrast/agent/version.rb +1 -1
  34. data/lib/contrast/components/config/sources.rb +6 -5
  35. data/lib/contrast/components/settings.rb +9 -0
  36. data/lib/contrast/config/diagnostics/source_config_value.rb +5 -1
  37. data/lib/contrast/config/diagnostics/tools.rb +4 -4
  38. data/lib/contrast/config/validate.rb +2 -2
  39. data/lib/contrast/configuration.rb +11 -19
  40. data/lib/contrast/framework/grape/support.rb +1 -2
  41. data/lib/contrast/framework/manager.rb +17 -8
  42. data/lib/contrast/framework/rack/support.rb +99 -1
  43. data/lib/contrast/framework/rails/support.rb +1 -2
  44. data/lib/contrast/framework/sinatra/support.rb +1 -2
  45. data/lib/contrast/logger/aliased_logging.rb +18 -9
  46. data/lib/contrast/utils/hash_utils.rb +21 -2
  47. data/lib/contrast/utils/request_utils.rb +14 -0
  48. data/resources/assess/policy.json +11 -0
  49. metadata +6 -3
  50. data/lib/contrast/agent/reporting/input_analysis/details/bot_blocker_details.rb +0 -27
@@ -0,0 +1,132 @@
1
+ # Copyright (c) 2023 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
2
+ # frozen_string_literal: true
3
+
4
+ require 'contrast/agent/reporting/client/interface_base'
5
+
6
+ module Contrast
7
+ module Agent
8
+ module Reporting
9
+ module Client
10
+ # Interface to safely manage connections across threads.
11
+ class Interface < Contrast::Agent::Reporting::Client::InterfaceBase
12
+ # Execute startup routine and
13
+ def startup
14
+ with_monitor { reporter_client.startup!(reporting_connection) }
15
+ end
16
+
17
+ # @param event [Contrast::Agent::Reporting::ReportingEvent]
18
+ # @return [Net::HTTPResponse]
19
+ def send_event event
20
+ with_monitor { reporter_client.send_event(event, reporting_connection) }
21
+ end
22
+
23
+ # return [Boolean]
24
+ def sleep?
25
+ with_monitor { reporter_client.sleep? }
26
+ end
27
+
28
+ # Retry once than discard the event. This is trigger on too many events of
29
+ # same kind error.
30
+ #
31
+ # @param event [Contrast::Agent::Reporting::ReportingEvent]
32
+ def handle_resend event
33
+ with_monitor do
34
+ reporter_client.handle_resend(event, reporting_connection)
35
+ end
36
+ end
37
+
38
+ # Check to see if client exists and there is connection
39
+ #
40
+ # @return [Boolean
41
+ def connected?
42
+ with_monitor do
43
+ return true if reporter_client && reporting_connection
44
+
45
+ false
46
+ end
47
+ end
48
+
49
+ # Check to see if statup connections are sent or not
50
+ def startup_messages_sent?
51
+ with_monitor { reporter_client.status.startup_messages_sent? }
52
+ end
53
+
54
+ # Check to see if event need to be resend
55
+ #
56
+ # @return [Boolean, nil]
57
+ def resending?
58
+ with_monitor { reporter_client.mode.status == reporter_client.mode.resending }
59
+ end
60
+
61
+ # Return timeout in ms
62
+ def timeout
63
+ with_monitor { reporter_client.timeout } || Contrast::Agent::Reporting::ResponseHandler::TIMEOUT
64
+ end
65
+
66
+ # @return headers [Contrast::Agent::Reporting::Headers]
67
+ def headers
68
+ with_monitor { reporter_client.headers }
69
+ end
70
+
71
+ # Response_handler
72
+ #
73
+ # @return [Contrast::Agent::Reporting::ResponseHandler]
74
+ def response_handler
75
+ with_monitor { reporter_client.response_handler }
76
+ end
77
+
78
+ def status
79
+ with_monitor { reporter_client.status }
80
+ end
81
+
82
+ private
83
+
84
+ # @return [Contrast::Agent::Reporting::ReporterClient]
85
+ def reporter_client
86
+ @_reporter_client ||= Contrast::Agent::Reporting::ReporterClient.new
87
+ end
88
+
89
+ # @return [Net::HTTP, nil] Return open connection or nil
90
+ def reporting_connection
91
+ @_reporting_connection ||= reporter_client.initialize_connection
92
+ end
93
+ end
94
+ end
95
+
96
+ module Telemetry
97
+ # Interface to safely manage connections across threads.
98
+ class Interface < Contrast::Agent::Reporting::Client::InterfaceBase
99
+ URL = 'https://telemetry.ruby.contrastsecurity.com/'
100
+
101
+ # Check to see if client exists and there is connection
102
+ #
103
+ # @return [Boolean
104
+ def connected?
105
+ with_monitor do
106
+ return true if telemetry_client && telemetry_connection
107
+
108
+ false
109
+ end
110
+ end
111
+
112
+ # Starts telemetry request.
113
+ def request_with_response event
114
+ with_monitor do
115
+ telemetry_client.handle_response(telemetry_client.send_request(event, telemetry_connection))
116
+ end
117
+ end
118
+
119
+ private
120
+
121
+ def telemetry_client
122
+ @_telemetry_client ||= Contrast::Agent::Telemetry::Client.new
123
+ end
124
+
125
+ def telemetry_connection
126
+ @_telemetry_connection ||= telemetry_client.initialize_connection(URL)
127
+ end
128
+ end
129
+ end
130
+ end
131
+ end
132
+ end
@@ -0,0 +1,27 @@
1
+ # Copyright (c) 2023 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
2
+ # frozen_string_literal: true
3
+
4
+ require 'monitor'
5
+
6
+ module Contrast
7
+ module Agent
8
+ module Reporting
9
+ module Client
10
+ # Common methods for Client interface.
11
+ class InterfaceBase
12
+ # Execute calls to connection with thread safety.
13
+ def with_monitor &block
14
+ monitor.synchronize(&block)
15
+ end
16
+
17
+ private
18
+
19
+ # @return [Monitor]
20
+ def monitor
21
+ @_monitor ||= Monitor.new
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -10,7 +10,6 @@ module Contrast
10
10
  @last_success = nil
11
11
  @last_failure = nil
12
12
  @startup_messages_sent = false
13
- @_startup_server_message_sent = false
14
13
  end
15
14
 
16
15
  # Whether we have sent startup message to TeamServer. True after successfully sending startup messages to
@@ -4,7 +4,7 @@
4
4
  require 'contrast/utils/object_share'
5
5
  require 'contrast/agent/reporting/input_analysis/input_type'
6
6
  require 'contrast/agent/reporting/input_analysis/score_level'
7
- require 'contrast/agent/reporting/input_analysis/details/protect_rule_details'
7
+ require 'contrast/agent/reporting/details/protect_rule_details'
8
8
 
9
9
  module Contrast
10
10
  module Agent
@@ -112,14 +112,16 @@ module Contrast
112
112
 
113
113
  # Additional per rule details containing more specific info.
114
114
  #
115
- # @param protect_rule_details [Contrast::Agent::Reporting::ProtectRuleDetails]
115
+ # @param protect_rule_details [Contrast::Agent::Reporting::Details::ProtectRuleDetails]
116
116
  def details= protect_rule_details
117
- @_details = protect_rule_details if protect_rule_details.is_a?(Contrast::Agent::Reporting::ProtectRuleDetails)
117
+ return unless protect_rule_details.is_a?(Contrast::Agent::Reporting::Details::ProtectRuleDetails)
118
+
119
+ @_details = protect_rule_details
118
120
  end
119
121
 
120
122
  # Additional per rule details containing more specific info.
121
123
  #
122
- # @return [Contrast::Agent::Reporting::ProtectRuleDetails, nil]
124
+ # @return [Contrast::Agent::Reporting::Details::ProtectRuleDetails, nil]
123
125
  def details
124
126
  @_details
125
127
  end
@@ -6,6 +6,7 @@ require 'contrast/agent/reporting/report'
6
6
  require 'contrast/components/logger'
7
7
  require 'contrast/agent/reporting/reporting_events/agent_startup'
8
8
  require 'contrast/agent/telemetry/exception'
9
+ require 'contrast/agent/reporting/client/interface'
9
10
 
10
11
  module Contrast
11
12
  module Agent
@@ -29,11 +30,7 @@ module Contrast
29
30
  end
30
31
 
31
32
  def client
32
- @_client ||= Contrast::Agent::Reporting::ReporterClient.new
33
- end
34
-
35
- def connection
36
- @_connection ||= client.initialize_connection
33
+ @_client ||= Contrast::Agent::Reporting::Client::Interface.new
37
34
  end
38
35
 
39
36
  def start_thread!
@@ -41,13 +38,12 @@ module Contrast
41
38
  return if running?
42
39
 
43
40
  @connection_attempts = 0
44
-
45
- client.startup!(connection)
46
41
  @_thread = Contrast::Agent::Thread.new do
47
42
  logger.debug('[Reporter] Starting background Reporter thread.')
43
+ client.startup
48
44
  loop do
49
- next unless connected?
50
45
  break unless attempt_to_start?
46
+ next unless connected?
51
47
 
52
48
  process_event(queue.pop)
53
49
  rescue StandardError => e
@@ -61,12 +57,7 @@ module Contrast
61
57
  #
62
58
  # @param event [Contrast::Agent::Reporting::ReportingEvent] Freshly pop-ed event.
63
59
  def handle_resend event
64
- sleep(client.timeout) if client.sleep?
65
- # Retry once than discard the event. This is trigger on too many events of
66
- # same kind error.
67
- client.send_event(event, connection) if client.mode.status == client.mode.resending
68
- client.mode.reset_mode
69
- client.wake_up
60
+ client.handle_resend(event)
70
61
  end
71
62
 
72
63
  # @param event [Contrast::Agent::Reporting::ReportingEvent]
@@ -99,8 +90,9 @@ module Contrast
99
90
  return
100
91
  end
101
92
  return unless event
93
+ return unless connected?
102
94
 
103
- client.send_event(event, connection)
95
+ client.send_event(event)
104
96
  rescue StandardError => e
105
97
  logger.error('[Reporter] Could not send message to TeamServer from reporting queue.', e)
106
98
  end
@@ -124,17 +116,9 @@ module Contrast
124
116
  @_queue ||= Queue.new
125
117
  end
126
118
 
127
- # TODO: RUBY-99999
128
- # The client and connection are being used in multiple threads/ concurrently, and that's not okay. We need
129
- # to figure out why that is and lock it so that it isn't.
130
- #
131
119
  # @return [Boolean]
132
120
  def connected?
133
- if client && connection
134
- # Try to resend startup messages now with connection:
135
- client.startup!(connection) unless client.status.startup_messages_sent?
136
- return true
137
- end
121
+ return true if client.connected?
138
122
 
139
123
  logger.debug('[Reporter] No client/connection; sleeping...')
140
124
  @connection_attempts += 1
@@ -148,8 +132,8 @@ module Contrast
148
132
 
149
133
  # @param event [Contrast::Agent::Reporting::ReportingEvent]
150
134
  def process_event event
151
- client.send_event(event, connection)
152
- handle_resend(event) if client.mode.status == client.mode.resending
135
+ client.send_event(event)
136
+ handle_resend(event) if client.resending?
153
137
  rescue StandardError => e
154
138
  logger.error('[Reporter] Could not send message to TeamServer from reporting queue.', e)
155
139
  end
@@ -171,6 +155,7 @@ module Contrast
171
155
  stack_trace[1].path.delete_prefix(Dir.pwd)
172
156
  end
173
157
  stack_frame_function = stack_trace.nil? || stack_trace[1].nil? ? 'none' : stack_trace[1].label
158
+ stack_frame_type = Contrast::Agent::Telemetry::Exception::Obfuscate.obfuscate_path(stack_frame_type)
174
159
  Contrast::Agent::Telemetry::Exception::StackFrame.build(stack_frame_function, stack_frame_type, nil)
175
160
  end
176
161
  end
@@ -81,7 +81,7 @@ module Contrast
81
81
  safe_url = source_or_string(url || pattern)
82
82
 
83
83
  msg = new
84
- msg.signature = "#{ controller }##{ method } #{ safe_pattern }"
84
+ msg.signature = "#{ controller }##{ method } #{ safe_pattern }" # rubocop:disable [Security/Object/Method]
85
85
  msg.verb = Contrast::Utils::StringUtils.force_utf8(method)
86
86
  msg.url = Contrast::Utils::StringUtils.force_utf8(safe_url)
87
87
  msg
@@ -55,17 +55,24 @@ module Contrast
55
55
  # @param event_name [String] the type portion of the file to which to write
56
56
  # @param data [any] The data to be written to the file
57
57
  def write_to_file type, event_name, data = nil
58
- time = Time.now.to_i
58
+ time = Contrast::Utils::Timer.now_ms
59
59
  destination = type == :request ? path_for_requests : path_for_responses
60
60
  # If the feature is disabled or we have yet to create the directory structure, then we could have a nil
61
61
  # destination. In that case, take no action
62
62
  return unless destination
63
63
 
64
- filename = "#{ time }_#{ Thread.current.object_id }_#{ event_name.gsub('::', '-') }_teamserver_#{ type }.json"
64
+ # Get process id and thread id to make sure we don't overwrite files
65
+ process_id = Process.pid
66
+ thread_id = Thread.current.object_id
67
+ event_title = event_name.gsub('::', '-')
68
+ filename = "#{ time }_#{ thread_id }_#{ process_id }_#{ event_title }_teamserver_#{ type }.json"
65
69
  filepath = File.join(destination, filename)
66
70
  logger.debug('Writing to file', eventname: event_name, filename: filename, filepath: filepath)
67
71
  # Here is use append mode, because of a slightly possibility of overwriting an existing file
68
- File.open(filepath, 'a') { |f| f.write(Contrast::Utils::StringUtils.force_utf8(data)) }
72
+ File.open(filepath, 'a') do |f|
73
+ f.write(Contrast::Utils::StringUtils.force_utf8(data))
74
+ f.close
75
+ end
69
76
  rescue StandardError => e
70
77
  logger.warn('Saving audit failed', e: e)
71
78
  end
@@ -14,6 +14,7 @@ require 'contrast/agent/reporting/reporting_utilities/response_handler'
14
14
  require 'contrast/agent/reporting/reporting_events/application_settings'
15
15
  require 'contrast/agent/reporting/reporting_events/agent_effective_config'
16
16
  require 'contrast/agent/reporting/reporting_utilities/reporter_client_utils'
17
+ require 'contrast/agent/reporting/reporting_utilities/resend'
17
18
 
18
19
  module Contrast
19
20
  module Agent
@@ -72,17 +73,17 @@ module Contrast
72
73
  def send_event event, connection
73
74
  return unless connection
74
75
 
76
+ response = nil
75
77
  logger.debug('[Reporter] Preparing to send reporting event', event_class: event.cs__class)
76
-
77
78
  request = build_request(event)
78
79
  response = connection.request(request)
79
- audit&.audit_event(event, response) if ::Contrast::API.request_audit_enable
80
+ audit.audit_event(event, response) if ::Contrast::API.request_audit_enable
80
81
  process_settings_response(response, event)
81
- report_configuration(response, event)
82
82
  process_preflight_response(event, response, connection)
83
+ report_configuration(response, event)
83
84
  response
84
85
  rescue StandardError => e
85
- handle_error(event, e)
86
+ handle_response_error(event, connection, e)
86
87
  end
87
88
 
88
89
  # Write effective config to file:
@@ -103,6 +104,9 @@ module Contrast
103
104
  diagnostics.write_to_file
104
105
  config_event = Contrast::Agent::Reporting::AgentEffectiveConfig.new(diagnostics)
105
106
  Contrast::Agent.reporter.send_event(config_event)
107
+ rescue StandardError => e
108
+ # Don't let this error bubble up and stop the agent reporting, with resending triggered.
109
+ logger.error('[Reporter] Error while reporting configuration', error: e, event_type: event&.cs__class)
106
110
  end
107
111
 
108
112
  def status
@@ -117,10 +121,47 @@ module Contrast
117
121
  @_diagnostics ||= Contrast::Config::Diagnostics::Monitor.new(Contrast::LOGGER.path)
118
122
  end
119
123
 
124
+ # Compress data with Zlib
125
+ #
126
+ # @param event [Contrast::Agent::Reporting::ReportingEvent]
127
+ # @param level [Integer] compression level
128
+ # @param strategy [Integer] compression strategy
129
+ # @return [String] compressed data
130
+ def compress_event event, level = Zlib::DEFAULT_COMPRESSION, strategy = Zlib::DEFAULT_STRATEGY
131
+ compressed_data = StringIO.new.set_encoding(STRING_ENCODING)
132
+ gzip = Zlib::GzipWriter.new(compressed_data, level, strategy)
133
+ gzip.write(event.event_json)
134
+ gzip.close
135
+ gzip = nil
136
+ compressed_event = compressed_data.string.dup
137
+ compressed_data.close
138
+ compressed_data = nil
139
+ compressed_event
140
+ ensure
141
+ gzip&.close
142
+ compressed_data&.close
143
+ compressed_event
144
+ end
145
+
146
+ # Reads compressed data
147
+ #
148
+ # @param compresed_data [String]
149
+ def decompress compresed_data
150
+ Zlib::GzipReader.wrap(StringIO.new(compresed_data), &:read)
151
+ end
152
+
153
+ ##############
154
+ # Forwarders #
155
+ ##############
156
+
120
157
  def sleep?
121
158
  response_handler.sleep?
122
159
  end
123
160
 
161
+ def put_to_sleep
162
+ response_handler.put_to_sleep
163
+ end
164
+
124
165
  def timeout
125
166
  response_handler.timeout
126
167
  end
@@ -129,8 +170,8 @@ module Contrast
129
170
  response_handler.mode
130
171
  end
131
172
 
132
- def reset_mode
133
- response_handler.reset_mode
173
+ def enter_run_mode
174
+ response_handler.enter_run_mode
134
175
  end
135
176
 
136
177
  def wake_up
@@ -8,16 +8,20 @@ require 'contrast/components/scope'
8
8
  require 'contrast/agent/reporting/reporting_events/application_startup'
9
9
  require 'contrast/agent/reporting/reporting_utilities/reporter_client'
10
10
  require 'contrast/agent/reporting/reporting_utilities/endpoints'
11
+ require 'contrast/agent/reporting/reporting_utilities/resend'
11
12
 
12
13
  module Contrast
13
14
  module Agent
14
15
  module Reporting
15
16
  # This module holds utilities required by the reporting service client
16
17
  module ReporterClientUtils
18
+ include Contrast::Agent::Reporting::Resend
17
19
  include Contrast::Components::Logger::InstanceMethods
18
20
  include Contrast::Components::Scope::InstanceMethods
19
21
  include Contrast::Agent::Reporting::Endpoints
20
22
 
23
+ STRING_ENCODING = 'BINARY'
24
+
21
25
  # List the events that need to be sent when agent starts up.
22
26
  # The order here matters -- DO NOT CHANGE IT!!! >_< - HM
23
27
  #
@@ -33,19 +37,37 @@ module Contrast
33
37
 
34
38
  private
35
39
 
36
- # Send Agent Startup event
40
+ # Send Agent Startup event. If error occurs, it will try to resend the message.
37
41
  #
38
42
  # @param connection [Net::HTTP] open connection
39
43
  def send_agent_startup connection
40
- logger.debug('Preparing to send startup messages')
44
+ logger.debug('[Reporter] Preparing to send startup messages')
45
+ STARTUP_EVENTS.each { |event| send_event(event.new, connection) }
46
+ logger.debug('[Reporter] Startup messages sent.') if status.startup_messages_sent?
47
+ end
41
48
 
42
- STARTUP_EVENTS.each do |event|
43
- startup_event = event.new
44
- send_event(startup_event, connection)
45
- rescue StandardError => e
46
- handle_error(startup_event, e)
47
- end
48
- logger.debug('Startup messages sent')
49
+ # Disable reporting and log the error
50
+ #
51
+ # @param event [Contrast::Agent::Reporting::ReportingEvent]
52
+ # @param error [StandardError]
53
+ def disable_reporting event, error
54
+ status.failure!
55
+ mode.resend.reset_rescue_attempts
56
+ mode.status = mode.disabled
57
+ message = '[Reporter] Unable to send message.'
58
+ response_handler.stop_reporting(message,
59
+ application: Contrast::APP_CONTEXT.name, # rubocop:disable Security/Module/Name
60
+ connection_error: error,
61
+ client: Contrast::Agent::Reporting::ReporterClient::SERVICE_NAME,
62
+ event_id: event&.__id__,
63
+ event_type: event&.cs__class&.cs__name)
64
+ nil
65
+ end
66
+
67
+ def response_success!
68
+ status.success!
69
+ mode.enter_run_mode
70
+ mode.resend.reset_rescue_attempts
49
71
  end
50
72
 
51
73
  # This method will build headers of the request required for TS communication
@@ -65,29 +87,18 @@ module Contrast
65
87
  request
66
88
  end
67
89
 
68
- # Handles standard error case, logs and set status for failure
69
- #
70
- # @param event [Contrast::Agent::Reporting::ReportingEvent]
71
- # One of the DTMs valid for the event field of Contrast::Api::Dtm::Message
72
- # @param error_msg [StandardError]
73
- # @return nil [NilClass] to be passed as response
74
- def handle_error event, error_msg
75
- status.failure!
76
- logger.error('Unable to send message.',
77
- error_msg,
78
- client: Contrast::Agent::Reporting::ReporterClient::SERVICE_NAME,
79
- event_id: event&.__id__,
80
- event_type: event&.cs__class&.cs__name)
81
- nil
82
- end
83
-
84
90
  # Handles response processing and sets status
85
91
  #
86
92
  # @param event [Contrast::Agent::Reporting::ReportingEvent] The event sent to TeamServer.
87
93
  # @param response [Net::HTTP::Response]
88
94
  def process_settings_response response, event
89
95
  res = response_handler.process(response, event)
90
- status.success! if res
96
+ if res
97
+ status.success!
98
+ mode.resend.reset_rescue_attempts
99
+ else
100
+ status.failure!
101
+ end
91
102
  res
92
103
  end
93
104
 
@@ -104,6 +115,7 @@ module Contrast
104
115
  return unless response&.body && connection
105
116
 
106
117
  findings_to_return = response.body.split(',').delete_if { |el| el.include?('*') }
118
+ mode.resend.reset_rescue_attempts
107
119
  findings_to_return.each do |index|
108
120
  preflight_message = event.messages[index.to_i]
109
121
  corresponding_finding = Contrast::Agent::Reporting::ReportingStorage.delete(preflight_message.data)
@@ -112,7 +124,7 @@ module Contrast
112
124
  send_event(corresponding_finding, connection)
113
125
  end
114
126
  rescue StandardError => e
115
- logger.error('Unable to handle response', e)
127
+ logger.error('[Reporter] Unable to handle preflight response', e)
116
128
  end
117
129
 
118
130
  # Convert the given event into an appropriate Net::HTTPRequest object, setting the request headers and
@@ -133,10 +145,7 @@ module Contrast
133
145
  end
134
146
  build_headers(request)
135
147
  event.attach_headers(request)
136
- # compress:
137
- gzip = Zlib::GzipWriter.new(StringIO.new)
138
- gzip << event.event_json
139
- request.body = gzip.close.string
148
+ request.body = compress_event(event)
140
149
  request
141
150
  end
142
151
  end