const
TsaMaxResponseBytes = 4 * 1024 * 1024;
TsaRequestTimeoutSeconds = 30;
TsaConnectTimeoutSeconds = 30;
function TsaHttpAvailable: Boolean;
function TsaHttpBackendName: string;
function PostTimeStampQuery(const TsaUrl: string; const ReqDer: TBytes;
out RespDer: TBytes): Boolean;
FPdfTsaFpc 是 FPdfTsa 使用的非 Windows 時間戳記傳輸,對應 FPdfTsaWin。它透過 HTTP 或 HTTPS 將編碼後的 TimeStampReq 投遞到時間戳記授權單位 URL,並收集 TimeStampResp 位元組;DER 的建構與剖析仍留在 FPdfTsa
傳輸層是 libcurl,在執行期繫結而不是連結,因此該程式庫不是編譯期相依,缺失時會被回報而不是導致載入失敗。經由 libcurl 也能讓 TLS 堆疊遠離本單元:libcurl 自行選擇後端,並針對平台信任存放區驗證伺服器鏈
TsaHttpAvailable 回報是否找到了 libcurl 並解析出所需進入點;TsaHttpBackendName 給出解析到的後端名稱;PostTimeStampQuery 執行 HTTP 交換,任何傳輸失敗都傳回 False(而不是拋出例外),讓呼叫端附加自己的情境與重試政策
整個 interface 部分只在 FPC 下編譯。在 Delphi 下本單元為空,因為 Delphi 面向 Windows,那裡由 FPdfTsaWin 擔任後端。本單元仍能在包括 Windows 在內的所有 FPC 目標上編譯,只是 Windows 上 FPdfTsa 優先使用 WinHttp 後端,不會有任何程式碼呼叫本單元
libcurl 控制代碼型別、進入點繫結與選項常數位於 implementation 部分;interface 只公開可用性檢查、後端名稱、投遞輔助函式與三個傳輸限制
| Function | Description |
|---|---|
TsaHttpAvailable | 當執行期找到 libcurl 且所有必需進入點解析成功時傳回 True |
TsaHttpBackendName | 傳回解析到的後端名稱,傳輸可用時為 libcurl,否則為空字串 |
PostTimeStampQuery | 將 ReqDer 投遞到 TsaUrl,並以原始 TimeStampResp 主體填入 RespDer;傳輸失敗時傳回 False |
| Constant | Value | Description |
|---|---|---|
TsaMaxResponseBytes | 4 * 1024 * 1024 | 可接受的 TimeStampResp 主體上限;更大的回應會中止傳輸,而不是無限制地擴充緩衝區。與 FPdfTsaWin 中的同名常數保持一致 |
TsaRequestTimeoutSeconds | 30 | 整個請求的秒級額度,與 WinHttp 逾時一致,因此無回應的 TSA 無法在任一平台上卡住簽署執行緒 |
TsaConnectTimeoutSeconds | 30 | 連線的秒級額度,先於請求額度套用 |
Content-Type: application/timestamp-query 送出,並預期 application/timestamp-reply;Expect: 100-continue 被停用,因此不回應的回應端無法卡住大於 1 KB 的主體http 與 https URL,且不跟隨重新導向:以重新導向回應的回應端被視為設定錯誤,而不是被悄悄導向呼叫端從未指定的端點再重試TsaHttpAvailable 呼叫時載入,控制代碼被刻意保持開啟直至處理程序結束,因為在另一個執行緒正處於傳輸中時卸載它會拖垮主機。以信號為基礎的解析器逾時保持關閉,因此簽署可以在工作執行緒上執行TsaHttpAvailable 傳回 False,FPdfTsa 回報 PadesTsaAvailable = False,除非透過 PadesTimestampOverride 註冊了其他傳輸