【问题标题】:Reading (https) response body in yarp's middleware在 yarp 的中间件中读取 (https) 响应主体
【发布时间】:2022-11-13 07:27:20
【问题描述】:

我正在尝试将请求/响应推送到弹性搜索中,但是在尝试获取响应主体时阅读文档后我被卡住了。那里说:“虽然启用缓冲是可能的,但不鼓励这样做,因为它会增加显着的内存和延迟开销。如果必须检查或修改主体,建议使用包装的流式处理方法”。所以这部分很容易理解,因为缓冲响应可能会保存到文件中. “例如,请参阅 ResponseCompression 中间件。” (Full article)

我检查了里面有什么,我被卡住了。我应该创建实现IHttpResponseBodyFeature 的类吗?

我已经实现了实现该接口的简单类:

internal class BodyReader : IHttpResponseBodyFeature, IDisposable
{
    private bool _disposedValue;

    public Stream Stream { get; } = new MemoryStream();

    public PipeWriter Writer => throw new NotImplementedException();

    public Task CompleteAsync()
    {
        return Task.CompletedTask;
    }

    public void DisableBuffering()
    {
        //throw new NotImplementedException();
    }

    public Task SendFileAsync(string path, long offset, long? count, CancellationToken cancellationToken = default)
    {
        throw new NotImplementedException();
    }

    public Task StartAsync(CancellationToken cancellationToken = default)
    {
        throw new NotImplementedException();
    }

    protected virtual void Dispose(bool disposing)
    {
        if (!_disposedValue)
        {
            if (disposing)
            {
                // TODO: dispose managed state (managed objects)
                Stream?.Dispose();
            }

            // TODO: free unmanaged resources (unmanaged objects) and override finalizer
            // TODO: set large fields to null
            _disposedValue = true;
        }
    }

    // // TODO: override finalizer only if 'Dispose(bool disposing)' has code to free unmanaged resources
    // ~Tmp()
    // {
    //     // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
    //     Dispose(disposing: false);
    // }

    public void Dispose()
    {
        // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
        Dispose(disposing: true);
        GC.SuppressFinalize(this);
    }
}

然后在中间件中:

        var bodyReader = new BodyReader();
        context.Features.Set<IHttpResponseBodyFeature>(bodyReader);

        try
        {
            await _next(context);

            bodyReader.Stream.Position = 0;
            using (var sr = new StreamReader(bodyReader.Stream))
            {
                // here should be text response but unfortunately in variable is some garbage
                // I'm guessing ciphered response?
                var html = sr.ReadToEnd();
            }

            bodyReader.Dispose();
        }
        finally
        {
            context.Features.Set(originalBodyFeature);
        }

似乎在 html 变量中有一些垃圾 - 可能是加密的?也不知道如何再次将响应推送到管道中。

我不确定方法是否好?也许我不应该使用中间件进行日志记录,或者我对 IHttpResponseBodyFeature 的实现不正确?

无论哪种方式,我都需要推动弹性请求和响应:)

【问题讨论】:

    标签: ms-yarp


    【解决方案1】:

    我在 yarp 的 github 上询问了这个问题,我得到的信息是这不是因为 https,而是因为压缩(我只是忘了它): https://github.com/microsoft/reverse-proxy/issues/1921#issuecomment-1301287432

    长话短说,添加以下内容就足够了:

    builder.Services.AddReverseProxy()
        .ConfigureHttpClient((context, handler) =>
        {
            // this is required to decompress automatically
            handler.AutomaticDecompression = System.Net.DecompressionMethods.All; 
        })
    

    快乐编码:)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-12-13
      • 1970-01-01
      • 1970-01-01
      • 2016-04-14
      • 2021-02-13
      • 1970-01-01
      • 2019-06-03
      • 1970-01-01
      相关资源
      最近更新 更多