Mountable Plug relaying native Incus HTTP and optional WebSockets through host policy.
Mount it for the canonical native routes, before any body parser:
# Phoenix router: one root discovery route plus the /1.0 tree.
get "/", Opsmaru.Incus.Gateway.Plug, gateway: {MyHost.Gateway, :fetch, []}
forward "/1.0", Opsmaru.Incus.Gateway.Plug, gateway: {MyHost.Gateway, :fetch, []}:gateway is either an Opsmaru.Incus.Gateway or an {module, function, args} returning one at request time; prefer the MFA so runtime
configuration and the admission pid are never compiled into the router.
Routing uses the original encoded request_path and raw query_string, so
forward does not change what the backend receives. Only /, /1.0 and
/1.0/* are relayed; other paths fail with a native 404 and no backend
contact. If a body parser already consumed the request, the gateway
refuses it with 500 rather than relaying a reconstructed body.
Every request goes through Opsmaru.Incus.Gateway.Policy (admission,
readiness, authorization, expiry/revocation) before a backend socket opens.
Discovery and certificate trust use bounded host callbacks; authenticated
GET /1.0 buffers/replaces public identity. WebSockets use the optional
native WebSocket adapter when available; raw SFTP/NBD requires the host's
same-listener Cowboy gateway handler. Missing adapters fail with 501.
See docs/gateway.md for the verified protocol and mounting contract.
Response streaming is tested with Plug.Cowboy. When a response that has already started cannot be completed (backend loss, deadline, budget, revocation), the gateway ends the caller's HTTP/1.x connection without a final chunk, so the caller sees a truncated response rather than a complete one. On HTTP/2 it resets the stream.