我可以使用HTTP模块更改传入HTTP请求的内容吗?

Nit*_*amk 8 c# asp.net wcf gzip filter

我正在尝试扩展我的REST服务(使用WCF/webHttpBinding构建),以便客户端可以上载gzip压缩数据.我不确定最好的方法是什么,但我认为通过添加一个HTTP模块可以相当容易,如果传入请求的Content-Encoding设置为gzip,它将解压缩数据.

所以我创建了一个派生自IHttpModule的类,具有以下实现:

  private void OnBeginRequest(object sender, EventArgs e)
  {
     var app = (HttpApplication) sender;
     var context = app.Context;

     var contentEncoding = context.Request.Headers["Content-Encoding"];

     if (contentEncoding == "gzip")
     {
        // some debug code:
        var decompressedStream = new GZipStream(context.Request.InputStream, CompressionMode.Decompress);
        var memoryStream = new MemoryStream();
        decompressedStream.CopyTo(memoryStream);
        memoryStream.Seek(0, SeekOrigin.Begin);

        var streamReader = new StreamReader(memoryStream);
        string msg = streamReader.ReadToEnd();

        context.Request.InputStream.Seek(0, SeekOrigin.Begin);

        app.Request.Filter = //new TestFilterStream(app.Request.Filter);
                    new System.IO.Compression.GZipStream(
                    app.Request.Filter, CompressionMode.Decompress);
     }

  }
Run Code Online (Sandbox Code Playgroud)

我看到的问题是GZipStream解压缩从未实际执行过.我已经确认传入的数据实际上是gzip(msg变量包含正确的数据).我也尝试在上面创建我自己的流类(TestFilterStream)并将其分配给app.Request.Filter,并且我已经确认ASP.NET实际上没有调用流类上的任何成员.因此,虽然可以指定过滤器,但实际上并未使用该过滤器.

是不是实际使用了HttpApplication.Request.Filter?

Men*_*vel 0

我刚刚做了几个测试,只要存在请求正文并且 http 处理程序读取请求正文,我的 Request.Filter 流就会被调用。我猜您使用 PUT 或 POST,并且肯定会读取请求正文,所以这应该不是问题。

\n\n

我怀疑 Kna\xc4\xa3is 的评论是正确的。您是否尝试过不使用调试代码?如果我深入研究 HttpRequest 源代码,我会发现变量 _rawContent 只被写入一次;同时应用请求过滤器。之后,_rawContent 值只会被缓存,并且永远不会更新(添加过滤器时也不会重置)。

\n\n

因此,通过在调试代码中调用 Request.InputStream ,您肯定会阻止稍后应用您的过滤器。读取Request.Headers集合没有问题。

\n