概述
我希望能够将请求参数和内容修改为第三方Web服务(ArcGIS Server)。这将用于创建任何客户端应用程序和服务器应用程序之间存在的安全层。
我认为我找到了解决方案,但我目前在实施方面遇到了一些困难。
潜在解决方案:使用自定义请求过滤器修改请求
对于解决方案,我基于sample shown on 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;
}
只要修改后的内容长度与原始内容长度不同,这似乎效果很好。例如,如果我用2替换1,一切正常。但是,如果我用10替换1(从而将消息大小增加1),那么我从ArcGIS Server收到错误,表明该格式不受支持。
这引起了我的注意:
有什么想法吗?
答案 0 :(得分:4)
这个问题的第二部分的答案是返回修改后的内容大小,而不是原始流的大小。看哪!
// return bytesRead;
return newByteCountLength;
答案 1 :(得分:2)
这个问题和你的答案对我来说真的很有用,但如果你试图在流中插入更多的数据,答案就不是全部:
仅当您插入流中的数据不会将读取到缓冲区中的字节数超过count
值时,返回修改后的内容大小才有效。如果您尝试插入太多数据,您要么会发现buffer
对象不足以容纳您正在插入的数据,要么写入超过count
个字节的数据在缓冲区中,您将覆盖缓冲区末尾的一些数据,而这些数据本来就是一个人。
如果您需要插入的数据多于当前buffer
对象可以容纳的数据,那么您必须在单独的字节数组中缓冲数据并将其复制到块中,因为对stream.read
的调用是制成。
答案 2 :(得分:0)
正如Chris McKeown所说,除非你承诺不修改数据的大小,否则这并不是最好的过滤技术。为了完整地回答这个问题,我发布了一个示例项目,该项目演示了如果您感兴趣,如何使用缓冲技术处理请求和响应的过滤。
https://github.com/snives/HttpModuleRewrite
另外,对于有关排除HttpModules进行过滤的问题,过滤此帖也非常有用Is it possible to modify the content of HttpRequest POST in an IIS HttpModule?