IIS 7 托管模块无法获取 Content-Length 或发送的字节数

Posted

技术标签:

【中文标题】IIS 7 托管模块无法获取 Content-Length 或发送的字节数【英文标题】:IIS 7 managed module can't get Content-Length or bytes sent 【发布时间】:2010-10-03 19:05:01 【问题描述】:

我有一个用于 IIS 6 的 ISAPI 过滤器,它使用响应的字节发送字段进行一些自定义处理。我想为 IIS 7 更新它,但我遇到了问题。 IIS 7 事件似乎都无法访问内容长度、发送的字节数或任何可以让我计算内容长度或发送的字节数的数据。 (我知道发送的内容长度标头和字节不一样,但都可以用于此目的。)

据我所知,内容长度标头是在托管模块完成执行后由 HTTP.SYS 添加的。现在我有一个在 EndRequest 上运行的事件处理程序。如果我能得到输出流,我可以自己计算出我需要什么,但托管管道似乎也无法访问它。

是否有某种方法可以获取在托管管道中发送的内容长度或字节?如果做不到这一点,有什么方法可以计算从托管管道中可用的对象发送的内容长度或字节数?

【问题讨论】:

有什么我可以补充的可以帮助回答这个问题吗? 【参考方案1】:

要获取发送的字节,您可以使用@987654321@ 属性。正如 MSDN 文档所说,此属性获取或设置一个包装过滤器对象,该对象用于在传输之前修改 HTTP 实体主体。

您可以创建一个新的@987654322@ 来包装现有的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; 
    

【讨论】:

感谢您提供非常完整的答案和代码示例。现在我只需要一个机会插上它并尝试一下。 这正是我所需要的。再次感谢您。

以上是关于IIS 7 托管模块无法获取 Content-Length 或发送的字节数的主要内容,如果未能解决你的问题,请参考以下文章

无法在 IIS 托管应用程序上使用 System.DirectoryServices.AccountManagement 获取 LDAP 数据

无法在 ASP.NET Core 5.0 下的 IIS 中托管 CoreWcf

在 IIS 7.5 中托管的 .Net Remoting 服务中,如何删除“Server : IIS/7.5”标记表单响应头

无法在 IIS 中托管 Web 服务

IIS 7 托管 WCF 服务使用域帐户作为应用程序池标识

如何诊断由 IIS7 托管的 WCF 服务中的 W3WP.exe 错误