2009-01-27 24 views
7

IIS 6 için ISAPI filtresine sahibim, bu da yanıtın bayt tarafından gönderilen alanını kullanan bazı özel işlemler yapıyor. IIS 7 için bunu güncellemek istiyorum, ancak bir sorunla karşılaşıyorum. IIS 7 olaylarından hiçbiri, gönderilen içerik uzunluğuna, gönderilen bayt sayısına veya gönderilen içerik uzunluğunu veya baytları hesaplamama izin verecek herhangi bir veriye sahip görünmüyor. (İçerik uzunluğu üstbilgisi ve gönderilen baytların aynı olmadığını biliyorum, ancak bu amaç için çalışacaklardır.)IIS 7 yönetilen modül, Content-Length veya byte gönderilemedi

Açıklayabildiğim kadarıyla, içerik uzunluğu üstbilgisi yönetilen modüllerden sonra HTTP.SYS tarafından eklenir. yürütmeyi bitirdi. Şu anda EndRequest'te çalışan bir olay işleyicim var. Çıkış akışına ulaşabilseydim, kendime ihtiyacım olan şeyi hesaplayabilirdim, ancak yönetilen boru hattı da buna erişim sağlayamıyor gibi görünüyor.

Yönetilen boru hattında gönderilen içerik uzunluğunu veya baytları almanın bir yolu var mı? Başarısız olan şey, yönetilen boru hattında bulunan nesnelerden gönderilen içerik uzunluğunu veya baytları hesaplayabilmem için bir yol var mı?

+0

Bu sorunun yanıtlanmasında yardımcı olabilecek ekleyebileceğim bir şey var mı? –

cevap

7

Gönderilen baytlara ulaşmak için HttpResponse.Filter özelliğini kullanabilirsiniz. MSDN belgelerine göre, bu özellik aktarımdan önce HTTP varlık gövdesini değiştirmek için kullanılan bir sarma filtresi nesnesi alır veya ayarlar.

Varolan HttpResponse.Filter akışını tamamlayan ve iletilmeden önce Write yöntemine iletilen baytları sayan yeni bir System.IO.Stream oluşturabilirsiniz. Örneğin:

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; } 
    } 
} 
+0

Çok eksiksiz cevap ve kod örneği için teşekkürler. Şimdi sadece onu takıp denemek için bir şansa ihtiyacım var. –

+0

Tam olarak ihtiyacım olan şey buydu. Tekrar teşekkürler. –