using System.Net.Http.Headers; using Microsoft.Extensions.Logging; namespace Infrastructure.StockData; /// KRX OpenAPI(data-dbg.krx.co.kr) 호출 공통 — AUTH_KEY 헤더 인증 + 간단 3회 재시도 (2s/4s 백오프) internal static class KrxCoKrHttp { public const string ClientName = "KRXCoKr"; /// KRX OpenAPI 인증 헤더명 (라이브 검증: 헤더 있으면 "Unauthorized API Call", 없으면 "Unauthorized Key") public const string AuthHeader = "AUTH_KEY"; private const int MaxAttempts = 3; public static async Task GetStringWithRetryAsync(HttpClient client, string url, string apiKey, ILogger logger, CancellationToken ct) { for (var attempt = 1; ; attempt++) { try { using var request = new HttpRequestMessage(HttpMethod.Get, url); request.Headers.TryAddWithoutValidation(AuthHeader, apiKey); request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); using var response = await client.SendAsync(request, ct); response.EnsureSuccessStatusCode(); return await response.Content.ReadAsStringAsync(ct); } catch (Exception ex) when (ex is not OperationCanceledException && attempt < MaxAttempts) { logger.LogWarning(ex, "[KRXCoKr] HTTP 실패 — 재시도 {Attempt}/{Max}", attempt, MaxAttempts); await Task.Delay(TimeSpan.FromSeconds(2 * attempt), ct); } } } }