diff --git a/DevProxy/Commands/DevProxyCommand.cs b/DevProxy/Commands/DevProxyCommand.cs index 77d464c0..9f124bd4 100644 --- a/DevProxy/Commands/DevProxyCommand.cs +++ b/DevProxy/Commands/DevProxyCommand.cs @@ -1,6 +1,7 @@ using DevProxy.Abstractions.Plugins; using DevProxy.Abstractions.Proxy; using DevProxy.Abstractions.Utils; +using DevProxy.State; using Microsoft.AspNetCore.Hosting.Server; using Microsoft.AspNetCore.Hosting.Server.Features; using System.CommandLine; @@ -314,6 +315,13 @@ private async Task InvokeAsync(ParseResult parseResult, CancellationToken c var serverAddresses = _app.Services.GetRequiredService().Features.Get(); var address = serverAddresses?.Addresses.FirstOrDefault() ?? $"http://{_proxyConfiguration.IPAddress}:{_proxyConfiguration.ApiPort}"; _logger.LogInformation("Dev Proxy API listening on {Address}...", address); + + // Update state file with the actual Kestrel API address + // (resolves port 0 to OS-assigned port) + if (IsInternalDaemon) + { + _ = UpdateStateWithApiUrlAsync(address); + } }); await _app.RunAsync(cancellationToken); @@ -716,4 +724,14 @@ private async Task CheckForNewVersionAsync() ); } } + + private static async Task UpdateStateWithApiUrlAsync(string apiUrl) + { + var state = await StateManager.LoadStateByPidAsync(Environment.ProcessId); + if (state is not null) + { + state.ApiUrl = apiUrl; + await StateManager.SaveStateAsync(state); + } + } } \ No newline at end of file diff --git a/DevProxy/Program.cs b/DevProxy/Program.cs index 2cb2a862..3e8f7c56 100644 --- a/DevProxy/Program.cs +++ b/DevProxy/Program.cs @@ -163,13 +163,25 @@ await Console.Error.WriteLineAsync( await Task.Delay(200); var state = await StateManager.LoadStateByPidAsync(process.Id); - if (state != null) + if (state is { Port: > 0 } && !string.IsNullOrEmpty(state.ApiUrl) && !state.ApiUrl.EndsWith(":0", StringComparison.Ordinal)) { + Uri? apiUri = null; + if (!string.IsNullOrWhiteSpace(state.ApiUrl)) + { + Uri.TryCreate(state.ApiUrl, UriKind.Absolute, out apiUri); + } + + // Build proxy URL in a way that correctly handles IPv6 hosts. + string hostForProxy = apiUri?.Host ?? IPAddress.Loopback.ToString(); + var proxyUriBuilder = new UriBuilder(Uri.UriSchemeHttp, hostForProxy, state.Port); + var proxyUrl = proxyUriBuilder.Uri.ToString().TrimEnd('/'); + if (isJsonOutput) { await Console.Out.WriteLineAsync(FormatJsonResultEntry(new { state.Pid, + ProxyUrl = proxyUrl, state.ApiUrl, state.LogFile })); @@ -179,6 +191,7 @@ await Console.Out.WriteLineAsync(FormatJsonResultEntry(new await Console.Out.WriteLineAsync("Dev Proxy started in background."); await Console.Out.WriteLineAsync(); await Console.Out.WriteLineAsync($" PID: {state.Pid}"); + await Console.Out.WriteLineAsync($" Proxy URL: {proxyUrl}"); await Console.Out.WriteLineAsync($" API URL: {state.ApiUrl}"); await Console.Out.WriteLineAsync($" Log file: {state.LogFile}"); await Console.Out.WriteLineAsync();