using System.Text; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; namespace YD_Event.Web.Entry.Controllers; /// /// 官网赛事信息管理。使用后台登录态访问,将请求转发到内部赛事服务。 /// [ApiController] [Authorize] [Route("api/website-competition")] public sealed class WebsiteCompetitionController : ControllerBase { private readonly IConfiguration _configuration; private readonly IHttpClientFactory _httpClientFactory; public WebsiteCompetitionController(IConfiguration configuration, IHttpClientFactory httpClientFactory) { _configuration = configuration; _httpClientFactory = httpClientFactory; } [HttpGet] public Task Get() => ForwardAsync(HttpMethod.Get); [HttpPut] [RequestSizeLimit(8 * 1024 * 1024)] public Task Put() => ForwardAsync(HttpMethod.Put); private async Task ForwardAsync(HttpMethod method) { var adminUrl = _configuration["CompetitionApi:AdminUrl"] ?? "http://127.0.0.1:8787/api/competition/admin"; if (!Uri.TryCreate(adminUrl, UriKind.Absolute, out var target) || (target.Scheme != Uri.UriSchemeHttp && target.Scheme != Uri.UriSchemeHttps)) return StatusCode(503, new { error = "官网赛事接口地址无效" }); using var upstreamRequest = new HttpRequestMessage(method, target); if (method == HttpMethod.Put) { using var reader = new StreamReader(Request.Body, Encoding.UTF8, leaveOpen: true); var body = await reader.ReadToEndAsync(HttpContext.RequestAborted); upstreamRequest.Content = new StringContent(body, Encoding.UTF8, "application/json"); } try { var client = _httpClientFactory.CreateClient("WebsiteCompetition"); client.Timeout = TimeSpan.FromSeconds(30); using var upstreamResponse = await client.SendAsync( upstreamRequest, HttpCompletionOption.ResponseHeadersRead, HttpContext.RequestAborted); var response = await upstreamResponse.Content.ReadAsStringAsync(HttpContext.RequestAborted); return new ContentResult { Content = response, ContentType = "application/json; charset=utf-8", StatusCode = (int)upstreamResponse.StatusCode }; } catch (HttpRequestException) { return StatusCode(502, new { error = "官网赛事接口连接失败" }); } catch (TaskCanceledException) when (!HttpContext.RequestAborted.IsCancellationRequested) { return StatusCode(504, new { error = "官网赛事接口响应超时" }); } } }