Skip to content

Unreleased Changes in The Mainline

Breaking Changes

Other Changes and Enhancements

  • New kumo.counter_series module exposing in-memory rolling counters backed by a fixed-size ring of time buckets. Useful for short-term, per-process bookkeeping of event rates from policy. Thanks to @kayozaki!
  • New message:import_headers method, a more flexible alternative to message:import_x_headers. Supports exact names and trailing-* wildcards, first/last/all match modes, optional removal of matched headers, and configurable name-transform styles (snake/kebab/camel/pascal case).
  • New accept_invalid_certs option on kumo.http.build_client that disables TLS certificate verification for the resulting client. Intended for development and testing against self-signed endpoints; see the reference for the security caveats. Thanks to @Fallmay! #504
  • The HTTP injection API now supports per-recipient metadata via a new metadata field on each recipient object. Key-value pairs supplied there are stored on the resulting message under the extra metadata key, accessible from Lua hooks via msg:get_meta('extra').
  • Documented a naming convention for user-defined message and connection meta keys: prefix application-specific keys with x_ to avoid collisions with current and future KumoMTA-predefined meta names. This aligns with the x_* keys produced by message:import_x_headers and the default snake_case transform used by message:import_headers; KumoMTA's own predefined meta keys will never start with x_. See the naming convention for details. Existing meta names continue to work; the x_ prefix is a recommendation, not a hard requirement.

Fixes

  • proxy-server: TCP keepalive is now configured on inbound and outbound sockets handled by the proxy listener, so unresponsive peers are detected and the connection is closed rather than left open indefinitely. The probe timing can be tuned (or keepalive disabled) via the new tcp_keepalive field on proxy.start_proxy_listener. Thanks to @jack-atlas! #509
  • A message with multipart/mixed as the root with multipart/related as a child part was not structurally parsed correctly, producing incorrect parts when using mimepart:get_simple_structure. Thanks to @kayozaki! #506
  • typing.lua: couldn't distinguish false from unset for a boolean field with default of true, such as those used in mail_auth.lua. Thanks to @kayozaki! #505
  • Regression with postmaster@domain style addresses and null sender addresses when constructing messages via kumo.make_message and its equivalent internal API. Thanks in part to @kayozaki! #511 #512