Module: Karst::Web::Badge

Defined in:
lib/karst/web/badge.rb

Overview

Rewrites an eligible host HTML response to add a small, page-local link into Karst's route-scoped scenario catalog. Every check here exists to make injection safe to skip: Badge never guesses, never raises into the host application, and never touches a response it cannot confidently rewrite -- an untouched response is always the safe fallback.

Route identity (controller/action/http_method) comes from Middleware, itself derived from a real process_action.action_controller notification; Badge never infers it from a path. context.path is carried along purely as display context for the panel (see Karst::Web::Panel), never as part of route identity.

Defined Under Namespace

Classes: Context

Class Method Summary collapse

Class Method Details

.apply(status:, headers:, body:, context:) ⇒ Object

Returns a replacement [status, headers, body] triple, or nil when the response should be returned to the host application unchanged -- including when anything above raises, so a bug here can never turn into a broken host page.



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/karst/web/badge.rb', line 54

def apply(status:, headers:, body:, context:)
  return nil unless context
  return nil unless html_response?(status: status, headers: headers)
  # `to_ary` is Rack's own signal that a body is already fully
  # buffered rather than genuinely streaming (Rack::ETag relies on
  # exactly this same check for exactly this same reason). Rails
  # delegates it down to the response's real stream object, so a
  # Live-streaming response correctly reports false and is left
  # alone. Under Rack 2 (Rails 7.0), ActionDispatch's older
  # RackBody wrapper never exposes to_ary at all -- every response
  # reports false there, so Badge never injects on that Rails
  # series. That is a missing feature, not a bug: guessing
  # bufferability by any other means risks blocking forever on a
  # real streaming body, which this module will not do.
  return nil unless body.respond_to?(:to_ary)

  parts = body.to_ary
  return nil unless bufferable?(parts)

  rewrite(status: status, headers: headers, parts: parts, body: body, context: context)
rescue StandardError
  nil
end