【问题标题】:How can I modify a POST request using a custom IHttpModule and an HttpRequest filter?如何使用自定义 IHttpModule 和 HttpRequest 过滤器修改 POST 请求?
【发布时间】:2011-03-15 11:41:15
【问题描述】:

概述

我希望能够将请求参数和内容修改为第 3 方 Web 服务 (ArcGIS Server)。这将用于创建存在于任何客户端应用程序和服务器应用程序之间的安全层。

我认为我已经找到了解决方案,但我目前在实施中遇到了一些困难。

可能的解决方案:使用自定义请求过滤器修改请求

对于解决方案,我基于sample shown on MSDN 松散地实现了自定义请求过滤器。我已经“增强”了代码,以便我可以使用正则表达式搜索和替换必要的内容。这涉及:

  1. 将内容(存储在字节数组中)转换为字符串。
  2. 搜索字符串并执行任何必要的修改。
  3. 将修改后的字符串转换为字节数组并写入缓冲区。

一个例子如下所示:

public override int Read(byte[] buffer, int offset, int count)
{
    int bytesRead = _stream.Read(buffer, offset, count);

    string orgContent = Encoding.UTF8.GetString(buffer, offset, bytesRead);
    string orgContentDecoded = HttpUtility.UrlDecode(orgContent);
    
    string layersPattern = @"&layers=(show|hide|include|exclude):([0-9]+,?)+";
    Regex layersRegex = new Regex(layersPattern, RegexOptions.IgnoreCase);
    
    string[] permittedLayers = new string[] { "0" , "1" };
    string replacementLayers = "&layers=show:" + String.Join(",", permittedLayers);
    string newContentDecoded = layersRegex.Replace(orgContentDecoded, replacementLayers);
    
    string newContent =  newContentDecoded.Replace(",", "%2C").Replace(":", "%3A");

    byte[] newBuffer = Encoding.UTF8.GetBytes(newContent);
    int newByteCountLength = Encoding.UTF8.GetByteCount(newContent);
    
    Encoding.UTF8.GetBytes(newContent, 0, Encoding.UTF8.GetByteCount(newContent), buffer, 0);
    
    return bytesRead;
}

只要修改后的内容长度原始内容长度没有差异,这似乎效果很好。例如,如果我用 2 替换 1 一切正常。但是,如果我将 1 替换为 10(从而将消息大小增加 1),那么我会收到来自 ArcGIS Server 的错误,指出该格式不受支持。

这让我注意到了两个问题:

  1. 当前实现不处理分块请求。也就是说,如果请求 sie 足够大,则单个请求可能会多次调用 Read。 在这种情况下应该如何处理分块?
  2. 错误消息的根本原因是什么?问题是否与内容长度与流长度不同? 如何正确修改内容,以免更改其长度?

有什么想法吗?

【问题讨论】:

    标签: c# asp.net iis iis-7 httpmodule


    【解决方案1】:

    此问题第二部分的答案是返回修改后的内容大小,而不是原始流的大小。看!

    // return bytesRead;
    return newByteCountLength;
    

    【讨论】:

      【解决方案2】:

      这个问题和您的回答对我来说真的很有用,但是如果您尝试将大量数据插入流中,答案并不是全部:

      仅当您插入到流中的数据不会将读入缓冲区的字节数超过count 值时,返回修改后的内容大小才有效。如果您尝试插入太多数据,您要么会发现buffer 对象不够大,无法容纳您要插入的数据,要么会发现向缓冲区写入的字节数超过count,您正在覆盖缓冲区末尾的一些数据,这些数据本来应该被单独留下。

      如果您需要插入比当前 buffer 对象所能容纳的更多的数据,那么您必须将数据缓冲在一个单独的字节数组中,并在调用 stream.read 时将其复制到块中。

      【讨论】:

        【解决方案3】:

        正如 Chris McKeown 所说,除非您承诺不修改数据的大小,否则这并不是最好的过滤技术。为了完整回答这个问题,我发布了一个示例项目,演示了如何使用缓冲技术处理过滤请求和响应(如果您有兴趣)。

        https://github.com/snives/HttpModuleRewrite

        对于与过滤此帖子的 HttpModules 故障排除有关的问题也非常有帮助 Is it possible to modify the content of HttpRequest POST in an IIS HttpModule?

        【讨论】:

          猜你喜欢
          • 2021-07-29
          • 2018-12-30
          • 2015-01-23
          • 2020-11-14
          • 2010-11-27
          • 1970-01-01
          • 2015-07-27
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多