7

応答のバイト送信フィールドを使用してカスタム処理を行う IIS 6 用の ISAPI フィルターがあります。IIS 7 用に更新したいのですが、問題が発生しています。IIS 7 イベントのいずれも、コンテンツの長さ、送信されたバイト数、またはコンテンツの長さまたは送信されたバイト数を計算できるデータにアクセスできないようです。(コンテンツ長ヘッダーと送信されるバイトが同じではないことはわかっていますが、この目的にはどちらも機能します。)

私が知る限り、Content-Length ヘッダーは、マネージ モジュールの実行が終了した後に HTTP.SYS によって追加されます。現在、EndRequest で実行されるイベント ハンドラーがあります。出力ストリームを取得できれば、必要なものを自分で計算できますが、管理されたパイプラインもそれにアクセスできないようです。

管理されたパイプラインで送信されたコンテンツの長さまたはバイトを取得する方法はありますか? それができない場合、管理されたパイプラインで利用可能なオブジェクトから送信されたコンテンツの長さまたはバイトを計算する方法はありますか?

4

1 に答える 1

8

送信されたバイトを取得するには、HttpResponse.Filterプロパティを使用できます。MSDN のドキュメントによると、このプロパティは、送信前に HTTP エンティティ本体を変更するために使用されるラッピング フィルター オブジェクトを取得または設定します。

既存のストリームSystem.IO.Streamをラップする new を作成し、メソッドに渡されるバイト数をカウントしてから渡すことができます。例えば:HttpResponse.FilterWrite

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; }
    }
}
于 2009-02-08T20:46:35.857 に答える