using LMS.Tools.FileTool; using Microsoft.Extensions.Logging; using System.Text; namespace LMS.Tools.HttpTool { /// /// HTTP网络请求服务 /// public class HttpService : IHttpService { private readonly IHttpClientFactory _httpClientFactory; private readonly ILogger _logger; public HttpService( IHttpClientFactory httpClientFactory, ILogger logger) { _httpClientFactory = httpClientFactory; _logger = logger; } /// /// 下载文件并返回字节数组 /// /// 文件URL /// 文件字节数组 public async Task DownloadFileAsync(string url, double maxFileSize) { try { if (string.IsNullOrWhiteSpace(url)) throw new ArgumentException("URL不能为空", nameof(url)); if (!Uri.IsWellFormedUriString(url, UriKind.Absolute)) throw new ArgumentException("无效的URL格式", nameof(url)); using var httpClient = _httpClientFactory.CreateClient("HttpService"); using var response = await httpClient.GetAsync(url, HttpCompletionOption.ResponseHeadersRead); if (!response.IsSuccessStatusCode) { throw new HttpRequestException($"HTTP请求失败,状态码: {response.StatusCode}"); } // 检查文件大小 if (response.Content.Headers.ContentLength.HasValue) { if (response.Content.Headers.ContentLength.Value > maxFileSize * 1024 * 1024) { throw new InvalidOperationException($"文件大小({response.Content.Headers.ContentLength.Value} bytes)超过限制({maxFileSize * 1024 * 1024} bytes)"); } } var fileBytes = await response.Content.ReadAsByteArrayAsync(); if (fileBytes.Length > maxFileSize * 1024 * 1024) { throw new InvalidOperationException($"下载的文件大小({fileBytes.Length} bytes)超过限制({maxFileSize * 1024 * 1024} bytes)"); } return fileBytes; } catch (HttpRequestException ex) { _logger.LogError(ex, "HTTP请求异常: {Url}", url); throw; } catch (TaskCanceledException ex) { _logger.LogError(ex, "请求超时: {Url}", url); throw new TimeoutException("请求超时", ex); } catch (Exception ex) { _logger.LogError(ex, "下载文件失败: {Url}", url); throw; } } /// /// 发送GET请求 /// /// 请求URL /// 响应内容 public async Task GetAsync(string url) { try { if (string.IsNullOrWhiteSpace(url)) throw new ArgumentException("URL不能为空", nameof(url)); using var httpClient = _httpClientFactory.CreateClient("HttpService"); var response = await httpClient.GetStringAsync(url); return response; } catch (Exception ex) { _logger.LogError(ex, "GET请求失败: {Url}", url); throw; } } /// /// 发送POST请求 /// /// 请求URL /// 请求内容 /// 响应内容 public async Task PostAsync(string url, string content) { try { if (string.IsNullOrWhiteSpace(url)) throw new ArgumentException("URL不能为空", nameof(url)); using var httpClient = _httpClientFactory.CreateClient("HttpService"); var httpContent = new StringContent(content, Encoding.UTF8, "application/json"); var response = await httpClient.PostAsync(url, httpContent); response.EnsureSuccessStatusCode(); return await response.Content.ReadAsStringAsync(); } catch (Exception ex) { _logger.LogError(ex, "POST请求失败: {Url}", url); throw; } } /// /// 检查URL是否可访问 /// /// 要检查的URL /// 是否可访问 public async Task IsUrlAccessibleAsync(string url) { try { using var httpClient = _httpClientFactory.CreateClient("HttpService"); using var response = await httpClient.GetAsync(url, HttpCompletionOption.ResponseHeadersRead); return response.IsSuccessStatusCode; } catch { return false; } } /// /// 获取URL的Content-Type /// /// 要检查的URL /// Content-Type public async Task GetContentTypeAsync(string url) { try { using var httpClient = _httpClientFactory.CreateClient("HttpService"); using var response = await httpClient.GetAsync(url, HttpCompletionOption.ResponseHeadersRead); if (response.IsSuccessStatusCode) { return response.Content.Headers.ContentType?.MediaType; } return null; } catch { return null; } } } }