2009-01-27 15 views
7

Tôi có bộ lọc ISAPI cho IIS 6, một số quy trình tùy chỉnh sử dụng trường được gửi byte của phản hồi. Tôi muốn cập nhật cho IIS 7, nhưng tôi đang chạy vào một vấn đề. Không có sự kiện nào trong số các sự kiện IIS 7 dường như có quyền truy cập vào chiều dài nội dung, byte được gửi hoặc bất kỳ dữ liệu nào cho phép tôi tính toán độ dài nội dung hoặc byte được gửi. (Tôi biết tiêu đề nội dung và byte được gửi không giống nhau, nhưng sẽ hoạt động cho mục đích này.)Mô-đun được quản lý IIS 7 không thể nhận được Content-Length hoặc byte được gửi

Từ những gì tôi có thể biết, tiêu đề nội dung có độ dài được thêm bởi HTTP.SYS sau các mô-đun được quản lý đã thực hiện xong. Ngay bây giờ tôi có một trình xử lý sự kiện chạy trên EndRequest. Nếu tôi có thể nhận được ở các dòng đầu ra tôi có thể tính toán những gì tôi cần bản thân mình nhưng đường ống quản lý dường như không có quyền truy cập vào đó hoặc.

Có cách nào để nhận được độ dài nội dung hoặc byte được gửi trong kênh được quản lý không? Nếu không, có cách nào tôi có thể tính toán độ dài nội dung hoặc byte được gửi từ các đối tượng có sẵn trong đường ống được quản lý không?

+0

Tôi có thể thêm bất kỳ điều gì giúp trả lời câu hỏi này không? –

Trả lời

7

Để nhận các byte được gửi, bạn có thể sử dụng thuộc tính HttpResponse.Filter. Theo tài liệu MSDN nói thuộc tính này nhận hoặc đặt một đối tượng lọc gói được sử dụng để sửa đổi phần thân thực thể HTTP trước khi truyền.

Bạn có thể tạo System.IO.Stream mới kết thúc tốt đẹp luồng hiện tại HttpResponse.Filter và tính các byte được chuyển vào phương thức Write trước khi truyền chúng. Ví dụ:

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

Cảm ơn câu trả lời và mẫu mã hoàn chỉnh. Bây giờ tôi chỉ cần một cơ hội để cắm nó vào và thử nó ra. –

+0

Đó chính xác là những gì tôi cần. Cám ơn bạn một lần nữa. –

Các vấn đề liên quan