module

ProxyHelpers::ImageResizer

HTTP::Client block-form copy — no body buffering. Optional max_bytes ceiling rejects oversize responses either up front (declared Content-Length > max) or mid-stream (running total > max). on_headers fires exactly once on the final 2xx response (not on intermediate redirect responses), before any body byte is written to dst_io, so the caller can set its own Content-Type / Cache-Control / status and flush before bytes flow.

max_redirects (default 0) controls opt-in redirect-following. When 0, any 3xx triggers the existing "raise upstream status N" path. When > 0, 3xx responses extract Location and retry up to max_redirects times. Buffer-then-resize fallback for oversized podcast artwork. The cheap stream-through path in ProxyStreamer caps responses at 5 MB; a small number of legitimate feeds (e.g. Lex Fridman ships a 7.8 MB 3000×3000 PNG) exceed that. Rather than raise the streaming cap (which would let bogus HTML error pages slip through too), we route oversized fetches through libvips: buffer up to RESIZE_MAX_BYTES, hand it to vipsthumbnail for a max-edge resize + JPEG re-encode, and emit the small re-encoded bytes as the response body. The runtime alpine image installs vips-tools for the vipsthumbnail binary; if it's missing, ResizeFailed surfaces to the route handler as a 502.

Constants

RESIZE_MAX_BYTES = (20_i64 * 1024) * 1024
THUMB_QUALITY = 85
THUMB_SIZE = 600

Class methods

resize_through(url : String, dst_io : IO, *, max_bytes : Int64 = RESIZE_MAX_BYTES, size : Int32 = THUMB_SIZE, quality : Int32 = THUMB_QUALITY, connect_timeout : Time::Span = 5.seconds, read_timeout : Time::Span = 15.seconds, on_headers : -> Nil | Nil = nil, max_redirects : Int32 = 5) : Nil
Source

Nested types