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
appID
being a UUID (simple capability) - Metrics: Prometheus / Grafana ready
- Config: env + flags, tested (
internal/config
)
go build ./noisytransferd
NT_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 128
docker build -t noisytransferd .
docker run --rm -p 1234:1234 \
-e NT_BASE_URL=http://127.0.0.1:1234 \
-e NT_DEV=1 \
noisytransferd
Flags 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/redeem
body{ "code": "..." }
→{ "status": "ok|waiting|expired|not_found", "appID"?, "expiresAt"? }
GET /ws?appID=<uuid>&side=A|B
- In prod,
appID
must be a UUID. - Per‑IP and per‑
appID
rate limits apply.
- In prod,
POST /objects
→{ "objectId": "<uuid>", "uploadUrl": ".../blob", "manifestUrl": ".../manifest" }
(orLocation: /objects/{id}
)PUT /objects/{id}/blob
PUT /objects/{id}/manifest
POST /objects/{id}/commit
GET /objects/{id}/blob
HEAD /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
.