Skip to content

Releases: freitasjca/horse-provider-mormot

v1.0.7 — Horse 3.3.0 required

Choose a tag to compare

@freitasjca freitasjca released this 04 Aug 10:55

What's changed

Breaking dependency requirement

  • Horse ≥ 3.3.0 — all previously fork-only Horse patches (IHorseRawRequest / IHorseRawResponse, HORSE_PROVIDER_* define normalization, request/response shadow fields) are now included in the official HashLoad/horse 3.3.0 release. The freitasjca/horse fork is retired — remove it from your boss.json and point at hashload/horse directly.

boss.json

"github.com/HashLoad/horse": ">=3.3.0"

Integration test client

Added HorseMormotTestClient — companion to the existing test server, mirrors the CrossSocket provider test suite structure.

v1.0.6

Choose a tag to compare

@freitasjca freitasjca released this 12 Jul 11:42

Requires horse >=3.2.101 (upstream 3.2.1 sync): implements IHorseRawRequest.PopulateHeaders, drops Web.HTTPApp from the request bridge (TMethodType now in Horse.Commons), adds the Listen overload family with bind-host support (socket backends use mORMot's host:port syntax; http.sys ignores host).

v1.0.5

Choose a tag to compare

@freitasjca freitasjca released this 01 Jul 16:32

TLSOPT-1/2 config fields (SSLKeyPassword, SSLCipherList) in Mormot.Config.pas; mORMot provider updates; TLS integration tests + certs; implementation notes + middleware compatibility docs

v1.0.4 — RFC 6265 cookie emission

Choose a tag to compare

@freitasjca freitasjca released this 24 Jun 21:48

BuildHeaders appends one 'Set-Cookie: ' line per Res.Cookie(...)/AddCookie entry to OutCustomHeaders (CRLF-joined, so multiple cookies are preserved); all attributes
incl. Max-Age round-trip. Adds Section K cookie tests and Section J wildcard SendFile tests (Delphi .dpr + Lazarus .lpr). Requires horse >=3.1.104.

v1.0.3

Choose a tag to compare

@freitasjca freitasjca released this 22 Jun 18:18

Ownership-aware multipart AddStream (PATCH-PARAM-1) resolving the file-part TMemoryStream leak; new response stream helpers (TryReadBodyStream /
ReleaseRawResponseContentStream); FPC PopulateMultipartFiles for RawWebRequest.Files; param/stream/multipart test suites for Delphi and Lazarus/FPC; implementation-notes doc update.

v1.0.2 — Multi-backend HTTP server + FPC/Lazarus compatibility

Choose a tag to compare

@freitasjca freitasjca released this 14 Jun 21:17

What's new

Multi-backend HTTP server

The provider now supports all three mORMot2 HTTP server backends, selectable via THorseMormotConfig.ServerKind or compile-time defines:

ServerKind mORMot class Model
mskThreadPool (default) THttpServer Socket thread-pool
mskAsync THttpAsyncServer Non-blocking IOCP/epoll/kqueue event loop
mskHttpApi THttpApiServer Windows http.sys kernel-mode (Windows only)

Switch at runtime: Cfg.ServerKind := mskAsync; THorse.ListenWithConfig(9000, Cfg);
Or at compile time: -dHORSE_MORMOT_ASYNC / -dHORSE_MORMOT_HTTPAPI.

FPC/Lazarus compatibility

  • Replace TInterlocked.* (Delphi-only RTL) with InterlockedIncrement / InterlockedDecrement / InterlockedCompareExchange free functions — the provider now compiles under
    FPC 3.2.0+.
  • Minimum FPC version: 3.2.0 (Lazarus 2.2+ stable) — no trunk required (unlike the CrossSocket provider).

Lazarus IDE setup docs

Full step-by-step Lazarus setup added to README and doc/building-a-mormot-provider.md: mormot2 package compile, LazUtils dependency, search paths, static blob linker path, and the
TNextProc vs TProc distinction for FPC middleware.

Breaking changes

None — existing THorse.Listen(port) calls continue to use THttpServer (thread-pool) by default.

v1.0.0 — Initial release

Choose a tag to compare

@freitasjca freitasjca released this 01 Jun 16:10

v1.0.0 — Initial release

First public release of horse-provider-mormot — a mORMot2-backed transport provider for the Horse web framework.

What this is

A drop-in alternative to Horse's default Indy transport, activated by a single compiler define:

{$DEFINE HORSE_PROVIDER_MORMOT}

uses Horse;
begin
  THorse.Get('/ping', procedure(Req: THorseRequest; Res: THorseResponse)
  begin
    Res.Send('pong');
  end);
  THorse.Listen(9000);
end.

Routes, middleware, and THorseRequest / THorseResponse API are unchanged — switching transports does not require rewriting handlers. The mORMot2 THttpServer runs underneath instead of Indy's thread-per-connection model.

What's included

  • Hybrid interface architectureIHorseRawRequest / IHorseRawResponse with backward-compatible TInterfacedWebRequest / TInterfacedWebResponse adapters so every existing Horse middleware (CORS, JWT, Jhonson, …) works unchanged.
  • Pre-pipeline request validation — URL length, header limits, body size, method allowlist, request-smuggling guards before the Horse pipeline is entered.
  • Pooled THorseContext — pre-warmed object pool, zero allocation on the hot path, Reset wipes every security-sensitive field between requests.
  • Graceful drain on shutdownSEC-30 active-request counter; Listen returns only after in-flight requests complete.
  • Application-type cross-product units — Console (default), VCL, Daemon (Windows Service + Linux daemon in one unit), FPC.Daemon, FPC.LCL, FPC.HTTPApplication. Same .dpr compiles for both Windows and Linux targets.
  • TLS via OpenSSL — both libssl 1.1.x and 3.x accepted at runtime; mormot2static static-link variant supported for self-contained deployments.

mORMot2 interop notes

  • Loopback RemoteIP normalised — mORMot2 defaults RemoteIPLocalHostAsVoidInServers to True, reporting loopback connections with an empty RemoteIP. Horse middleware that consumes Req.RawWebRequest.RemoteAddr (rate limiters, audit loggers) needs a stable peer IP, so the provider sets this global to False at unit init. See doc/implementation-notes.md for the side effect this has on co-resident mORMot servers in the same process.
  • Multipart file uploadsMultiPartFormDataDecode returns inline RawByteString parts; the bridge synthesises a TMemoryStream per file part and routes it through ContentFields.AddStream. See Known limitations below.

Requirements

Dependency Version Notes
Delphi 10.4 Sydney or later Uses inline var, System.Threading
FPC 3.2.0 or later For the FPC.* application-type units
Horse >= 3.1.98 PATCH-HORSE-2 three-axis define release
mORMot2 recent master Install per synopse/mORMot2 instructions; on Delphi the mormot2static precompiled blobs are required

Installation

boss install horse-provider-mormot

mORMot2 itself is installed manually (clone + search paths). See the README for the full setup including the static-blob download.

Tested platforms

  • Windows x86 / x64 (IOCP; also http.sys via THttpApiServer swap)
  • Linux x64 (epoll)
  • macOS ARM64

Known limitations

  • [FOLLOW-UP-MEM-1] — multipart-with-file uploads leak one TMemoryStream per request until the pool is torn down. Functionally correct (uploads work, content arrives intact), but memory accumulates under sustained upload load. Two proper fixes (pool-side stream tracking, or a Horse upstream TObjectDictionary([doOwnsValues]) patch) are documented in doc/implementation-notes.md — appropriate for low-throughput services, dev/test, and short-lived processes; not yet appropriate for high-throughput production upload endpoints.

Documentation

Acknowledgements