Runlight.Plug (runlight v0.1.0)

Copy Markdown View Source

The dashboard, its API, and the tracker as a Plug: the SDK's rl.routes(), the same answers byte for byte, so the dashboard, the MCP server, and every port's tools work against an Elixir app as they do against a Node one.

In Phoenix, forward to it outside the :browser pipeline (the routes have their own cross-site checks, and Phoenix's CSRF plug would refuse the tracker's posts):

# lib/my_app_web/router.ex
scope "/" do
  forward "/runlight", Runlight.Plug
end

and in a Plug.Router the same way. The base path is where the router mounted it. Options are Runlight.Routes's, plus :instance, the instance's name (default Runlight). Phoenix calls init/1 when the router compiles, so nothing is read there: the token and the instance are read on the first request.

A request on a link domain added in Settings, such as go.example.com, is answered with its redirect or a 404 before anything else, as every one of these Plugs does; on every other host the request carries on.

The connection's own address is passed on for the visitor's daily hash when no trusted proxy header names the client (see the instance's :trust_proxy).

A Phoenix endpoint's Plug.Parsers reads form and JSON bodies before the router forwards here. Those reach the routes as the client sent them, a form as a form and JSON as JSON, rebuilt from what the parsers made of them. To hand on the exact bytes instead, give the parsers this module's reader:

plug Plug.Parsers,
  parsers: [:urlencoded, :multipart, :json],
  json_decoder: Phoenix.json_library(),
  body_reader: {Runlight.Plug, :body_reader, []}

Summary

Functions

A body_reader for Plug.Parsers that keeps the bytes it reads, so a body the parsers have already read reaches the routes byte for byte.

Functions

body_reader(conn, opts)

@spec body_reader(Plug.Conn.t(), keyword()) ::
  {:ok, binary(), Plug.Conn.t()}
  | {:more, binary(), Plug.Conn.t()}
  | {:error, term()}

A body_reader for Plug.Parsers that keeps the bytes it reads, so a body the parsers have already read reaches the routes byte for byte.