我正试图将请求/响应推送到弹性搜索中,但在阅读文档后,当我试图获取响应主体时,我被卡住了。上面写着:;虽然启用缓冲是可能的,但不鼓励这样做,因为这会增加大量内存和延迟开销。如果必须检查或修改身体,建议使用包装的流式方法;。因此,这一部分是可以理解的,因为缓冲的响应可能会保存到文件中。"有关示例,请参阅ResponseCompression中间件"(全文(
我检查了里面的东西,我被卡住了。我应该创建实现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的实现不正确?
无论哪种方式,我都需要进入弹性请求和响应:(
我在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;
})
快乐编码:(