9.9 KiB
🌊 Reverse Proxy (Streaming, Caching & Rate Limits)
This section documents the reverse_proxy: block inside config.yml. It is the most critical block for determining runtime
behavior when Tuliprox actively proxies video streams to clients (Reverse Proxy Mode), rather than just redirecting them.
It manages how Tuliprox establishes upstream connections, buffers video frames, handles sudden client disconnects, and caches static resources like EPG images and channel logos.
Top-level entries
reverse_proxy:
resource_rewrite_disabled: false
rewrite_secret: A1B2C3D4E5F60718293A4B5C6D7E8F90
stream:
cache:
rate_limit:
disabled_header:
resource_retry:
geoip:
General Parameters
| Parameter | Type | Default | Technical Impact & Background |
|---|---|---|---|
resource_rewrite_disabled |
Bool | false |
Normally, Tuliprox rewrites all image URLs in playlists to point to itself (e.g., http://tuliprox:8901/resource/...). If set to true, original URLs are kept (clients load images directly from the provider). Warning: Local caching will stop working if this is enabled! |
rewrite_secret |
String | "" |
A 32-character Hex string (16 bytes). Tuliprox encrypts/signs the original image URLs during the rewrite process. To prevent image URLs from becoming invalid after a server restart, you MUST enter a static secret here (generate via openssl rand -hex 16). |
1. Stream Management (stream)
This sub-block defines how Tuliprox maintains stream stability, buffers data, and handles HLS/Catchup session affinity.
reverse_proxy:
stream:
retry: true
buffer:
enabled: true
size: 1024
throttle_kbps: 12500
grace_period_millis: 2000
grace_period_timeout_secs: 4
grace_period_hold_stream: true
hls_session_ttl_secs: 15
catchup_session_ttl_secs: 45
shared_burst_buffer_mb: 12
metrics_enabled: false
Stream Parameters in Detail
| Parameter | Type | Default | Technical Impact & Background |
|---|---|---|---|
retry |
Bool | true |
Background: If the upstream provider unexpectedly drops the connection or a TCP network timeout occurs, Tuliprox immediately opens a new connection to the provider in the background and seamlessly pipes the new bytes to the end-client. The client's player (e.g., VLC) might stutter for a fraction of a second but will not abort playback. |
buffer.enabled |
Bool | false |
Enables an asynchronous ring-buffer in RAM between the provider download stream and the client upload stream. Necessary if the provider stream is faster than the consumer can process. |
buffer.size |
Int | 0 |
The size of the buffer in Chunks (1 Chunk = 8192 Bytes). A value of 1024 equals approximately 8 Megabytes of RAM per active stream. |
throttle_kbps |
Int | 0 |
Background: Some players download VODs (Movies) at maximum line speed ("Bursting"). Providers often view this as abuse or scraping and will ban the IP. By throttling (e.g., to 12500 kbps), you force the download into a constant, inconspicuous flow. Supports units like KB/s, MB/s, kbps, Mibps. |
metrics_enabled |
Bool | false |
Monitoring: If active, Tuliprox samples the live bandwidth (in kbps) and transferred bytes for every active reverse-proxied stream and pushes them via WebSockets to the Web UI. It adds a tiny bit of CPU overhead but is invaluable for debugging buffering issues. |
grace_period_millis |
Int | 2000 |
The exact time window in ms where a temporary over-allocation is allowed (see notes on The VLC Seek Problem for details). |
grace_period_timeout_secs |
Int | 4 |
A hard timeout limit for overlapping "ghost sessions" to expire. |
grace_period_hold_stream |
Bool | true |
Tuliprox artificially holds back the video data to the client, waiting for the grace check to finish, so it doesn't trigger the provider prematurely. |
hls_session_ttl_secs |
Int | 15 |
Keeps the virtual provider slot open between HLS segment (.ts) requests to prevent provider bans for "Account Hopping". |
catchup_session_ttl_secs |
Int | 45 |
The same session-holding principle applied to Archive/Catchup TV. See notes on section Session TTLs for HLS & Catchup for details. |
shared_burst_buffer_mb |
Int | 12 |
Minimum burst buffer size (in MB) used for shared live streams to immediately synchronize new clients without Keyframe dropouts. See notes on section Shared Live Streams for details. |
2. Resource Caching (cache)
Tuliprox caches channel logos, posters, and EPG images on your disk so your clients don't stress the provider's servers on every playlist reload.
reverse_proxy:
cache:
enabled: true
size: 1GB
directory: ./cache
An LRU (Least Recently Used) disk cache. If it hits the limit (e.g., 1GB), Tuliprox automatically deletes the oldest images.
Note: Fails if resource_rewrite_disabled is true.
3. Rate Limiting (rate_limit)
reverse_proxy:
rate_limit:
enabled: true
period_millis: 500
burst_size: 10
Implements an IP-based Token-Bucket rate limiter. In this example, an IP can fire 10 requests immediately (burst_size). After
that, it receives exactly one new token every 500ms (period_millis). This prevents DDOS attacks from malfunctioning scrapers.
(Ensure your upstream Nginx/Traefik passes X-Forwarded-For for this to work correctly!)
4. Header Stripping (disabled_header)
When Tuliprox makes requests to the upstream provider, it can strip revealing headers that might expose which player you are actually using or the fact that you are proxying traffic.
reverse_proxy:
disabled_header:
referer_header: true # Removes the 'Referer' header
x_header: true # Removes all 'X-*' headers (like X-Real-IP)
cloudflare_header: true# Removes 'CF-*' headers
custom_header:
- my-custom-tracker
5. Resource Retries (resource_retry)
Defines how aggressively Tuliprox tries to retry failed logo or EPG downloads when proxying them from the provider.
reverse_proxy:
resource_retry:
max_attempts: 3
backoff_millis: 250
backoff_multiplier: 1.5
failover_redirect_patterns:
- "service-abuse"
- Retries: After the first error, Tuliprox waits 250ms. After the second error, it waits
250 * 1.5 = 375ms, and so on. failover_redirect_patterns: A list of Regex patterns. If an upstream resource responds with an HTTP Redirect (302) containing these patterns (e.g., pointing to a "service-abuse" warning image from the provider), Tuliprox treats it as a failure instead of blindly serving the abuse image to your clients.
6. GeoIP Resolution (geoip)
To see the country flags of connected clients in the Web UI ("Active Streams" tab), Tuliprox can resolve IP addresses locally.
reverse_proxy:
geoip:
enabled: true
url: "https://raw.githubusercontent.com/sapics/ip-location-db/refs/heads/main/asn-country/asn-country-ipv4.csv"
The CSV file must have exactly 3 columns: range_start,range_end,country_code. (The DB is periodically updated via the
schedules block using the GeoIpUpdate task type).
Additional Information
The "VLC Seek Problem" & Grace Periods
When a user fast-forwards or rewinds a VOD, the player calculates the new byte offset, drops the old TCP connection, and
immediately fires a new HTTP GET request (with a Range header) to Tuliprox.
The Problem: It takes milliseconds to seconds for the upstream provider to realize the old connection is dead. If you have
a max_connections: 1 limit at the provider, they will view this new seek-request as a second concurrent stream and reject
it with an HTTP 509 (Bandwidth Exceeded) or HTTP 401 error.
The Tuliprox Solution:
grace_period_millis: 2000: Tuliprox grants the user a temporary over-allocation (Grace) for exactly this duration.grace_period_hold_stream: true: Tuliprox artificially holds back the video data to the client, waiting for the grace check to finish, so it doesn't trigger the provider prematurely.- After the milliseconds expire, Tuliprox checks internally: Is the old connection truly gone now? If Yes ➔ Data flows.
If No ➔ The new connection is hard-killed (serving the
user_connections_exhausted.tsvideo) because the user is actually illegally watching twice. grace_period_timeout_secs: 4: A hard timeout limit for overlapping "ghost sessions" to expire.
Session TTLs for HLS (.m3u8) & Catchup
HLS streams do not consist of an endless TCP pipe. Instead, the player downloads small .ts segments every few seconds
(e.g., seg1.ts, seg2.ts).
If Tuliprox released and re-acquired the provider slot for every single segment, providers would block the account for "Account Hopping" or spam. Tuliprox simulates a continuous session:
hls_session_ttl_secs: 15: After a.tssegment finishes downloading, the physical slot to the provider is closed, but the "Virtual Slot" for this specific user remains reserved for 15 seconds. No other user can steal this slot during this window. Channel switches from the same client can immediately take over the reservation.- The same principle applies to Archive/Catchup TV (
catchup_session_ttl_secs: 45), which shares the same fragmentation and seeking issues.
Shared Live Streams
Tuliprox can share a live stream (share_live_streams: true in the target options of source.yml). If 5 users watch the same
Live-TV channel, Tuliprox pulls the stream only 1x from the provider and multicasts the bytes locally to 5 clients.
To ensure a user who tunes in 10 seconds later doesn't get player errors due to missing I-Frames/Keyframes, Tuliprox
continuously keeps the last X Megabytes (shared_burst_buffer_mb, default 12) in RAM. It fires this burst buffer at new
subscribers so their decoders can instantly synchronize.