Как можно безопасно перехватить поток ответов в пользовательском промежуточном программном обеспечении Owin

Я пытаюсь написать простуюOwin Промежуточное программное обеспечение, чтобы перехватить поток ответа. То, что я пытаюсь сделать, это заменить исходный поток собственным классом на основе потока, где я смогу перехватывать записи в поток ответов.

Однако я сталкиваюсь с некоторыми проблемами, потому что не могу знать, когда ответ был полностью записан внутренними компонентами промежуточного программного обеспечения в цепочке.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.
    }
}

Как я упоминал в комментариях из приведенного выше кода, я могу придумать две стратегии, чтобы определить, завершен ли ответ.

а) Я могу записать количество байтов, записанных в поток ответов, и сопоставить их с ожидаемой длиной ответа. Однако в случае ответов, в которых используется кодирование передачи по частям, длина неизвестна.

б) я могу решить, что поток ответа завершен, когдаDispose вызывается в потоке ответа. Однако инфраструктура OWIN / Katana никогда не вызывает Dispose в замененном потоке.

Я расследовалНепрозрачный Поток для того, чтобы увидеть, будет ли осуществимым манипулирование базовым протоколом HTTP, но я, похоже, не выяснил, поддерживает ли Katana Opaque Streaming или нет.

Есть ли способ добиться того, чего я хочу?

Ответы на вопрос(1)

Ваш ответ на вопрос