응답 스트림을 가로 채기 위해 간단한 OWIN 미들웨어를 작성하려고합니다. 내가하고 싶은 것은 원래 스트림을 사용자 지정 스트림 기반 클래스로 대체하는 것입니다. 여기서 응답 스트림에 대한 쓰기를 가로 챌 수 있습니다.사용자 정의 Owin Middleware에서 응답 스트림을 안전하게 가로 챌 수있는 방법
그러나 체인의 내부 미들웨어 구성 요소가 응답을 완전히 기록한 시점을 알 수 없기 때문에 일부 문제에 직면하고 있습니다. 스트림의 Dispose
재정의는 절대로 호출되지 않습니다. 따라서 응답 처리가 끝날 때 처리가 수행되는 시점을 언제 알 수 없습니다.
public sealed class CustomMiddleware: OwinMiddleware
{
public CustomMiddleware(OwinMiddleware next)
: base(next)
{
}
public override async Task Invoke(IOwinContext context)
{
var request = context.Request;
var response = context.Response;
// capture response stream
var vr = new MemoryStream();
var responseStream = new ResponseStream(vr, response.Body);
response.OnSendingHeaders(state =>
{
var resp = (state as IOwinContext).Response;
var contentLength = resp.Headers.ContentLength;
// contentLength == null for Chunked responses
}, context);
// invoke the next middleware in the pipeline
await Next.Invoke(context);
}
}
public sealed class ResponseStream : Stream
{
private readonly Stream stream_; // MemoryStream
private readonly Stream output_; // Owin response
private long writtenBytes_ = 0L;
public ResponseStream(Stream stream, Stream output)
{
stream_ = stream;
output_ = output;
}
... // System.IO.Stream implementation
public override void Write(byte[] buffer, int offset, int count)
{
// capture writes to the response stream in our local stream
stream_.Write(buffer, offset, count);
// write to the real output stream
output_.Write(buffer, offset, count);
// update the number of bytes written
writtenBytes_ += count;
// how do we know the response is complete ?
// we could check that the number of bytes written
// is equal to the content length, but content length
// is not available for Chunked responses.
}
protected override void Dispose(bool disposing)
{
// we could perform our processing
// when the stream is disposed of.
// however, this method is never called by
// the OWIN/Katana infrastructure.
}
}
, 내가 응답이 완료 여부를 감지하기 위해 생각할 수있는 두 가지 전략이있다 : 여기
은 샘플 코드입니다.a) 응답 스트림에 기록 된 바이트 수를 기록하고 예상 응답 길이와 상관시킬 수 있습니다. 그러나 청크 분할 전송 인코딩을 사용하는 응답의 경우 길이는 알 수 없습니다.
b) Dispose
이 응답 스트림에서 호출 될 때 응답 스트림이 완료되었다고 결정할 수 있습니다. 그러나 OWIN/Katana 인프라는 교체 된 스트림에서 Dispose를 호출하지 않습니다.
내가 기본 HTTP 프로토콜을 조작하는 것이 실현 가능한 접근법인지 여부를 확인하기 위해 Opaque Streaming을 조사했지만 Katana가 Opaque Streaming을 지원하는지 여부를 찾지 못하는 것 같습니다.
내가 원하는 것을 얻을 수있는 방법이 있습니까?
답변 해 주셔서 감사합니다. 'OwinMiddleware'에서 파생 된 점. 그러나 응답에서 Katana에 고유 한 OwinContext를 사용하고 있습니다. 내가 놓친 게 있니? –
네, 맞습니다. 하지만 미들웨어에 내부적으로 OwinContext를 사용하고 있는데, 이는 Katana에 의존하고 있음을 의미합니다. 그러나 생성자 또는'Invoke' 메소드 시그니처에서이를 사용하지 않기 때문에 다른 어셈블리가 Katana에 의존하지 않도록합니다. OWIN 파이프 라인을 만드는 사람은 누구나 OwinMiddleware에 대해 알 필요가 없습니다. 비슷하게 파이프 라인에있는 미들웨어가 'Invoke'를 호출 할 때 마찬가지입니다. – Badri
David Fowler의 SO 대답에 대한 링크가 있습니다. http://stackoverflow.com/a/19613529/1709870 – Badri