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에 POST하고 TimeStampResp 바이트를 받아옵니다. DER 생성과 파싱은 FPdfTsa에 그대로 남습니다
전송 계층은 링크가 아니라 런타임에 바인딩되는 libcurl이므로, 라이브러리는 빌드 타임 의존성이 아니며 없어도 로드가 실패하지 않고 그 사실이 보고됩니다. libcurl을 거치면 TLS 스택도 이 유닛 밖에 머뭅니다. libcurl이 자체 백엔드를 고르고 플랫폼 trust store로 서버 체인을 검증하기 때문입니다
TsaHttpAvailable은 libcurl을 찾고 필요한 엔트리 포인트를 해석했는지 보고하고, TsaHttpBackendName은 해석된 백엔드 이름을 알려주며, PostTimeStampQuery는 HTTP 교환을 수행하고 전송 실패 시 예외 대신 False를 반환해 호출자가 자체 맥락과 재시도 정책을 추가할 수 있게 합니다
인터페이스 섹션 전체는 FPC에서만 컴파일됩니다. Delphi에서는 이 유닛이 비어 있습니다. Delphi는 Windows를 대상으로 하고 그곳의 백엔드는 FPdfTsaWin이기 때문입니다. Windows를 포함한 모든 FPC 대상에서는 이 유닛이 계속 컴파일되지만, FPdfTsa가 WinHttp 백엔드를 선호하므로 아무도 이 유닛을 호출하지 않습니다
libcurl 핸들 타입, 엔트리 포인트 바인딩, 옵션 상수는 implementation 섹션에 있고, 인터페이스는 가용성 검사, 백엔드 이름, POST 헬퍼, 세 가지 전송 한도만 노출합니다
| Function | Description |
|---|---|
TsaHttpAvailable | 런타임에 libcurl을 찾고 필요한 모든 엔트리 포인트를 해석했으면 True를 반환합니다 |
TsaHttpBackendName | 해석된 백엔드 이름을 반환합니다. 전송을 사용할 수 있으면 libcurl이고 그렇지 않으면 빈 문자열입니다 |
PostTimeStampQuery | ReqDer를 TsaUrl로 POST하고 RespDer를 원본 TimeStampResp 본문으로 채웁니다. 전송 실패 시 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 호출에서 로드되며, 핸들은 의도적으로 프로세스 수명 내내 열려 있습니다. 다른 스레드가 전송 중일 때 언로드하면 호스트가 함께 죽기 때문입니다. 시그널 기반 resolver 타임아웃은 꺼져 있어 서명이 워커 스레드에서 실행될 수 있습니다TsaHttpAvailable이 False를 반환하고, PadesTimestampOverride로 다른 전송이 등록되지 않는 한 FPdfTsa는 PadesTsaAvailable = False를 보고합니다