mORMot2 DailyDaily read of upstream commits

HTTP clients and WebSockets settle after a broad ECC optimization pass

This edition closes several HTTP.sys WebSocket lifecycle gaps and corrects response-header handling across WinINet, WinHTTP, Delphi's HTTP client and libcurl. The same batch rewrites many ECC P-256 arithmetic paths for ARM, i386 and x86-64, while restoring Delphi 7/2007 and Delphi POSIX compilation. POSIX Kerberos users must also account for two public keytab signature changes.

TL;DR

  • Use build 2.4.17531: it includes the completed HTTP-client header series and all compatibility follow-ups.
  • Builds 2.4.17513 through 2.4.17515 contain a stray bare fixme token in mormot.core.base and should not be used.
  • TServerSspiKeyTab.PrepareKeyTab now returns boolean, and ServerForceKeytab now accepts RawUtf8 instead of TFileName.
  • HTTP.sys WebSocket cleanup, idle callbacks, ping tracking and failed-send handling were revised across seven commits.

Upgrade advice

Land on build 2.4.17531 rather than an intermediate revision. Recompile callers of TServerSspiKeyTab.PrepareKeyTab and ServerForceKeytab, then retest HTTP.sys WebSocket shutdown, rejected sends, idle callbacks, redirected libcurl requests and Windows client response headers. Do not use builds 2.4.17513-2.4.17515 because mormot.core.base contains an invalid bare fixme token.

Build2.4.17497 → 2.4.17531
Commits33
Lines+3540 -1049
Read7 min

30 of 30 entries · 33 commits upstream

# Entry Category Units
1 High POSIX keytab handling becomes locked, UTF-8 aware and result-bearing TServerSspiKeyTab protects its file name and sequence with fSafe, converts TFileName to UTF-8 before GSSAPI registration and preserves the active keytab when a replacement is invalid. PrepareKeyTab becomes a boolean function and ServerForceKeytab now takes RawUtf8. Breaking changes mormot.lib.gssapi 4059a7dd+53-38

lib: several TServerSspiKeyTab fixes

Impact

Direct callers must recompile for both signature changes. Delphi POSIX file names are passed to GSSAPI with the required UTF-8 encoding, and concurrent readers no longer observe an unprotected keytab name.

Migration required

Search for PrepareKeyTab and consume or deliberately ignore its boolean result; pass UTF-8 RawUtf8 values to direct ServerForceKeytab calls. Use build 2.4.17505 or later.

Public API

  • TServerSspiKeyTab.PrepareKeyTabsignature-changed — The procedure becomes function PrepareKeyTab: boolean.
  • ServerForceKeytabsignature-changed — The parameter changes from TFileName to UTF-8 RawUtf8.

Arnaud Bouchez · 09:15 UTC · view the commit on GitHub →

2 High Record alignment cleanup briefly leaves mormot.core.base uncompilable Several naturally sized records lose packed to improve ARM access alignment, including THash128Rec, THash256Rec, THash512Rec, TDebugSymbol and TDebugBlock. The same diff accidentally inserts a bare fixme token before InterlockedIncrement. Breaking changes mormot.core.base+3 b66d0984+13-13

core: don't use "packed record" unless really needed

Impact

Builds 2.4.17513 through 2.4.17515 cannot compile mormot.core.base because fixme is parsed as invalid Pascal. At a fixed build, ARM accesses may be faster; raw record-layout consumers should still rebuild together.

Public API

  • THash128Rec, THash256Rec, THash512Rec, TDebugSymbol, TDebugBlock and related recordsbehaviour-changed — The packed modifier is removed where natural alignment is sufficient; rebuild binary-layout consumers.

Arnaud Bouchez · 14:37 UTC · view the commit on GitHub →

3 High HTTP.sys response failures and WebSocket teardown become observable and bounded HttpSendResponse and SendResponse now return actual submission success, static-file and invalid Range paths exit immediately, failed WebSocket handshakes free native handles, disconnect callbacks run only after connection and server teardown waits at most five seconds. Fixes mormot.net.server cc55fa88+58-40

net: several THttpApiServer/THttpApiWebSocketServer fixes

Impact

HTTP.sys callers no longer treat failed response submission as success, invalid files and ranges stop processing, partial WebSocket upgrades do not leak handles and shutdown cannot wait forever for connections.

Arnaud Bouchez · 06:39 UTC · view the commit on GitHub →

4 High HTTP.sys WebSocket sends fail closed and action queues keep draining Broadcast catches per-connection send exceptions and begins closure, active and closed state sets are centralized, shutdown skips already closed connections, and ProcessActions continues after completing non-send actions without double completion. Fixes mormot.net.server 6e02ccef+37-25

