c# - 在 HttpClient 中解压 Brotli HttpResponse
问题描述
我有一个 Web Api,它向我发送使用 brotli 压缩的响应,我有一个控制台应用程序,它通过向我的 WebApi 请求数据来使用 HttpClient。我需要解压缩我的 WebApi 发送的数据。
对于 .Net Core 2.2
启动.cs
//Compresión de respuestas del servidor
services.Configure<BrotliCompressionProviderOptions>(opciones =>
opciones.Level = CompressionLevel.Optimal
);
services.AddResponseCompression(opciones =>
{
opciones.EnableForHttps = true;
opciones.Providers.Add<BrotliCompressionProvider>();
});
控制台应用程序
using (var client = new HttpClient(handler)){
client.BaseAddress = new Uri(BASE_URL);
client.Timeout = new TimeSpan(0, 0, TIMEOUT_SECONDS);
HttpRequestHeaders headers = client.DefaultRequestHeaders;
headers.Add("X-User", Environment.UserName);
headers.Add("Accept-Encoding", "br"); //gzip
HttpResponseMessage response = null;
response = await client.GetAsync($"{requestUrl}");
if (response.IsSuccessStatusCode)
{
string strResult = await response.Content.ReadAsStringAsync();
return JsonConvert.DeserializeObject<T>(strResult);
}
}
strResult 不是 JSON。. .
解决方案
假设您使用的是 .NET Core 2.1 中包含的 HttpClientFactory,那么您只需创建一个委托处理程序,该处理程序将在将完整的有效负载交给您的代码之前拦截并解压缩它。
using System.Linq;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using BrotliSharpLib;
public class BrotliCompressionHandler : DelegatingHandler
{
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
var response = await base.SendAsync(request, cancellationToken);
if (!response.Content.Headers.TryGetValues("Content-Encoding", out var ce) || ce.First() != "br")
return response;
var buffer = await response.Content.ReadAsByteArrayAsync();
response.Content = new ByteArrayContent(Brotli.DecompressBuffer(buffer, 0, buffer.Length));
return response;
}
}
然后只需将处理程序连接到您需要支持 brotli 的客户端。
public void ConfigureServices(IServiceCollection services)
{
services
.AddTransient<BrotliCompressionHandler>()
.AddHttpClient("github", c =>
{
c.BaseAddress = new Uri("https://api.github.com/");
c.DefaultRequestHeaders.Add("Accept", "application/vnd.github.v3+json");
c.DefaultRequestHeaders.Add("User-Agent", "HttpClientFactory-Sample");
})
.AddHttpMessageHandler<BrotliCompressionHandler>();
}
推荐阅读
- javascript - 从父元素javascript中删除类
- c# - 系统范围的全局列表变量是否存在
- javascript - 打字稿问题:受限制的属性类型不兼容
- r - 更改字符串中间单个字符的大小写
- c++ - 如何确定为 boost::stacktrace::safe_dump_to 分配多少空间?
- java - 如何禁用启用与 IoT 中心的连接?
- symfony - 在 symfony 中添加普通文本类型字段(不是文本框)
- dataframe - 使用 pandas styler 将逐行彩色数据框导出到 excel
- python - 更新 Azure 核心工具后 Python Azure 函数因 AttributeError('__enter__') 失败
- authentication - 我可以从 Blazor 客户端中的 AuthenticationStateProvider 访问我的 ID 令牌吗?