alpha
Login
or
Join now
atradio.fm
/
atradio
Star
13
Fork
0
Atom
Configure Feed
Issues
Pull Requests
Commits
Tags
Feed URL
Select the types of activity you want to include in your feed.
A social internet radio platform built on AT Protocol.
atradio.fm
atproto
radio
Star
13
Fork
0
Atom
Configure Feed
Issues
Pull Requests
Commits
Tags
Feed URL
Select the types of activity you want to include in your feed.
Overview
Issues
Pulls
Pipelines
atradio
/
apps
/
media-proxy
/
src
/
at
main
1 folder
4 files
Tsiry Sandratraina
fix(media-proxy): keep radio streams alive past gun's 15s cutoff
1mo ago
61305cb4
media_proxy
fix(media-proxy): keep radio streams alive past gun's 15s cutoff Icecast/SHOUTcast streams reply with no Content-Length and no chunked encoding, so the body is delimited by connection close. gun classifies that as `body_close`/`connection: close`, enters its `closing` state, and arms `closing_timeout` (default 15s) — then force-closes the upstream after 15s, cutting every web radio stream off shortly after it starts. Pass `http_opts => #{closing_timeout => infinity}` so gun keeps the connection open for the whole listening session. Since that 15s close was also the only thing tearing down abandoned streams, add explicit teardown: the chunked loop signals the pump (proxy_gun_ffi:stop/1) when send_chunk to the client fails, so the upstream is closed promptly when a listener leaves (the pump's DATA_TIMEOUT remains the backstop for upstream stalls).
1 month ago
atradio_media_proxy.gleam
feat(media-proxy): per-IP rate limiting on /api routes Fixed-window limiter backed by ETS atomic counters (proxy_ratelimit_ffi.erl), keyed by client IP (X-Forwarded-For / X-Real-IP / socket). /api/* over the budget gets 429 + Retry-After; health + root are exempt. Configurable via RATE_LIMIT (120) / RATE_WINDOW (60s). A background sweep drops expired windows. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2 months ago
proxy_cache_ffi.erl
feat(media-proxy): cache TuneIn + ICY responses (ETS, per-node TTL) Add a node-local ETS-backed TTL cache (no Redis — the proxy is stateless and scales horizontally). TuneIn responses cached 300s, ICY now-playing 20s; a hit is served with `x-cache: HIT`. The table is created at startup from the long-lived main process so it outlives request handlers. Verified live: ICY/TuneIn MISS -> HIT, hits served from memory in ~15ms.
2 months ago
proxy_gun_ffi.erl
fix(media-proxy): keep radio streams alive past gun's 15s cutoff Icecast/SHOUTcast streams reply with no Content-Length and no chunked encoding, so the body is delimited by connection close. gun classifies that as `body_close`/`connection: close`, enters its `closing` state, and arms `closing_timeout` (default 15s) — then force-closes the upstream after 15s, cutting every web radio stream off shortly after it starts. Pass `http_opts => #{closing_timeout => infinity}` so gun keeps the connection open for the whole listening session. Since that 15s close was also the only thing tearing down abandoned streams, add explicit teardown: the chunked loop signals the pump (proxy_gun_ffi:stop/1) when send_chunk to the client fails, so the upstream is closed promptly when a listener leaves (the pump's DATA_TIMEOUT remains the backstop for upstream stalls).
1 month ago
proxy_ratelimit_ffi.erl
feat(media-proxy): per-IP rate limiting on /api routes Fixed-window limiter backed by ETS atomic counters (proxy_ratelimit_ffi.erl), keyed by client IP (X-Forwarded-For / X-Real-IP / socket). /api/* over the budget gets 429 + Retry-After; health + root are exempt. Configurable via RATE_LIMIT (120) / RATE_WINDOW (60s). A background sweep drops expired windows. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2 months ago