65 lines
2.2 KiB
C#
65 lines
2.2 KiB
C#
using System.Security.Cryptography;
|
|
using NATS.Server.Auth;
|
|
|
|
namespace NATS.Server.Imports;
|
|
|
|
/// <summary>
|
|
/// Handles response routing for service imports.
|
|
/// Maps to Go's service reply prefix generation and response cleanup.
|
|
/// Reference: golang/nats-server/server/accounts.go — addRespServiceImport, removeRespServiceImport
|
|
/// </summary>
|
|
public static class ResponseRouter
|
|
{
|
|
private static readonly char[] Base62 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789".ToCharArray();
|
|
|
|
/// <summary>
|
|
/// Generates a unique reply prefix for response routing.
|
|
/// Format: "_R_.{10 random base62 chars}."
|
|
/// </summary>
|
|
public static string GenerateReplyPrefix()
|
|
{
|
|
Span<byte> bytes = stackalloc byte[10];
|
|
RandomNumberGenerator.Fill(bytes);
|
|
var chars = new char[10];
|
|
for (int i = 0; i < 10; i++)
|
|
chars[i] = Base62[bytes[i] % 62];
|
|
return $"_R_.{new string(chars)}.";
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates a response service import that maps the generated reply prefix
|
|
/// back to the original reply subject on the requesting account.
|
|
/// </summary>
|
|
public static ServiceImport CreateResponseImport(
|
|
Account exporterAccount,
|
|
ServiceImport originalImport,
|
|
string originalReply)
|
|
{
|
|
var replyPrefix = GenerateReplyPrefix();
|
|
|
|
var responseSi = new ServiceImport
|
|
{
|
|
DestinationAccount = exporterAccount,
|
|
From = replyPrefix + ">",
|
|
To = originalReply,
|
|
IsResponse = true,
|
|
ResponseType = originalImport.ResponseType,
|
|
Export = originalImport.Export,
|
|
TimestampTicks = DateTime.UtcNow.Ticks,
|
|
};
|
|
|
|
exporterAccount.Exports.Responses[replyPrefix] = responseSi;
|
|
return responseSi;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Removes a response import from the account's export map.
|
|
/// For Singleton responses, this is called after the first reply is delivered.
|
|
/// For Streamed/Chunked, it is called when the response stream ends.
|
|
/// </summary>
|
|
public static void CleanupResponse(Account account, string replyPrefix, ServiceImport responseSi)
|
|
{
|
|
account.Exports.Responses.Remove(replyPrefix);
|
|
}
|
|
}
|