net: some http.sys WebSockets fixes

Impact

One broken WebSocket no longer aborts a broadcast, failed sends are reported through the boolean result and receive/close actions are less likely to stall or complete twice.

Arnaud Bouchez · 06:55 UTC · view the commit on GitHub →

5 High Keytab registration retries after a per-thread GSSAPI failure PrepareKeyTab now copies the main sequence under lock but updates the threadvar sequence only after ServerForceKeytab succeeds. SetKeyTab performs file-change checks and FileIsKeyTab validation while holding fSafe. Fixes mormot.lib.gssapi 0a647b66+29-21

lib: minor TServerSspiKeyTab fixes

Impact

Heimdal or transient registration failures are retried on the same thread instead of being treated as prepared, and concurrent refresh cannot race the cached file metadata.

Arnaud Bouchez · 09:33 UTC · view the commit on GitHub →

6 High New ARM assembly selectors also repair the broken core declaration mormot.defines.inc introduces ASMARM64 and ASMINTELARM and consistently clears them under NOASMBLOCK. mormot.core.base adopts ASMINTELARM for atomic declarations and removes the stray bare fixme token added in build 17513. Fixes mormot.core.base+1 6f93fc70+24-16

core: new ASMINTELARM/ASMARM64 conditionals

Impact

Builds 2.4.17513 through 2.4.17515 contain invalid Pascal in mormot.core.base; build 2.4.17516 restores compilation and supplies stable architecture selectors for later ECC assembly.

Arnaud Bouchez · 14:51 UTC · view the commit on GitHub →

7 High HTTP.sys servers regain periodic logging, telemetry and OnIdle THttpApiServer creates a TSynBackgroundThreadProcess named HttpApiIdle, calls virtual DoIdle every second with monotonic times and frees the worker before its main teardown. Fixes mormot.net.server df25cd22+25-6

net: fixed logger + telemetry + OnIdle() support in THttpApiServer

Impact

Windows HTTP.sys backends once again flush logs, consolidate telemetry, invoke OnIdle and run blacklist/keytab maintenance even without request traffic.

Arnaud Bouchez · 09:54 UTC · view the commit on GitHub →

8 High libcurl now exposes only the final response headers TCurlHttp installs CurlWriteLastResponseHeader as its header callback. The callback clears the accumulated block whenever a new HTTP status line starts, then appends the current response headers. Fixes mormot.net.client b9bdb628+16-3

net: fix TCurlHttp intermediate response headers

Impact

Redirects and other multi-response exchanges no longer leave intermediate headers mixed into TCurlHttp.Header; callers inspect the headers belonging to the final status code.

Arnaud Bouchez · 09:32 UTC · view the commit on GitHub →

9 High Windows request headers keep valid Unicode storage and clean names TWinHttp.InternalAddHeader keeps the Utf8ToSynUnicode result in a local SynUnicode variable and passes its actual wide-character length. TDelphiNetHttp.InternalAddHeader trims header names and values separately. Fixes mormot.net.client 59a88c92+11-7

net: TWinHttp and TDelphiNetHttp client fixes

Impact

TWinHttp avoids a temporary-string pointer and UTF-8/wide-length mismatch, while Delphi's client no longer forwards surrounding whitespace in parsed custom headers.

Arnaud Bouchez · 09:23 UTC · view the commit on GitHub →

10 High Delphi 7 and 2007 keep a compatible P-256 reduction fallback _modMultN is split by HASQWORD. Modern compilers use Barrett reduction, while Delphi 7/2007 retain the earlier shift-and-subtract algorithm that does not require unsigned UInt64 semantics. Compiler & platform mormot.crypt.ecc256r1 597b691f+61-7

crypt: circumvent Delphi 7/2007 compiler restriction

Impact

Legacy Delphi builds compile and continue producing P-256 results through the slower proven path. Newer backends keep the optimized reducer.

Arnaud Bouchez · 17:21 UTC · view the commit on GitHub →

11 High Delphi POSIX builds regain the wide multiply helper mormot.core.base adds a Delphi implementation of mul64x64 outside the FPC branch. ECC carry expressions also receive explicit ordinal and PtrUInt/QWord conversions accepted by Delphi POSIX. Compiler & platform mormot.core.base+2 c763b013+23-9

crypt: fixed Delphi POSIX compilation

Impact

Delphi POSIX targets compile the new ECC arithmetic again. The change is compiler compatibility only and does not alter application APIs.

