mirror of
https://github.com/unshackle-dl/unshackle.git
synced 2026-11-12 20:15:10 +00:00
feat(tunnel): free finished tunnels at once and wait out 429s on --remote
A tunnel closed with code 1000 is freed without the 60s grace, a shared: true API key counts tunnels per X-Client-Id, and --remote waits out Retry-After and a full tunnel cap with a countdown; responses carry X-RateLimit-* headers.
This commit is contained in:
@@ -224,6 +224,19 @@ A limit comes from `serve.tiers.<name>.rate_limit` or from the API key's own
|
||||
[dashboard rate limits](dashboard.md#rate-limits) for the config and the counters, and
|
||||
[services configuration](../../reference/configuration/services.md) for the keys themselves.
|
||||
|
||||
Every response to an API key that has a limit carries these headers, the `429` too. A
|
||||
WebSocket or event stream response sends its headers before the handler returns, so it has none.
|
||||
The CORS headers expose these headers and `Retry-After` to a browser client.
|
||||
|
||||
| Header | Value |
|
||||
|---|---|
|
||||
| `X-RateLimit-Limit` | Requests per hour that the API key may make. |
|
||||
| `X-RateLimit-Remaining` | Requests left in the current window. |
|
||||
| `X-RateLimit-Reset` | Seconds until the window resets. |
|
||||
|
||||
A `--remote` client that gets a `429` with `Retry-After` shows a countdown, waits that time
|
||||
(one hour at most), and then sends the request again. It stops after 3 waits for one request.
|
||||
|
||||
!!! warning "`429` is not the `RATE_LIMITED` error body"
|
||||
`RATE_LIMITED` in [Errors](errors.md) is a *service* rate limit that a handler raises, and it
|
||||
arrives in the standard envelope with an `error_code`. The `429` here comes from the
|
||||
@@ -311,6 +324,7 @@ With `--caddy`, unshackle also starts `caddy run` using the `Caddyfile` located
|
||||
| Missing-header body | `{"status": 401, "message": "Secret Key is Empty."}` |
|
||||
| Invalid-key body | `{"status": 401, "message": "Secret Key is Invalid."}` |
|
||||
| Over-limit body | `{"status": 429, "message": "Rate limit exceeded."}`, plus a `Retry-After` header |
|
||||
| Rate limit headers | `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset` on each response to a limited API key |
|
||||
| Rate limit config | `serve.tiers.<name>.rate_limit`, overridden by `serve.users.<key>.rate_limit` |
|
||||
| Disable auth | `--no-key` (all requests allowed) |
|
||||
| Config location | `serve.api_secret` and `serve.users` in `unshackle.yaml` |
|
||||
|
||||
@@ -448,7 +448,7 @@ The server mounts all these routes, even in `--remote-only` mode. Paths use the
|
||||
| Method | Path | Purpose |
|
||||
|---|---|---|
|
||||
| `POST` | `/api/session/create` | Build + authenticate a service instance; returns a session ID immediately |
|
||||
| `GET` | `/api/tunnel` | WebSocket that relays the connections of a `tunnel:<id>` proxy to the client; `?id=` reconnects |
|
||||
| `GET` | `/api/tunnel` | WebSocket that relays the connections of a `tunnel:<id>` proxy to the client; `?id=` reconnects, close code 1000 frees the tunnel at once |
|
||||
| `GET` | `/api/tunnel/check?id=` | Exit IP address and lookup time through the caller's tunnel, for `unshackle tunnel-test` |
|
||||
| `GET` | `/api/session/{id}/titles` | Fetch and cache the title list |
|
||||
| `POST` | `/api/session/{id}/tracks` | Resolve tracks, manifests, chapters, headers/cookies for a title |
|
||||
|
||||
@@ -336,8 +336,10 @@ A service that uses a server account does not work with `--local-proxy`, because
|
||||
logs in with its own account. If the tunnel drops, the client connects again, and a new request
|
||||
from the server waits up to 10 seconds for it. A request that was in progress when the tunnel
|
||||
dropped fails. The server closes a tunnel when its client has not connected for 60 seconds, and
|
||||
the client then stops with `The tunnel to the server closed`. An API key can have 4 tunnels
|
||||
open at once.
|
||||
the client then stops with `The tunnel to the server closed`. A client that exits closes its
|
||||
tunnel at once. An API key can have 4 tunnels open at once (4 for each person on a key with
|
||||
`shared: true`, see [services configuration](../reference/configuration/services.md)). A fifth run waits for a free
|
||||
tunnel and tries again every 15 seconds, for one hour at most.
|
||||
|
||||
## Basic (static proxies)
|
||||
|
||||
|
||||
@@ -240,10 +240,17 @@ server vault with this grant, are the only source, and a missing content key sto
|
||||
|
||||
`admin` is a boolean that lets the API key run the maintenance endpoints (clear-cache, clear-temp, refresh-services). It is `false` unless the entry sets it. Keys that have no `users` entry, such as `api_secret`, keep that access.
|
||||
|
||||
`shared` is a boolean for an API key that a gateway in front of the server gives to many people.
|
||||
The gateway puts its own ID for each person in the `X-Client-Id` header, and the server then
|
||||
counts the `--local-proxy` tunnels of that API key for each person. Without `shared: true` the
|
||||
server ignores the header, because a client that connects to the server directly can set any
|
||||
value. Set it only when the gateway always replaces the header that the client sends.
|
||||
|
||||
A `tier` names an entry under `serve.tiers`, which holds the settings that several API keys
|
||||
share. Today a tier carries `rate_limit`, the requests per hour that API key may make; an API
|
||||
key can also set its own `rate_limit`, which wins over its tier's. An API key with neither has
|
||||
no limit. Going over the limit answers `429` with a `Retry-After` header. The server keeps a
|
||||
no limit. Going over the limit answers `429` with a `Retry-After` header, and a `--remote`
|
||||
client waits that time before it tries again. The server keeps a
|
||||
fixed window rather than a sliding one: it opens on the first request and resets an hour
|
||||
later. A `tier` that names no entry under `serve.tiers`, or a `rate_limit` that is not a
|
||||
positive whole number, stops the server at startup, because the alternative is an API key that
|
||||
@@ -341,6 +348,8 @@ serve:
|
||||
f3a4b5c6:
|
||||
services: [EXAMPLE1]
|
||||
server_vault: [EXAMPLE1] # the client's device licenses; the server vault still serves keys
|
||||
d7e8f9a0:
|
||||
shared: true # a gateway gives this key to many people; tunnels count per X-Client-Id
|
||||
```
|
||||
|
||||
!!! note "`dl` keys inside `serve`"
|
||||
|
||||
Reference in New Issue
Block a user