Class: ReactOnRailsPro::CompressionMiddlewareGuard

Inherits:
Object
  • Object
show all
Defined in:
lib/react_on_rails_pro/compression_middleware_guard.rb

Defined Under Namespace

Classes: Finding, StreamingBodyProbe

Constant Summary collapse

COMPATIBILITY_GUIDE_PATH =
"https://reactonrails.com/docs/building-features/" \
"streaming-server-rendering/#compression-middleware-compatibility"
PROBLEMATIC_MIDDLEWARES =
%w[Rack::Deflater Rack::Brotli].freeze
PROBE_TIMEOUT_SECONDS =
1

Instance Method Summary collapse

Constructor Details

#initialize(middlewares:, logger: nil) ⇒ CompressionMiddlewareGuard

Returns a new instance of CompressionMiddlewareGuard.



16
17
18
19
# File 'lib/react_on_rails_pro/compression_middleware_guard.rb', line 16

def initialize(middlewares:, logger: nil)
  @middlewares = normalize_middlewares(middlewares)
  @logger = logger
end

Instance Method Details

#findingsObject



21
22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/react_on_rails_pro/compression_middleware_guard.rb', line 21

def findings
  @findings ||= @middlewares.filter_map do |middleware|
    next unless problematic_middleware?(middleware)

    condition = middleware_condition(middleware)
    next unless condition.respond_to?(:call)
    next unless destructively_iterates_stream?(condition)

    Finding.new(
      middleware_name: middleware_name(middleware),
      source_location: source_location_for(condition)
    )
  end
end

#warning_messages(root:) ⇒ Object



36
37
38
39
40
41
42
43
44
45
# File 'lib/react_on_rails_pro/compression_middleware_guard.rb', line 36

def warning_messages(root:)
  findings.map do |finding|
    "[React on Rails Pro] #{finding.middleware_name} has a custom `:if` callback" \
      "#{formatted_source_location(finding, root: root)} that calls `body.each`. " \
      "This is incompatible with streaming SSR/RSC and can deadlock `ActionController::Live` responses. " \
      "Remove the custom `:if`, or guard it with " \
      "`return true unless body.respond_to?(:to_ary)` before iterating. " \
      "See #{COMPATIBILITY_GUIDE_PATH}."
  end
end