Skip to content

Routing and mirroring ​

On http ports a rule can send matching requests to a different service instead, or send a copy of them somewhere and compare the two answers. Both are for the moment you have a fix for one endpoint and do not want to redeploy, or trust, the whole service yet.

route ​

yaml
- name: patched admin
  match: { path: '^/admin', method: 'GET|POST' }
  route: 19681          # host:port, or a bare port for something on this machine

Matching requests go to the patched copy; everything else carries on to the service untouched. The patched copy can be anything that speaks http: a container, a script, a second instance of the service with one handler changed.

mirror ​

yaml
- name: rewrite under test
  match: { path: '^/api/' }
  mirror: 19682

The client always gets the real service's answer. The copy goes out alongside, so a mirror that is slow, broken or missing costs the client nothing.

Status and body are compared, and a difference is logged as a warning naming the request and where the answers diverge. Headers are not compared, since dates and the like differ on every request. Matching answers are logged at debug. vulnboxd_mirror_total counts each outcome: agrees, body differs, status differs or unreachable.

A request that is routed and mirrored compares the copy against whatever actually served it.

Limitations ​

  • Both are settled from the head, before the body is read, so they can only use head conditions: method, path, headers and headers_opt, plus not.
  • A rule either redirects or edits: a route or mirror rule cannot have an action or change the message. Put blocks and rewrites in rules of their own; they still apply to routed requests.
  • A rule either routes or mirrors. To do both, use two rules.
  • They only apply to requests, so dir must be in, the default.
  • If several rules match, the first route and the first mirror win.
  • Mirroring holds the request and the answer in memory to replay and compare them, so keep it on routes whose messages fit limits.buffered_body. A larger answer is refused while a mirror is on it.