using BlueLaminate.Scraper.Proxies; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using System.CommandLine; namespace BlueLaminate.Cli.Commands; /// /// probe-proxy: launch a non-headless Edge browser through the IPRoyal /// residential proxy and print the exit IP, to confirm authentication works and /// the IP is genuinely residential. Reads IPROYAL_USERNAME / IPROYAL_PASSWORD. /// Costs a few KB, so it's the right first check against a metered plan. /// internal static class ProbeProxyCommand { public static Command Build(IHost host) { var countryOption = new Option("--country") { Description = "Optional ISO country code(s) for the exit IP, e.g. \"us\" or \"us,gb\". " + "Default: random.", }; var rotatingOption = new Option("--rotating") { Description = "Use a rotating exit IP instead of a pinned (sticky) session.", }; var command = new Command( "probe-proxy", "Launch non-headless Edge through the IPRoyal residential proxy and print the exit IP " + "to confirm auth works and the IP is residential. Reads IPROYAL_USERNAME / IPROYAL_PASSWORD.") { countryOption, rotatingOption, }; command.SetAction((parseResult, ct) => RunAsync( host, parseResult.GetValue(countryOption), parseResult.GetValue(rotatingOption), ct)); return command; } private static async Task RunAsync( IHost host, string? country, bool rotating, CancellationToken ct) { using var scope = host.Services.CreateScope(); try { var probe = scope.ServiceProvider.GetRequiredService(); var info = await probe.RunAsync(new ProxyRequest(Country: country, Sticky: !rotating)); Console.WriteLine(); Console.WriteLine($" Exit IP : {info.Ip}"); Console.WriteLine($" Location: {info.City}, {info.Region}, {info.Country}"); Console.WriteLine($" Org/ASN : {info.Org}"); Console.WriteLine($" Hostname: {info.Hostname ?? "—"}"); Console.WriteLine(); Console.WriteLine( "Check Org/ASN: a consumer ISP = residential; a hosting provider = datacenter."); return 0; } catch (Exception ex) { Console.Error.WriteLine($"Proxy probe failed: {ex.Message}"); return 1; } } }