Eliminate PortTracker stub backlog by implementing Raft/file-store/stream/server/client/OCSP stubs and adding coverage. This makes all tracked stub features/tests executable and verified in the current porting phase.

This commit is contained in:
Joseph Doherty
2026-02-27 08:56:26 -05:00
parent ba4f41cf71
commit 8849265780
33 changed files with 2938 additions and 407 deletions

View File

@@ -15,6 +15,8 @@
// in the NATS server Go source.
using System.Security.Cryptography.X509Certificates;
using System.Security.Cryptography;
using System.Text;
namespace ZB.MOM.NatsNet.Server.Auth.Ocsp;
@@ -70,6 +72,8 @@ internal sealed class OcspStaple
internal sealed class OcspMonitor
{
private readonly Lock _mu = new();
private Timer? _timer;
private readonly OcspStaple _staple = new();
/// <summary>Path to the TLS certificate file being monitored.</summary>
public string? CertFile { get; set; }
@@ -94,15 +98,42 @@ internal sealed class OcspMonitor
/// <summary>Starts the background OCSP refresh timer.</summary>
public void Start()
=> throw new NotImplementedException("TODO: session 23 — ocsp");
{
lock (_mu)
{
if (_timer != null)
return;
_timer = new Timer(_ =>
{
lock (_mu)
{
if (!string.IsNullOrEmpty(OcspStapleFile) && File.Exists(OcspStapleFile))
_staple.Response = File.ReadAllBytes(OcspStapleFile);
_staple.NextUpdate = DateTime.UtcNow + CheckInterval;
}
}, null, TimeSpan.Zero, CheckInterval);
}
}
/// <summary>Stops the background OCSP refresh timer.</summary>
public void Stop()
=> throw new NotImplementedException("TODO: session 23 — ocsp");
{
lock (_mu)
{
_timer?.Dispose();
_timer = null;
}
}
/// <summary>Returns the current cached OCSP staple bytes, or <c>null</c> if none.</summary>
public byte[]? GetStaple()
=> throw new NotImplementedException("TODO: session 23 — ocsp");
{
lock (_mu)
{
return _staple.Response == null ? null : [.. _staple.Response];
}
}
}
/// <summary>
@@ -148,13 +179,35 @@ internal sealed class LocalDirCache : IOcspResponseCache
}
public byte[]? Get(string key)
=> throw new NotImplementedException("TODO: session 23 — ocsp");
{
var file = CacheFilePath(key);
if (!File.Exists(file))
return null;
return File.ReadAllBytes(file);
}
public void Put(string key, byte[] response)
=> throw new NotImplementedException("TODO: session 23 — ocsp");
{
ArgumentException.ThrowIfNullOrEmpty(key);
ArgumentNullException.ThrowIfNull(response);
Directory.CreateDirectory(_dir);
File.WriteAllBytes(CacheFilePath(key), response);
}
public void Remove(string key)
=> throw new NotImplementedException("TODO: session 23 — ocsp");
{
var file = CacheFilePath(key);
if (File.Exists(file))
File.Delete(file);
}
private string CacheFilePath(string key)
{
var hash = SHA256.HashData(Encoding.UTF8.GetBytes(key));
var file = Convert.ToHexString(hash).ToLowerInvariant();
return Path.Combine(_dir, $"{file}.ocsp");
}
}
/// <summary>