Arnaud Bouchez · 17:29 UTC · view the commit on GitHub →

12 High Delphi HTTP header trimming compiles across supported compilers TDelphiNetHttp.InternalAddHeader now writes TrimCopy results into explicit RawUtf8 variables before converting them to string for THTTPClient.AddHeader. Compiler & platform mormot.net.client 0a8341fb+8-5

net: fixed TDelphiNetHttp header trimming compilation

Impact

The previous inline use of the procedure-style TrimCopy overload could not compile; Delphi backends using TDelphiNetHttp build again without changing application code.

Arnaud Bouchez · 09:26 UTC · view the commit on GitHub →

13 Medium HTTP.sys WebSocket closure and ping bookkeeping share one path THttpApiWebSocketConnection.DoClose centralizes close status, context and BeginClose calls. Ping timestamps are recorded before sending, ping/pong sends no longer renew normal activity and repeated close sites use DoClose. Fixes mormot.net.server 303139a2+23-29

net: new THttpApiWebSocketConnection.DoClose internal method

Impact

Idle WebSocket connections are not kept alive merely by server pings, and failure paths produce consistent close state. No application API changes.

Worth a look

Arnaud Bouchez · 10:33 UTC · view the commit on GitHub →

14 Medium WinINet and WinHTTP stop returning the HTTP status line as a header RemoveHeadInHeaders trims whitespace and removes a leading HTTP status line. TWinHttpApi.InternalRetrieveAnswer and TCurlHttp both apply it before exposing or parsing response headers. Fixes mormot.net.client e46374f3+21-12

net: fixed WinINet/WinHttp retrieved headers

Impact

Callers receive a normalized header block instead of a pseudo-header containing HTTP/1.x status text. Header lookups become consistent across Windows and curl clients.

Arnaud Bouchez · 08:02 UTC · view the commit on GitHub →

15 Medium WebSocket buffers and action queues survive callback failures DoOnMessage clears fBuffer in a finally block, ProcessActions continues after completing a send action instead of falling through, and UpgradeToWebSocket trims each requested subprotocol name. Fixes mormot.net.server a2fab1d6+8-9

net: minor THttpApiWebSocketServer tweaks

Impact

A user OnMessage exception no longer leaves stale payload for the next message, send completions do not corrupt action processing and spaced protocol lists negotiate correctly.

Arnaud Bouchez · 09:43 UTC · view the commit on GitHub →

16 Medium HTTP servers expose one virtual idle-maintenance hook THttpServerGeneric adds protected virtual DoIdle(tix64, sec32). Socket servers move logger, analyzer, OnIdle, blacklist and POSIX keytab maintenance into overrides, and the async server reuses that path. New features mormot.defines+2 ddb42855+37-42

net: new THttpServerGeneric.DoIdle virtual method

Impact

Server subclasses can extend periodic maintenance consistently, while existing socket and async backends retain their callbacks through the shared implementation.

Worth a look

Public API

  • THttpServerGeneric.DoIdleadded — Protected virtual procedure DoIdle(tix64: Int64; sec32: cardinal) centralizes periodic server work.

Arnaud Bouchez · 09:42 UTC · view the commit on GitHub →

17 Medium i386 receives native 128-bit and 256-bit multiplication mormot.crypt.core.asmx86 adds _mult128 and _mult256 implementations. The Pascal unit routes all ASMINTEL targets, including i386, to native multiply and square routines. Performance mormot.crypt.core+1 afce8c72+602-98

crypt: new i386 asm for _mult256() and _mult128()

Impact

32-bit Intel/AMD ECC operations avoid the generic Pascal multiplication path. Application source and cryptographic wire formats are unchanged.

Arnaud Bouchez · 17:20 UTC · view the commit on GitHub →

18 Medium Intel P-256 prime reduction moves into architecture assembly _mmodP is declared in mormot.crypt.core for ASMINTEL and implemented in the i386 and x86-64 include files. mormot.crypt.ecc256r1 keeps its Pascal reducer only for non-Intel targets. Performance mormot.crypt.core+3 15884e94+497-4

crypt: x86_64/i386 asm specific mormot.crypt.ecc256r1 computation of _mmodP

Impact

P-256 multiplication on i386 and x86-64 uses architecture-specific modular reduction. Public keys, signatures and APIs do not change.

Arnaud Bouchez · 16:27 UTC · view the commit on GitHub →

19 Medium ARMv7 atomics gain barrier-correct native implementations The AArch64 include is renamed mormot.core.base.asmarm.inc and extended with ARMv7 LDREX/STREX loops surrounded by DMB ISH. ASMARM selects these routines on AArch64 and ARMv7+ with CPUARM_HAS_DMB. Performance mormot.core.base+2 a1079132+320-164

