gzip 编码(.net 8)请求解压中间件错误(InvalidDataException)

问题描述 投票:0回答:1

客户端

目标框架:netstandard2.0。还在 .net8
上进行了测试 操作系统:Windows 10
该请求由 HttpClient 从 Windows 应用程序发出。源代码:

Test(someHostName, someSecretePath, jsonContent);

private static void Test(string host, string url, string jsonContent)
{
    var client = new HttpClient()
    {
        BaseAddress = new Uri(host)
    };
    var request = new HttpRequestMessage
    {
        Method = new HttpMethod("Post"),
        RequestUri = new Uri(url),
    };
    request.Content = new StringContent(Compress(jsonContent), Encoding.UTF8, "application/json");
    request.Content.Headers.ContentEncoding.Add("gzip");

    using var result = client.Send(request);
}

private static string Compress(string inputStr)
{
    var bytes = Encoding.Unicode.GetBytes(inputStr);
    using (var msi = new MemoryStream(bytes))
    {
        using (var mso = new MemoryStream())
        {
            using (var gs = new GZipStream(mso, CompressionMode.Compress, true))
            {
                msi.CopyTo(gs);
            }
            return Convert.ToBase64String(mso.ToArray());
        }
    }
}

服务器端

目标框架:net8.0
主持人:Kestrel
程序.cs

public static void Main(string[] args)
{
    var builder = WebApplication.CreateBuilder(args);

    // Add services to the container.
    builder.Services.AddRequestDecompression();
    builder.Services.AddEndpointsApiExplorer();
    builder.Services.AddControllers().AddNewtonsoftJson();

    var app = builder.Build();

    app.UseRequestDecompression();
    app.MapControllers();
    app.Run();
}

服务器端调试

Http请求

Protocol: HTTP/1.1
Method: POST
Scheme: http
PathBase: 
Path: /someSecretPath
Host: someSecretHost
Content-Type: application/json; charset=utf-8
Content-Length: 236
Content-Encoding: gzip

来自调试窗口的日志:

dbug: Microsoft.AspNetCore.RequestDecompression.DefaultRequestDecompressionProvider[4]
      **The request will be decompressed with 'gzip'**.
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[0]
      Executing endpoint 'WebApiNet8.Controllers.SomeController.CreateAsync (WebApi)'
dbug: Microsoft.AspNetCore.Server.Kestrel[25]
      Connection id "0HN11D3HP3G05", Request id "0HN11D3HP3G05:00000001": started reading request body.
dbug: Microsoft.AspNetCore.Server.Kestrel[26]
      Connection id "0HN11D3HP3G05", Request id "0HN11D3HP3G05:00000001": done reading request body.
Exception thrown: "System.IO.InvalidDataException" в System.Private.CoreLib.dll

fail: Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware[1]
      An unhandled exception has occurred while executing the request.
      System.IO.InvalidDataException: **The archive entry was compressed using an unsupported compression method.**
         at System.IO.Compression.Inflater.Inflate(FlushCode flushCode)
         at System.IO.Compression.Inflater.ReadInflateOutput(Byte* bufPtr, Int32 length, FlushCode flushCode, Int32& bytesRead)
         at System.IO.Compression.Inflater.ReadOutput(Byte* bufPtr, Int32 length, Int32& bytesRead)
         at System.IO.Compression.Inflater.InflateVerified(Byte* bufPtr, Int32 length)
         at System.IO.Compression.DeflateStream.<ReadAsyncMemory>g__Core|51_0(Memory`1 buffer, CancellationToken cancellationToken)
         at SizeLimitedStream.ReadAsync(Memory`1 buffer, CancellationToken cancellationToken)

在日志中我可以看到解压中间件已找到正确的解压提供程序并创建了流。但是在stream的read方法中却出现了读取数据的错误。

问题

有谁知道什么可能导致这样的问题?如何避免这种情况?

c# asp.net compression gzip .net-8.0
1个回答
0
投票

gzip压缩后的数据是二进制数据而不是字符串 试试这个

private static byte[] Compress(string inputStr)
{
    var bytes = Encoding.UTF8.GetBytes(inputStr); // Use UTF-8 instead of Unicode
    using (var mso = new MemoryStream())
    {
        using (var gs = new GZipStream(mso, CompressionMode.Compress))
        {
            gs.Write(bytes, 0, bytes.Length);
        }
        return mso.ToArray(); // Send the binary data directly
    }
}

您可能还需要更改测试方法

request.Content = new ByteArrayContent(compressedData);
© www.soinside.com 2019 - 2024. All rights reserved.