Управляемый модуль IIS 7 не может получить Content-Length или отправленные байты - PullRequest
7 голосов
/ 27 января 2009

У меня есть фильтр ISAPI для IIS 6, который выполняет некоторую пользовательскую обработку с использованием поля ответа, отправленного байтами. Я хотел бы обновить это для IIS 7, но я столкнулся с проблемой. Кажется, что ни одно из событий IIS 7 не имеет доступа к длине контента, отправленным байтам или любым данным, которые позволили бы мне рассчитать длину контента или отправленных байтов. (Я знаю, что заголовок длины содержимого и отправленные байты не совпадают, но любой из них будет работать для этой цели.)

Из того, что я могу сказать, заголовок длины содержимого добавляется HTTP.SYS после завершения выполнения управляемых модулей. Прямо сейчас у меня есть обработчик событий, который работает на EndRequest. Если бы я мог получить выходной поток, я мог бы сам рассчитать, что мне нужно, но управляемый конвейер, похоже, тоже не имеет к этому доступа.

Есть ли какой-нибудь способ получить длину содержимого или байты, отправленные в управляемом конвейере? Если это не удастся, можно ли как-нибудь рассчитать длину содержимого или байты, отправленные из объектов, доступных в управляемом конвейере?

1 Ответ

7 голосов
/ 08 февраля 2009

Чтобы получить отправленные байты, вы можете использовать свойство <a href="http://msdn.microsoft.com/en-us/library/system.web.httpresponse.filter.aspx" rel="noreferrer">HttpResponse.Filter</a>. Как сказано в документации MSDN, это свойство получает или задает объект фильтра-обертки, который используется для изменения тела объекта HTTP перед передачей.

Вы можете создать новый <a href="http://msdn.microsoft.com/en-us/library/system.io.stream.aspx" rel="noreferrer">System.IO.Stream</a>, который обернет существующий поток HttpResponse.Filter и подсчитает байты, переданные методу Write, прежде чем передать их. Например:

public class ContentLengthModule : IHttpModule
{
    public void Init(HttpApplication context)
    {
        context.BeginRequest += OnBeginRequest;
        context.EndRequest += OnEndRequest;
    }

    void OnBeginRequest(object sender, EventArgs e)
    {
        var application = (HttpApplication) sender;
        application.Response.Filter = new ContentLengthFilter(application.Response.Filter);
    }

    void OnEndRequest(object sender, EventArgs e)
    {
        var application = (HttpApplication) sender;
        var contentLengthFilter = (ContentLengthFilter) application.Response.Filter;
        var contentLength = contentLengthFilter.BytesWritten;
    }

    public void Dispose()
    {
    }
}

public class ContentLengthFilter : Stream
{
    private readonly Stream _responseFilter;

    public int BytesWritten { get; set; }

    public ContentLengthFilter(Stream responseFilter)
    {
        _responseFilter = responseFilter;
    }

    public override void Flush()
    {
        _responseFilter.Flush();
    }

    public override long Seek(long offset, SeekOrigin origin)
    {
        return _responseFilter.Seek(offset, origin);
    }

    public override void SetLength(long value)
    {
        _responseFilter.SetLength(value);
    }

    public override int Read(byte[] buffer, int offset, int count)
    {
        return _responseFilter.Read(buffer, offset, count);
    }

    public override void Write(byte[] buffer, int offset, int count)
    {
        BytesWritten += count;
        _responseFilter.Write(buffer, offset, count);
    }

    public override bool CanRead
    {
        get { return _responseFilter.CanRead; }
    }

    public override bool CanSeek
    {
        get { return _responseFilter.CanSeek; }
    }

    public override bool CanWrite
    {
        get { return _responseFilter.CanWrite; }
    }

    public override long Length
    {
        get { return _responseFilter.Length; }
    }

    public override long Position
    {
        get { return _responseFilter.Position; }
        set { _responseFilter.Position = value; }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...