Configurable bind addresses + display host in Server Settings

ServerConfig grows two fields:
- BindAddresses: list of IPs Kestrel binds to (empty = all interfaces,
  current behavior). Listening only on a subset is useful when the host
  has multiple NICs and the webhook should not be reachable on all of
  them.
- DisplayHost: the hostname/IP the GUI splices into the URL column and
  Copy URL button. Cosmetic; doesn't affect what the server accepts.

Server Settings dialog gains a "Network" section: a checkbox for "all
interfaces" plus per-NIC checkboxes auto-detected via NetworkInterface.
GetAllNetworkInterfaces, and an editable ComboBox for the display host
pre-populated with detected IPs and the machine name.

Listener restart fires on BindAddresses change but not on DisplayHost
change (cosmetic).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-08 09:27:18 -04:00
parent 4ef8d20578
commit 28479272d5
10 changed files with 162 additions and 4 deletions
@@ -52,6 +52,7 @@ public sealed class StatusInfo
public bool Running { get; set; }
public int HttpPort { get; set; }
public int? HttpsPort { get; set; }
public string? DisplayHost { get; set; }
public DateTimeOffset StartedAt { get; set; }
public int EndpointCount { get; set; }
}
@@ -5,6 +5,18 @@ public sealed class ServerConfig
public int HttpPort { get; set; } = 8080;
public HttpsBinding? HttpsBinding { get; set; }
/// <summary>
/// IP addresses Kestrel binds to. Empty = listen on all interfaces (default).
/// Non-empty = listen only on the named addresses.
/// </summary>
public List<string> BindAddresses { get; set; } = new();
/// <summary>
/// Hostname or IP that the GUI uses when constructing webhook URLs to display.
/// Null = "localhost". Has no effect on what Kestrel actually accepts.
/// </summary>
public string? DisplayHost { get; set; }
/// <summary>
/// IPs/CIDRs allowed to set X-Forwarded-For. Empty = forwarded headers are ignored
/// and the direct connection IP is always used.