namespace LeagueAPI.Utils; internal class LcuHttpClientHandler : HttpClientHandler { private Lazy _isFirstRequest = new(() => true); private Lazy _isFailing = new(() => false); public ProcessInfo? ProcessInfo { get; internal set; } public RiotAuthentication? RiotAuthentication { get { if (ProcessInfo is not null) { return new RiotAuthentication(ProcessInfo.RemotingAuthToken); } return null; } } public string? BaseAddress { get { if (ProcessInfo != null) { return $"https://127.0.0.1:{ProcessInfo.AppPort}"; } return null; } } internal LcuHttpClientHandler() { base.ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator; } protected override async Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { HttpResponseMessage result; int num; try { if (_isFirstRequest.Value) { _isFirstRequest = new Lazy(() => false); SetProcessInfo(); } if (_isFailing.Value) { _isFailing = new Lazy(() => false); SetProcessInfo(); } PrepareRequestMessage(request); result = await base.SendAsync(request, cancellationToken).ConfigureAwait(continueOnCapturedContext: false); return result; } catch (InvalidOperationException) { _isFailing = new Lazy(() => true); throw; } catch (HttpRequestException) { num = 1; } if (num == 1) { try { SetProcessInfo(); PrepareRequestMessage(request); return await base.SendAsync(request, cancellationToken).ConfigureAwait(continueOnCapturedContext: false); } catch (InvalidOperationException) { _isFailing = new Lazy(() => true); throw; } } throw new Exception("Failed to send request"); } protected override HttpResponseMessage Send(HttpRequestMessage request, CancellationToken cancellationToken) { try { if (_isFirstRequest.Value) { _isFirstRequest = new Lazy(() => false); SetProcessInfo(); } if (_isFailing.Value) { _isFailing = new Lazy(() => false); SetProcessInfo(); } PrepareRequestMessage(request); return base.Send(request, cancellationToken); } catch (InvalidOperationException) { _isFailing = new Lazy(() => true); throw; } catch (HttpRequestException) { try { SetProcessInfo(); PrepareRequestMessage(request); return base.Send(request, cancellationToken); } catch (InvalidOperationException) { _isFailing = new Lazy(() => true); throw; } } } private void SetProcessInfo() { ProcessInfo = ProcessFinder.GetProcessInfo(); if (!ProcessFinder.IsPortOpen(ProcessInfo)) { throw new InvalidOperationException("Failed to connect to LCUx process port."); } } private void PrepareRequestMessage(HttpRequestMessage request) { if (BaseAddress != null) { Uri requestUri = new(BaseAddress + (request.RequestUri?.PathAndQuery ?? "/")); request.RequestUri = requestUri; } request.Headers.Authorization = RiotAuthentication?.ToAuthenticationHeaderValue(); } }