A small rendezvous + signaling + object service for peer‑to‑peer file transfer apps.
- Rendezvous codes → one‑time room (
appID, UUID) - WebSocket signaling →
/ws?appID=<uuid>&side=A|B - Object storage (optional) → create / put blob / put manifest / commit / get
- No client secrets: prod gates on
appIDbeing a UUID (simple capability) - Metrics: Prometheus / Grafana ready
- Config: env + flags, tested (
internal/config)
go build ./noisytransferdNT_DEV=1 ./noisytransferd \
-addr :1234 \
-base http://127.0.0.1:1234 \
-cors "http://127.0.0.1,http://localhost"./noisytransferd \
-addr :1234 \
-base https://relay.example \
-cors "https://app.example" \
-upload_max_mb 128docker build -t noisytransferd .
docker run --rm -p 1234:1234 \
-e NT_BASE_URL=http://127.0.0.1:1234 \
-e NT_DEV=1 \
noisytransferdFlags and env vars (flags override env; both override sensible defaults).
| Flag | Env | Default | Notes |
|---|---|---|---|
-addr |
NT_ADDR |
:1234 |
HTTP listen address |
-base |
NT_BASE_URL |
http://localhost:1234 |
Public base URL used in responses |
-cors |
NT_CORS |
http://127.0.0.1,http://localhost |
Comma‑sep Origins; no * in prod |
-data |
NT_DATA_DIR |
./data |
Filesystem root for objects |
-gc_ttl |
NT_GC_TTL |
24h |
TTL for object GC |
-dev |
NT_DEV |
false |
Dev mode (looser WS origin etc.) |
-turn |
NT_TURN |
false |
Embedded TURN (dev/test) |
-upload_max_mb |
NT_UPLOAD_MAX_MB |
64 |
Per‑request upload cap; <=0 disables |
Server timeouts are set in internal/config and can be adjusted if needed.
POST /rendezvous/code→{ "code": "...", "appID": "<uuid>", "expiresAt": "..." }POST /rendezvous/redeembody{ "code": "..." }→{ "status": "ok|waiting|expired|not_found", "appID"?, "expiresAt"? }
GET /ws?appID=<uuid>&side=A|B- In prod,
appIDmust be a UUID. - Per‑IP and per‑
appIDrate limits apply.
- In prod,
POST /objects→{ "objectId": "<uuid>", "uploadUrl": ".../blob", "manifestUrl": ".../manifest" }(orLocation: /objects/{id})PUT /objects/{id}/blobPUT /objects/{id}/manifestPOST /objects/{id}/commitGET /objects/{id}/blobHEAD /objects/{id}/blob
The appID is a coarse, short‑lived capability. For stricter auth (and public exposure), add signed URLs/JWT later.
Exposed at /metrics (Prometheus). Useful counters include:
noisytransfer_ws_auth_failures{reason="bad_appid"}noisytransfer_ws_rate_limited{dim="ip|app"}
Grafana dashboard JSON and Prometheus config are under deploy/.
make check # fmt, tidy, lint, unit tests, vuln scan
make test # go test -race ./...
make test-e2e # end‑to‑end tests (object lifecycle, WS)E2E coverage includes:
- Object lifecycle (create → blob → manifest → commit → get/head)
- WS (prod): missing / invalid / valid appID
- Objects (prod): require appID, allow UUID
- No client secrets shipped. Prod gates on UUID appID only
AGPL‑3.0 — see LICENSE.