module

Krikri::PluginHelpers::HTTPDownload

HTTPDownload - shared binary-safe HTTP download with redirect following, used by get_url.cr and deb822_repository.cr. Both plugins previously hand-rolled their own near-identical download logic (each with its own redirect loop and body streaming); this centralizes the common behavior so it can't drift apart (e.g. one plugin learning redirect handling while the other doesn't).

The download is binary-safe: response.body_io is streamed straight to disk, matching how get_url.cr's own download always worked. A plain HTTP::Client#get with a String-returning body would UTF-8-decode and corrupt arbitrary binary data (GPG key bytes, archives, etc.), so never "fix" this by reading into a String.

Constants

DEFAULT_MAX_REDIRECTS = 5
DEFAULT_TIMEOUT = 10.seconds
X509_V_OK = 0

X509_V_OK: the store verified the chain, so a handshake that failed anyway did so outside certificate verification - Crystal's own wording is the honest one there.

Class methods

build_client(uri : URI, options : Options) : HTTP::Client
Source
copy_failure_reason(ex : Exception) : String

to_native() of whatever get_url's copyfileobj handler caught. An OS error on the write (a full staging filesystem: "[Errno 28] No space left on device") is Python's bare str(OSError) - errno and strerror with NO path, because the call that failed is the file object's own write, which raises with filename=None. Crystal's IO::Error message names the staging file ("write (<path>): <strerror>"), which ansible never prints, so rebuild the Python shape from the errno it carries.

Source
download(url : String, dest : String, options : Options = Options.new) : Nil

Downloads url to dest, following up to max_redirects redirects and streaming the raw body byte-for-byte. Returns nil on success; raises FetchError on a response other than 200 (including 304, which Ansible's own url_get handles one branch higher up), raises on too many redirects, and on an unsupported scheme.

Source
read_timeout_reason(scheme : String) : String

Python words a TLS read timeout differently from a plaintext one: ssl reads surface ssl.SSLError("The read operation timed out"), while a plain socket read is the bare socket.timeout's "timed out". Every read on the connection times out that way - the wait for the response head as much as the body copy - so both fetch_url's OSError text and get_url's copyfileobj text depend on the URL scheme, not on anything in the response.

Source
resolve_redirect(base : URI, location : String) : String
Source

Nested types