Skip to content

1.1.0 — Security, Telemetry & HTTP Compliance

Choose a tag to compare

@Maartz Maartz released this 29 Mar 08:17
· 32 commits to main since this release

What's New

Nexus 1.1.0 ships 10 new features across security, observability, HTTP compliance, and developer experience — with 76 new tests (448 total).

Security & Cryptography

  • Message Encryption — AES-256-GCM encrypt-then-sign with HKDF-derived keys. The MessageEncryption.encrypt/decrypt API produces compact base64url tokens (<nonce>.<ciphertext+tag>.<hmac>). This is the foundation for encrypted cookie sessions.
  • Key Generator — PBKDF2-HMAC-SHA256 key derivation for turning human passwords into cryptographic keys. Pure HMAC implementation works identically on Apple and Linux. Verified against RFC 7914 test vectors.

HTTP Compliance

  • Head Plug — Converts HEAD requests to GET before routing, then strips the response body via registerBeforeSend. Per RFC 9110 §9.3.2, headers like Content-Length and Content-Type are preserved. No more duplicate HEAD handlers or 404s.
  • Method Override — HTML forms only support GET and POST. The methodOverride() plug rewrites POST requests to PUT, PATCH, or DELETE when a _method form parameter (or query parameter) is present. Case-insensitive, security-constrained (only POST can be overridden, only to PUT/PATCH/DELETE).
  • Inform (103 Early Hints) — Queue informational 1xx responses with conn.inform(status:headers:). Multiple calls queue in order. Non-1xx statuses are silently rejected. Stored in assigns for adapter extraction.

Observability & Debugging

  • Telemetry — Emits <prefix>.request.duration (Timer) and <prefix>.request.count (Counter) via swift-metrics with method and status dimensions. Wraps the pipeline to capture errors too — thrown NexusHTTPError uses its status code, other errors use 500.
  • Debugger — Catches pipeline errors and renders a detailed HTML (or plain text) debug page showing the error type, message, request method/path/headers, query parameters, and connection assigns. Values for keys matching "secret", "password", "token", or "key" are automatically [REDACTED]. Development only.
  • RewriteOn — Rewrites conn.request.scheme, conn.request.authority, and remote IP from X-Forwarded-Proto, X-Forwarded-Host, and X-Forwarded-For headers. Selective opt-in via rewriteOn([.forwardedProto, .forwardedFor]). Essential for apps behind reverse proxies.

Developer Experience

  • Test Connection Recycling — TestConnection.recycle(previousConn, path: "/next") parses Set-Cookie response headers and injects them as a Cookie request header on a fresh connection. Cookies with Max-Age=0 are excluded. Explicit cookies merge with/override recycled ones.
  • Content Negotiation Fix — prefersHTML now defaults to true when the Accept header is missing, matching browser-default behavior for respondTo.

Dependencies

  • Added swift-metrics (>= 2.0.0) to the Nexus core target for the telemetry plug. This is an API-only dependency — no metrics backend is bundled.
  • Added NexusTest as a dependency of NexusTests for test recycling tests.

API Notes

telemetry() and debugger() are wrapper functions (like rescueErrors) rather than pipeline plugs, because they need to observe the full pipeline lifecycle including thrown errors:

let app = telemetry(debugger(pipeline([
    head(),
    rewriteOn([.forwardedProto, .forwardedFor]),
    requestId(),
    bodyParser(),
    methodOverride(),
    sessionPlug(SessionConfig(secret: key)),
    csrfProtection(),
    router.callAsFunction,
])))

Full Changelog

New files: Plugs/Head.swift, Plugs/MethodOverride.swift, Plugs/RewriteOn.swift, Plugs/Telemetry.swift, Plugs/Debugger.swift, MessageEncryption.swift, KeyGenerator.swift, Connection+Inform.swift, NexusTest/TestConnection+Recycle.swift

Modified: Package.swift (swift-metrics dep), Connection+Accept.swift (prefersHTML fix)

Test suites added: HeadTests (8), RewriteOnTests (10), DebuggerTests (12), TelemetryTests (7), MessageEncryptionTests (11), KeyGeneratorTests (9), InformTests (10), MethodOverrideTests (13), PrefersHTMLTests (14), TestRecycleTests (9)