【问题标题】:Decompress Brotli HttpResponse in a HttpClient在 HttpClient 中解压 Brotli HttpResponse
【发布时间】:2019-07-15 11:27:34
【问题描述】:

我有一个 Web Api,它向我发送使用 brotli 压缩的响应,我有一个控制台应用程序,它通过向我的 WebApi 请求数据来使用 HttpClient。我需要解压缩我的 WebApi 发送的数据。

对于 .Net Core 2.2

Startup.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>();
});

ConseleApp

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。 . .

【问题讨论】:

标签: c# .net-core dotnet-httpclient


【解决方案1】:

假设您使用的是 .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>();
}

【讨论】:

    【解决方案2】:

    我使用 Brotli.NET 实现如下:

    static async Task<string> GetLinkTitle(string link) => await Task.Run(async () =>
    {
        using (var httpGet = new System.Net.Http.HttpClient())
        {
            httpGet.DefaultRequestHeaders.Add("Accept-Encoding", "br");
            var response = await httpGet.GetAsync($"http://www.youtube.com/oembed?url={link}&format=xml");
            
            string responseContent;
            using(var brotli = new Brotli.BrotliStream(await response.Content.ReadAsStreamAsync(), System.IO.Compression.CompressionMode.Decompress, true))
            {
                var streamReader = new StreamReader(brotli);
                responseContent = streamReader.ReadToEnd();
            }
    
            var doc = XDocument.Parse(responseContent);
            return !response.IsSuccessStatusCode ? $"ERROR: {response.StatusCode} - {link}".Dump() : doc.Descendants("title").FirstOrDefault().Value;
        }
    });
    

    【讨论】:

      【解决方案3】:

      您是否尝试过以下 .Net 库之一:

      1. https://www.nuget.org/packages/Brotli.NET/
      2. https://www.nuget.org/packages/BrotliSharpLib/

      两者都支持 Brotli 压缩和解压缩,无需 .Net 原生支持。他们声称也比 .Net 实现更快。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-11-05
        • 1970-01-01
        • 2017-11-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多