我如何使用自定义IHttpModule和HttpRequest过滤器来修改POST请求?
概观
我希望能够将请求参数和内容修改为第三方Web服务(ArcGIS Server)。 这将用于创建存在于任何客户端应用程序和服务器应用程序之间的安全层。
我认为我已经找到了解决方案,但我目前在实施中遇到了一些困难。
潜在的解决方案:使用自定义请求过滤器修改请求
对于解决方案,我基于MSDN上显示的示例松散地实现了自定义请求过滤器。 我已经'增强'了代码,以便我可以使用正则表达式来搜索和替换必要的内容。 这包括:
一个例子如下所示:
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;
}
只要修改的内容长度与原始内容长度没有差异,这似乎工作得很好。 例如,如果我用1代替1,那么一切正常。 但是,如果我用10替换1(从而将消息大小增加1),那么我会从ArcGIS Server收到格式不受支持的错误。
这引起了我的两个关注:
有什么想法吗?
这个问题的第二部分的答案是返回修改后的内容大小,而不是原始流的大小。 看哪!
// return bytesRead;
return newByteCountLength;
这个问题和你的答案对我来说真的很有用,但是如果你试图向流中插入大量数据,答案并不是全部。
只有当您插入流中的数据不会占用通过count
数值读入缓冲区的字节数时,才返回修改的内容大小。 如果尝试插入太多数据,您要么发现buffer
对象不够大,无法保存要插入的数据,要么通过将多个count
字节写入缓冲区来覆盖缓冲区末尾的一些数据本来应该放在一边。
如果您需要插入比当前buffer
对象容纳的更多数据,那么您必须将数据缓存在单独的字节数组中,并在调用stream.read
将其复制为块。
正如Chris McKeown所说,除非您保证不修改数据大小,否则这不是真正的过滤技术。 为了完整回答这个问题,我发布了一个示例项目,演示如何处理过滤请求和响应使用缓冲技术,如果你有兴趣。
https://github.com/snives/HttpModuleRewrite
也有关排除HttpModules过滤这篇文章的问题也很有帮助是否可以修改IIS HttpModule中的HttpRequest POST的内容?
链接地址: http://www.djcxy.com/p/7601.html上一篇: How can I modify a POST request using a custom IHttpModule and an HttpRequest filter?
下一篇: Mixing Active Records with Standard SQL Query in Codeigniter