# Copyright (c) 2022 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details. # frozen_string_literal: true module Contrast module Framework module Rails module Patch # This class acts as our patch into the ActionController::Live::Buffer class, allowing us to track the close # event on streamed responses. module ActionControllerLiveBuffer class << self # TODO: RUBY-1353 # TODO: RUBY-1355 # TODO: RUBY-1357 # TODO: RUBY-1357 def send_messages return unless (context = Contrast::Agent::REQUEST_TRACKER.current) if Contrast::Agent::Reporter.enabled? [ context.new_observed_route, Contrast::Agent::Reporting::DtmMessage.dtm_to_event(context.server_activity), Contrast::Agent::Reporting::DtmMessage.dtm_to_event(context.activity.library_usages), Contrast::Agent::Reporting::DtmMessage.dtm_to_event(context.activity) ].each do |event| Contrast::Agent.reporter&.send_event_immediately(event) end else [context.server_activity, context.activity, context.observed_route].each do |msg| Contrast::Agent.messaging_queue&.send_event_immediately(msg) end end end def instrument @_instrument ||= begin ::ActionController::Live::Buffer.class_eval do # normally pre->in->post filters are applied however, in a streamed response we can run into a case # where it's pre -> in -> post -> more infilters in order to submit anything found during the # infilters after the response has been written we need to explicitly send them alias_method(:cs__close, :close) def close Contrast::Framework::Rails::Patch::ActionControllerLiveBuffer.send_messages cs__close end end true end end end end end end end end