立即处理可能影响正在运行的系统
HTTP 客户端与 WebSocket 在大规模 ECC 优化后趋于稳定
本期修复了多处 HTTP.sys WebSocket 生命周期问题,并纠正 WinINet、WinHTTP、Delphi HTTP 客户端与 libcurl 的响应头处理。同一批提交重写了 ARM、i386 与 x86-64 上的多条 ECC P-256 算术路径,同时恢复 Delphi 7/2007 和 Delphi POSIX 编译。POSIX Kerberos 用户还需处理两个公开 keytab 签名变化。
要点
- 应使用 build 2.4.17531:它包含完整的 HTTP 客户端响应头修复系列及全部兼容性后续修复。
- build 2.4.17513 至 2.4.17515 在 mormot.core.base 中含有孤立的 fixme token,不应使用。
- TServerSspiKeyTab.PrepareKeyTab 现在返回 boolean,ServerForceKeytab 的参数由 TFileName 改为 RawUtf8。
- HTTP.sys WebSocket 的清理、idle callback、ping 跟踪与发送失败处理在七个提交中被连续修订。
升级建议
应直接落在 build 2.4.17531,而不是中间版本。重新编译所有 TServerSspiKeyTab.PrepareKeyTab 与 ServerForceKeytab 调用,并复测 HTTP.sys WebSocket 关闭、发送失败、idle callback、libcurl 重定向及 Windows 客户端响应头。不要使用 build 2.4.17513-2.4.17515,因为 mormot.core.base 含有无效的孤立 fixme token。
30 条中的 30 条 · 上游 33 次提交
1
高
POSIX keytab 处理加入锁、UTF-8 与结果返回
TServerSspiKeyTab 用 fSafe 保护文件名与序列,在 GSSAPI 注册前把 TFileName 转为 UTF-8,并在替换文件无效时保留当前 keytab;PrepareKeyTab 改为 boolean function,ServerForceKeytab 改接收 RawUtf8。
破坏性变更
mormot.lib.gssapi
4059a7dd+53-38
lib: several TServerSspiKeyTab fixes
影响
直接调用方必须因两个签名变化重新编译;Delphi POSIX 文件名以 GSSAPI 所需 UTF-8 传递,并发读取也不再看到未保护的 keytab 名称。
需要迁移
搜索 PrepareKeyTab,并使用或显式忽略其 boolean 结果;直接调用 ServerForceKeytab 时传入 UTF-8 RawUtf8。请使用 build 2.4.17505 或更高版本。
公开 API
TServerSspiKeyTab.PrepareKeyTabsignature-changed — procedure 改为 function PrepareKeyTab: boolean。ServerForceKeytabsignature-changed — 参数从 TFileName 改为 UTF-8 RawUtf8。
2
高
记录对齐清理曾短暂导致 mormot.core.base 无法编译
多个自然尺寸 record 去掉 packed 以改善 ARM 访问对齐,包括 THash128Rec、THash256Rec、THash512Rec、TDebugSymbol 与 TDebugBlock;同一 diff 还意外在 InterlockedIncrement 前加入孤立的 fixme token。
破坏性变更
mormot.core.base+3
b66d0984+13-13
core: don't use "packed record" unless really needed
影响
build 2.4.17513 至 2.4.17515 因 fixme 被解析为无效 Pascal 而无法编译 mormot.core.base。修复后 ARM 访问可能更快;直接依赖 record 原始布局的组件仍应一起重建。
建议升级
不要停在 build 2.4.17513-2.4.17515;请使用 build 2.4.17516 或更高版本,并整体重建所有 unit。
公开 API
THash128Rec, THash256Rec, THash512Rec, TDebugSymbol, TDebugBlock and related recordsbehaviour-changed — 在自然对齐足够之处移除 packed;请重建依赖二进制布局的组件。
3
高
HTTP.sys 响应失败与 WebSocket 清理变得可观察且有时间上限
HttpSendResponse 与 SendResponse 返回真实提交结果;静态文件及无效 Range 路径立即退出;失败的 WebSocket handshake 释放原生 handle;仅连接成功后调用断开 callback;服务器清理最多等待五秒。
修复
mormot.net.server
cc55fa88+58-40
net: several THttpApiServer/THttpApiWebSocketServer fixes
影响
HTTP.sys 调用方不再把响应提交失败当作成功;无效文件与 Range 会停止处理;部分 WebSocket 升级不再泄漏 handle;关闭不会无限等待连接。
建议升级
升级 HTTP.sys 服务器,并复测静态文件、无效 Range 请求、失败 WebSocket 升级及存在活动 peer 时的关闭。
4
高
HTTP.sys WebSocket 发送失败会关闭连接并继续清空动作队列
Broadcast 捕获每连接发送异常并开始关闭;活动与关闭状态集合被集中定义;shutdown 跳过已关闭连接;ProcessActions 在完成非发送动作后继续且不会重复完成。
修复
mormot.net.server
6e02ccef+37-25
net: some http.sys WebSockets fixes
影响
单个故障 WebSocket 不再中断 broadcast;发送失败通过 boolean 结果报告,receive/close 动作也更不易停滞或重复完成。
建议升级
请复测包含一个断开 peer 的 broadcast,以及并发 I/O 下的 close/shutdown。
5
高
每线程 GSSAPI 失败后会重试 keytab 注册
PrepareKeyTab 在锁内复制主序列,但仅在 ServerForceKeytab 成功后更新 threadvar 序列;SetKeyTab 在持有 fSafe 时检查文件变化并执行 FileIsKeyTab 验证。
修复
mormot.lib.gssapi
0a647b66+29-21
lib: minor TServerSspiKeyTab fixes
影响
Heimdal 或临时注册失败会在同一线程重试,不再被误认为已准备;并发刷新也不会与缓存文件元数据竞争。
建议升级
POSIX keytab 热重载请使用 build 2.4.17505 或更高版本,不要停在首次签名变更提交。
6
高
新的 ARM 汇编条件同时修复损坏的 core 声明
mormot.defines.inc 引入 ASMARM64 与 ASMINTELARM,并在 NOASMBLOCK 下统一取消;mormot.core.base 用 ASMINTELARM 控制原子声明,同时移除 build 17513 加入的孤立 fixme token。
修复
mormot.core.base+1
6f93fc70+24-16
core: new ASMINTELARM/ASMARM64 conditionals
影响
build 2.4.17513 至 2.4.17515 的 mormot.core.base 含有无效 Pascal;build 2.4.17516 恢复编译,并为后续 ECC 汇编提供稳定架构条件。
建议升级
跳过 build 2.4.17513-2.4.17515,使用 build 2.4.17516 或更高版本。
7
高
HTTP.sys 服务器恢复周期日志、遥测与 OnIdle
THttpApiServer 创建名为 HttpApiIdle 的 TSynBackgroundThreadProcess,每秒用单调时间调用虚拟 DoIdle,并在主清理前释放该 worker。
修复
mormot.net.server
df25cd22+25-6
net: fixed logger + telemetry + OnIdle() support in THttpApiServer
影响
Windows HTTP.sys 后端即使无请求流量,也会重新刷新日志、汇总遥测、调用 OnIdle 并维护 blacklist/keytab。
建议升级
依赖 OnIdle、日志刷新、遥测或 keytab 刷新的 HTTP.sys 服务应升级,并在关闭测试中观察新的 idle worker。
8
高
libcurl 现在只暴露最终响应头
TCurlHttp 将 CurlWriteLastResponseHeader 设为响应头 callback。每当出现新的 HTTP 状态行时,它会清空已累积内容,再追加当前响应头。
修复
mormot.net.client
b9bdb628+16-3
net: fix TCurlHttp intermediate response headers
影响
重定向及其他多响应交换不再把中间响应头混入 TCurlHttp.Header;调用方读取的是最终状态码对应的响应头。
建议升级
若 TCurlHttp 会跟随重定向或收到 100 Continue,请升级并复测读取响应头的代码。
9
高
Windows 请求头保持有效 Unicode 存储并正确裁剪名称
TWinHttp.InternalAddHeader 将 Utf8ToSynUnicode 结果保存在本地 SynUnicode 变量中,并传递实际宽字符长度;TDelphiNetHttp.InternalAddHeader 分别裁剪名称和值。
修复
mormot.net.client
59a88c92+11-7
net: TWinHttp and TDelphiNetHttp client fixes
影响
TWinHttp 避免临时字符串指针及 UTF-8/宽字符长度不匹配;Delphi 客户端也不再转发自定义响应头两侧的空白。
建议升级
请复测 TWinHttp 与 TDelphiNetHttp 中的非 ASCII 及带两侧空白的自定义请求头。
10
高
Delphi 7/2007 保留兼容的 P-256 约简回退路径
_modMultN 按 HASQWORD 分支:现代编译器使用 Barrett 约简,Delphi 7/2007 保留不依赖无符号 UInt64 语义的旧移位减法算法。
编译器与平台
mormot.crypt.ecc256r1
597b691f+61-7
crypt: circumvent Delphi 7/2007 compiler restriction
影响
旧版 Delphi 可编译并通过较慢但成熟的路径继续生成 P-256 结果;新版后端仍使用优化约简器。
建议升级
使用 Delphi 7 或 2007 编译 mormot.crypt.ecc256r1 时,请使用 build 2.4.17522 或更高版本。
11
高
Delphi POSIX 构建恢复宽乘法辅助函数
mormot.core.base 在 FPC 分支之外新增 Delphi 版 mul64x64;ECC carry 表达式也加入 Delphi POSIX 可接受的 ordinal 与 PtrUInt/QWord 显式转换。
编译器与平台
mormot.core.base+2
c763b013+23-9
crypt: fixed Delphi POSIX compilation
影响
Delphi POSIX 目标可重新编译新的 ECC 算术实现;此变更仅涉及编译器兼容性,不改变应用 API。
建议升级
Delphi POSIX 目标请使用 build 2.4.17523 或更高版本,并重建依赖 ECC 的应用。
12
高
Delphi HTTP 响应头裁剪可在受支持编译器上编译
TDelphiNetHttp.InternalAddHeader 先把 TrimCopy 结果写入显式 RawUtf8 变量,再转换为 string 传给 THTTPClient.AddHeader。
编译器与平台
mormot.net.client
0a8341fb+8-5
net: fixed TDelphiNetHttp header trimming compilation
影响
此前内联使用 procedure 形式的 TrimCopy 无法编译;使用 TDelphiNetHttp 的 Delphi 后端无需改应用代码即可重新构建。
建议升级
若启用 TDelphiNetHttp,请使用 build 2.4.17529 或更高版本。
13
中
HTTP.sys WebSocket 关闭与 ping 记账统一路径
THttpApiWebSocketConnection.DoClose 集中处理关闭状态、上下文与 BeginClose;ping 时间在发送前记录,ping/pong 发送不再刷新普通活动时间,多处关闭逻辑统一调用 DoClose。
修复
mormot.net.server
303139a2+23-29
net: new THttpApiWebSocketConnection.DoClose internal method
影响
空闲 WebSocket 不会仅因服务器 ping 而一直存活,失败路径也会生成一致的关闭状态;应用 API 不变。
值得一看
14
中
WinINet 与 WinHTTP 不再把 HTTP 状态行当作响应头返回
RemoveHeadInHeaders 会裁剪空白并移除开头的 HTTP 状态行;TWinHttpApi.InternalRetrieveAnswer 与 TCurlHttp 在暴露或解析响应头前都会调用它。
修复
mormot.net.client
e46374f3+21-12
net: fixed WinINet/WinHttp retrieved headers
影响
调用方获得规范化响应头块,不再包含带 HTTP/1.x 状态文本的伪响应头;Windows 与 curl 客户端的查找行为更一致。
建议升级
请复测解析响应头首行的代码;现在首行应为真实响应头字段。
15
中
WebSocket 缓冲区与动作队列可正确处理 callback 失败
DoOnMessage 在 finally 中清空 fBuffer;ProcessActions 完成发送动作后继续取下一动作而非继续落入后续逻辑;UpgradeToWebSocket 会裁剪每个请求的子协议名。
修复
mormot.net.server
a2fab1d6+8-9
net: minor THttpApiWebSocketServer tweaks
影响
用户 OnMessage 异常不再把旧 payload 留给下一条消息;发送完成不会破坏动作处理,带空格的协议列表可正确协商。
建议升级
请复测 HTTP.sys WebSocket 的分片消息、OnMessage 异常及子协议协商。
16
中
HTTP 服务器提供统一的虚拟 idle 维护钩子
THttpServerGeneric 新增受保护虚拟方法 DoIdle(tix64, sec32);socket 服务器把 logger、analyzer、OnIdle、blacklist 与 POSIX keytab 维护移入覆写,async 服务器复用该路径。
新功能
mormot.defines+2
ddb42855+37-42
net: new THttpServerGeneric.DoIdle virtual method
影响
服务器子类可一致扩展周期维护;现有 socket 与 async 后端通过共享实现保留原有 callback。
值得一看
公开 API
THttpServerGeneric.DoIdleadded — 受保护虚拟 procedure DoIdle(tix64: Int64; sec32: cardinal) 统一周期服务器工作。
17
中
i386 获得原生 128 位与 256 位乘法
mormot.crypt.core.asmx86 新增 _mult128 与 _mult256;Pascal unit 将包括 i386 在内的全部 ASMINTEL 目标路由到原生乘法与平方例程。
性能
mormot.crypt.core+1
afce8c72+602-98
crypt: new i386 asm for _mult256() and _mult128()
影响
32 位 Intel/AMD 的 ECC 运算避开通用 Pascal 乘法路径;应用源码与密码学线格式不变。
18
中
Intel P-256 素数约简移入架构汇编
_mmodP 在 mormot.crypt.core 中为 ASMINTEL 声明,并在 i386/x86-64 include 中实现;mormot.crypt.ecc256r1 仅为非 Intel 目标保留 Pascal 约简器。
性能
mormot.crypt.core+3
15884e94+497-4
crypt: x86_64/i386 asm specific mormot.crypt.ecc256r1 computation of _mmodP
影响
i386 与 x86-64 上的 P-256 乘法使用架构专用模约简;公钥、签名和公共 API 不变。
19
中
ARMv7 原子操作获得正确内存屏障的原生实现
AArch64 include 重命名为 mormot.core.base.asmarm.inc,并加入由 DMB ISH 包围的 ARMv7 LDREX/STREX 循环;ASMARM 在 AArch64 及带 CPUARM_HAS_DMB 的 ARMv7+ 上选择这些例程。
性能
mormot.core.base+2
a1079132+320-164
core: ARMv7 asm for Locked*() - in a single mormot.core.base.asmarm.inc
影响
FPC ARMv7 的锁与引用计数保持完整内存屏障语义,同时减少 RTL 屏障调用;旧 ARM 目标继续使用带保护的 RTL 回退。
20
中
ARMv8 获得用于 ECC 的展开宽整数算术
mormot.core.base.asmarm.inc 新增 AArch64 加减、移位及 128/256 位乘法例程;mormot.crypt.core 通过 ASMARM64 选择它们,而不再编译较慢的 Pascal 等价实现。
性能
mormot.core.base+2
284915df+357-44
crypt: new unrolled ARMv8 64-bit asm for 128-bit and 256-bit computation
影响
AArch64 Delphi/FPC 密码学负载使用原生宽整数算术,主要加速 ECC 内部路径,无需修改应用代码。
21
中
AArch64 新增专用 P-256 素数约简例程
ASMARM64 现在从 mormot.core.base.asmarm.inc 提供 AArch64 _mmodP 实现,mormot.crypt.ecc256r1 在该目标上不再编译 Pascal 实现。
性能
mormot.core.base+2
1dec0f83+153-2
crypt: specific mormot.crypt.ecc256r1 computation in pure aarch64 asm
影响
ECC P-256 乘法与签名内部路径使用原生 AArch64 约简;公共 ECC 格式及应用调用不变。
22
中
P-256 标量约简切换为 Barrett 算法
mormot.crypt.ecc256r1 新增 BARRETT_N_MU_LOW,并把 _modMultN 中逐位的 Curve_N_32 约简替换为定宽 Barrett 约简及最多两次掩码减法。
性能
mormot.crypt.ecc256r1
49108d2f+81-51
crypt: use Curve_N_32 Barret Reduction algorithm for ecc256r1
影响
现代编译器上的 ECDSA 标量乘法与签名减少数据相关的约简步骤;密码学输出应保持一致。
值得一看
23
中
HTTP.sys WebSocket ping 移入服务器 idle 周期
THttpApiWebSocketServer 移除 TSynWebSocketGuard,并覆写 DoIdle 扫描协议连接;分别记录最后活动与最后 ping,在接收及非 ping 发送后刷新活动,并使 PingTimeout 可写。
内部重构
mormot.net.server
39a07c59+62-88
net: refactored http.sys WebSockets PING process
影响
ping 超时检查现在共用服务器每秒 idle thread,并把成功的应用发送视为活动;现有代码也可在构造后修改 PingTimeout。
值得一看
公开 API
THttpApiWebSocketServer.PingTimeoutbehaviour-changed — 该属性新增写访问器,超时检查由 DoIdle 执行,不再使用 TSynWebSocketGuard。
24
低
P-256 平方运算使用专用 Intel/AMD 汇编
i386 与 x86-64 include 新增原生 _square256;mormot.crypt.core 不再通过 _mult256 实现 Intel 平方。
性能
mormot.crypt.core+2
f6c7eed7+506-13
crypt: native i386/x64 asm version of _square256()
影响
32/64 位 Intel/AMD 目标的 ECC 算术使用专用平方路径;应用源码与序列化数据不变。
25
低
宽整数比较针对 x86-64 与 AArch64 专门优化
_cmp256 在 ASMX64 与 ASMARM64 上改用原生实现,其他 CPU64 目标仍使用 Pascal 比较;另有注释说明 TSynAngelizeState 保持 packed 的原因。
性能
mormot.app.agl+4
7023137e+70-25
crypt: x64 and aarch64 asm for _cmp256() function
影响
x86-64 与 AArch64 上的 ECC 比较开销更低;TSynAngelizeState 二进制布局及所有公共行为不变。
26
低
P-256 模逆减少宽整数比较
_modInv 仅在两个操作数均为奇数时调用 _cmp256,以 _sub256 的 borrow 结果替代比较后再减法,并使用 _inc256 原地累加。
性能
mormot.crypt.ecc256r1
a83aa6a6+38-33
crypt: slightly optimized _modInv() for ecc256r1
影响
纯 Pascal 及非专用 ECC 后端在模逆时减少内部运算;签名、密钥与公共行为不变。
27
低
纯 Pascal 256 位乘法器减少循环开销
_mult256 通过起始指针与显式迭代次数选择每条对角线,直接合并 carry,并通过 PQWordArray 写入,避免反复测试索引。
性能
mormot.crypt.core
e657f90d+21-25
crypt: faster pure pascal _mult256() algorithm
影响
没有专用汇编的目标(此阶段尤其是 ARM)执行内部 ECC 乘法时减少 Pascal 循环开销;API 不变。
28
低
DoubleToAscii 在 ARM 上使用原生宽乘法
Grisu 的 d2a_diy_fp_multiply 路径现在在 ARMv7 与 AArch64 上使用 ASMINTELARM 和 mul64x64,并通过 PQWordArray 访问归一化字。
性能
mormot.core.text
0fe4797b+6-6
core: slightly faster DoubleToAscii() on arm32/aarch64
影响
ARM Delphi/FPC 后端通过更快的内部乘法路径格式化 Double;输出格式与公共 API 不变。
29
低
FPC 原子包装按 CPU 行为选择
mormot.core.base 重组 FPC 的 Locked/Interlocked 实现:Intel 在 RTL 原子操作周围使用空 ReadWriteBarrier,AArch64 保留汇编 include,其他 CPU 保留显式屏障;字节交换与引用计数 helper 移入公共 FPC 分支。
内部重构
mormot.core.base
d1bb00c2+50-47
core: refactored FPC Locked*() functions
影响
FPC Intel 避免冗余屏障,非 Intel 目标保持内存顺序;公共原子函数签名与应用代码不变。
30
低
Decimal128 转换不再触发 FPC 字面量提示
mormot.db.nosql.bson 将乘数 100000000000000000 定义为 QWord 常量 BIGPOW10,并在 TDecimal128.FromText 中传给 mul64x64。
杂项
mormot.db.nosql.bson
42184b30+6-3
db: fixed FPC compiler hint in TDecimal128 process
影响
FPC 构建不再产生该编译器提示;Decimal128 解析行为和二进制表示不变。