core: ARMv7 asm for Locked*() - in a single mormot.core.base.asmarm.inc

Impact

FPC ARMv7 locks and reference counters keep full memory-barrier semantics with fewer RTL barrier calls. Older ARM targets remain on the guarded RTL fallback.

zen010101 · 08:22 UTC · view the commit on GitHub →

20 Medium ARMv8 receives unrolled wide-integer arithmetic for ECC mormot.core.base.asmarm.inc adds AArch64 add, subtract, shift and 128/256-bit multiply routines. mormot.crypt.core selects them through ASMARM64 instead of compiling the slower Pascal equivalents. Performance mormot.core.base+2 284915df+357-44

crypt: new unrolled ARMv8 64-bit asm for 128-bit and 256-bit computation

Impact

AArch64 Delphi/FPC cryptographic workloads use native wide arithmetic, primarily accelerating ECC internals without changing application code.

Arnaud Bouchez · 14:52 UTC · view the commit on GitHub →

21 Medium AArch64 gains a dedicated P-256 prime reduction routine ASMARM64 now publishes an AArch64 _mmodP implementation from mormot.core.base.asmarm.inc, and mormot.crypt.ecc256r1 excludes the Pascal implementation on that target. Performance mormot.core.base+2 1dec0f83+153-2

crypt: specific mormot.crypt.ecc256r1 computation in pure aarch64 asm

Impact

ECC P-256 multiplication and signing internals run through native AArch64 reduction. Public ECC formats and application calls remain unchanged.

Arnaud Bouchez · 19:48 UTC · view the commit on GitHub →

22 Medium P-256 scalar reduction switches to Barrett arithmetic mormot.crypt.ecc256r1 adds BARRETT_N_MU_LOW and replaces the bit-by-bit Curve_N_32 reduction in _modMultN with a fixed-width Barrett reduction followed by at most two masked subtractions. Performance mormot.crypt.ecc256r1 49108d2f+81-51

crypt: use Curve_N_32 Barret Reduction algorithm for ecc256r1

Impact

ECDSA scalar multiplication and signing perform fewer data-dependent reduction steps on modern compilers. Cryptographic outputs are intended to remain identical.

Worth a look

Arnaud Bouchez · 16:26 UTC · view the commit on GitHub →

23 Medium HTTP.sys WebSocket pings move onto the server idle cycle THttpApiWebSocketServer removes TSynWebSocketGuard and overrides DoIdle to scan protocol connections. It tracks last activity and last ping separately, refreshes activity after receives and non-ping sends, and makes PingTimeout writable. Under the hood mormot.net.server 39a07c59+62-88

net: refactored http.sys WebSockets PING process

Impact

Ping timeout enforcement now shares the server's one-second idle thread and treats successful application sends as activity. Existing code can also change PingTimeout after construction.

Worth a look

Public API

  • THttpApiWebSocketServer.PingTimeoutbehaviour-changed — The property gains a write accessor, and timeout checks run from DoIdle instead of TSynWebSocketGuard.

Arnaud Bouchez · 10:10 UTC · view the commit on GitHub →

24 Low P-256 squaring uses dedicated Intel and AMD assembly Native _square256 implementations are added to the i386 and x86-64 include files, and mormot.crypt.core no longer implements Intel squaring by calling _mult256. Performance mormot.crypt.core+2 f6c7eed7+506-13

crypt: native i386/x64 asm version of _square256()

Impact

ECC arithmetic on 32-bit and 64-bit Intel/AMD targets uses a specialized square path. No application source or serialized data changes.

Arnaud Bouchez · 18:02 UTC · view the commit on GitHub →

25 Low Wide integer comparison is specialized for x86-64 and AArch64 _cmp256 moves to native implementations for ASMX64 and ASMARM64, while the Pascal comparison remains for other CPU64 targets. A comment also clarifies why TSynAngelizeState stays packed. Performance mormot.app.agl+4 7023137e+70-25

crypt: x64 and aarch64 asm for _cmp256() function

Impact

ECC comparisons become cheaper on x86-64 and AArch64. The TSynAngelizeState binary layout and all public application behavior remain unchanged.

Arnaud Bouchez · 16:25 UTC · view the commit on GitHub →

26 Low P-256 modular inversion performs fewer wide comparisons _modInv delays _cmp256 until both operands are odd, replaces compare-then-subtract pairs with _sub256 borrow results and uses _inc256 for in-place additions. Performance mormot.crypt.ecc256r1 a83aa6a6+38-33

