diff --git a/DevProxy/Program.cs b/DevProxy/Program.cs index 78912573..a7fbf784 100644 --- a/DevProxy/Program.cs +++ b/DevProxy/Program.cs @@ -107,11 +107,22 @@ static async Task StartDetachedProcessAsync(string[] args) await Task.Delay(200); var state = await StateManager.LoadStateAsync(); - if (state != null) + if (state is { Port: > 0 }) { + 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('/'); 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(); diff --git a/DevProxy/Proxy/ProxyEngine.cs b/DevProxy/Proxy/ProxyEngine.cs index 6f353a8f..0b153a6b 100755 --- a/DevProxy/Proxy/ProxyEngine.cs +++ b/DevProxy/Proxy/ProxyEngine.cs @@ -6,6 +6,7 @@ using DevProxy.Abstractions.Proxy; using DevProxy.Abstractions.Utils; using DevProxy.Commands; +using DevProxy.State; using Microsoft.VisualStudio.Threading; using System.Collections.Concurrent; using System.Diagnostics; @@ -141,6 +142,20 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken) ProxyServer.AddEndPoint(_explicitEndPoint); await ProxyServer.StartAsync(cancellationToken: stoppingToken); + // Update config with actual port (resolves port 0 to OS-assigned port) + _config.Port = _explicitEndPoint.Port; + + // Update state file with actual port so detach parent gets the resolved port + if (DevProxyCommand.IsInternalDaemon) + { + var state = await StateManager.LoadStateAsync(stoppingToken); + if (state is not null) + { + state.Port = _config.Port; + await StateManager.SaveStateAsync(state, stoppingToken); + } + } + // run first-run setup on macOS FirstRunSetup();