using System.Text.RegularExpressions;
using CaddyManager.Contracts.Caddy;
namespace CaddyManager.Services.Caddy;
///
public partial class CaddyConfigurationParsingService: ICaddyConfigurationParsingService
{
///
/// Regex to help parse hostnames from a Caddyfile.
///
///
[GeneratedRegex(@"(?m)^[\w.-]+(?:\s*,\s*[\w.-]+)*(?=\s*\{)", RegexOptions.Multiline)]
private static partial Regex HostnamesRegex();
///
/// Regex to help parse hostnames being used in reverse proxy directives.
///
///
[GeneratedRegex(@"(?m)reverse_proxy .*", RegexOptions.Multiline)]
private static partial Regex ReverseProxyRegex();
///
public List GetHostnamesFromCaddyfileContent(string caddyfileContent)
{
var hostnamesRegex = HostnamesRegex();
var matches = hostnamesRegex.Matches(caddyfileContent);
var hostnames = new List();
foreach (Match match in matches)
{
// Split the matched string by commas and trim whitespace
var splitHostnames = match.Value.Split(',')
.Select(h => h.Trim())
.Where(h => !string.IsNullOrWhiteSpace(h))
.ToList();
hostnames.AddRange(splitHostnames);
}
// Remove duplicates and return the list
return hostnames.Distinct().ToList();
}
///
public string GetReverseProxyTargetFromCaddyfileContent(string caddyfileContent)
{
var reverseProxyRegex = ReverseProxyRegex();
var match = reverseProxyRegex.Match(caddyfileContent);
if (!match.Success) return string.Empty;
var parts = match.Value.TrimEnd('}').Trim().Split(' ');
var targetPart = parts.LastOrDefault(string.Empty);
if (string.IsNullOrEmpty(targetPart)) return string.Empty;
var targetComponents = targetPart.Split(':');
if (targetComponents.Length <= 1) return targetPart;
// Handle cases like http://backend:9000, 192.168.1.100:3000
return targetComponents[0];
}
///
public List GetReverseProxyPortsFromCaddyfileContent(string caddyfileContent)
{
var reverseProxyRegex = ReverseProxyRegex();
var matches = reverseProxyRegex.Matches(caddyfileContent);
var results = new List();
foreach (Match match in matches)
{
var parts = match.Value.TrimEnd('}').Trim().Split(' ');
var targetPart = parts.LastOrDefault(string.Empty);
if (string.IsNullOrEmpty(targetPart)) continue;
var targetComponents = targetPart.Split(':');
if (targetComponents.Length > 1 && int.TryParse(targetComponents.Last(), out int port))
{
results.Add(port);
}
}
return results.Distinct().ToList();
}
}