crypt: slightly optimized _modInv() for ecc256r1

Impact

Pure-Pascal and non-specialized ECC backends reduce internal work during inversion; signatures, keys and public behavior stay the same.

Arnaud Bouchez · 18:13 UTC · view the commit on GitHub →

27 Low The pure-Pascal 256-bit multiplier reduces loop overhead _mult256 now selects each diagonal with pointer starts and an explicit iteration count, combines carry terms directly and writes through PQWordArray instead of repeatedly testing loop indices. Performance mormot.crypt.core e657f90d+21-25

crypt: faster pure pascal _mult256() algorithm

Impact

Targets without specialized assembly, especially ARM at this point in the series, perform internal ECC multiplication with less Pascal-loop overhead. APIs are unchanged.

Arnaud Bouchez · 14:49 UTC · view the commit on GitHub →

28 Low DoubleToAscii uses native wide multiplication on ARM The Grisu d2a_diy_fp_multiply path now uses ASMINTELARM and mul64x64 on ARMv7 and AArch64, and accesses the normalization word through PQWordArray. Performance mormot.core.text 0fe4797b+6-6

core: slightly faster DoubleToAscii() on arm32/aarch64

Impact

ARM Delphi and FPC backends format Double values with a faster internal multiply path; output format and public APIs do not change.

Arnaud Bouchez · 09:27 UTC · view the commit on GitHub →

29 Low FPC atomic wrappers are selected by CPU behavior instead of one broad branch mormot.core.base reorganizes the FPC Locked and Interlocked implementations: Intel uses a no-op ReadWriteBarrier around RTL atomics, AArch64 keeps its assembly include and other CPUs keep explicit barriers. FPC byte swaps and refcount helpers move into the common FPC branch. Under the hood mormot.core.base d1bb00c2+50-47

core: refactored FPC Locked*() functions

Impact

FPC Intel avoids redundant barriers while non-Intel targets preserve ordering. Public atomic function signatures and application code remain unchanged.

Arnaud Bouchez · 07:25 UTC · view the commit on GitHub →

30 Low Decimal128 conversion no longer triggers the FPC literal hint mormot.db.nosql.bson names the 100000000000000000 multiplier as the QWord constant BIGPOW10 and passes that typed constant to mul64x64 in TDecimal128.FromText. Housekeeping mormot.db.nosql.bson 42184b30+6-3

db: fixed FPC compiler hint in TDecimal128 process

Impact

FPC builds lose a compiler hint while Decimal128 parsing behavior and binary representation remain unchanged.

Arnaud Bouchez · 14:50 UTC · view the commit on GitHub →

Upstream activity commits per day · last 60 days
Commits977
Active days44/60
Busiest2026-09-30
Peak60
2026-08-15: 0 commits2026-08-16: 0 commits2026-08-17: 0 commits2026-08-18: 0 commits2026-08-19: 0 commits2026-08-20: 0 commits2026-08-21: 0 commits2026-08-22: 0 commits2026-08-23: 0 commits2026-08-24: 0 commits2026-08-25: 0 commits2026-08-26: 0 commits2026-08-27: 26 commits2026-08-28: 11 commits2026-08-29: 10 commits2026-08-30: 1 commit2026-08-31: 23 commits2026-09-01: 0 commits2026-09-02: 20 commits2026-09-03: 29 commits2026-09-04: 35 commits2026-09-05: 13 commits2026-09-06: 0 commits2026-09-07: 0 commits2026-09-08: 23 commits2026-09-09: 10 commits2026-09-10: 17 commits2026-09-11: 23 commits2026-09-12: 14 commits2026-09-13: 9 commits2026-09-14: 7 commits2026-09-15: 4 commits2026-09-16: 24 commits2026-09-17: 26 commits2026-09-18: 21 commits2026-09-19: 59 commits2026-09-20: 13 commits2026-09-21: 5 commits2026-09-22: 34 commits2026-09-23: 17 commits2026-09-24: 57 commits2026-09-25: 22 commits2026-09-26: 26 commits2026-09-27: 0 commits2026-09-28: 2 commits2026-09-29: 19 commits2026-09-30: 60 commits2026-10-01: 26 commits2026-10-02: 30 commits2026-10-03: 32 commits2026-10-04: 15 commits2026-10-05: 1 commit2026-10-06: 26 commits2026-10-07: 37 commits2026-10-08: 27 commits2026-10-09: 35 commits2026-10-10: 33 commits2026-10-11: 9 commits2026-10-12: 11 commits2026-10-13: 35 commits
2026-08-152026-10-13