是否可以在IIS HttpModule中修改Http Request POST的内容?

时间:2010-06-17 04:54:08

标签: c# iis ssas httpmodule httprequest

我需要在IIS中修改某些HttpRequests(SSAS连接字符串)的内容。基本上,我需要在请求中包含的SOAP中添加一个元素。

到目前为止,我的方法是向HttpRequest添加一个Filter,并在过滤器的Read方法中执行更改。据我所知,Read永远不会被执行。

我对Request.Filter的理解是它从IIS处理请求时读取,因此IIS应该看到我修改过的请求。

我正在尝试使用HttpModule实际可行吗?我的Filter方法是否正确?

如果是这样,什么会导致Read不被命中?

以下是我的代码的简化版本:


public class CustomHttpModule : IHttpModule {
    private HttpApplication app;
    public string ModuleName {
        get { return "CustomHttpModule"; }
    }
    public void Init(HttpApplication context) {
        app = context;
        context.PreRequestHandlerExecute += new EventHandler(context_PreRequestHandlerExecute);
    }
    void context_PreRequestHandlerExecute(object sender, EventArgs e) {
        var request = app.Context.Request;
        request.Filter = new CustomHttpFilter(request.Filter);
    }
}

public class CustomHttpFilter : Stream {
    private Stream outputStream;
    public CustomHttpFilter(Stream outputFilter) {
        outputStream = outputFilter;
    }
    public override int Read(byte[] buffer, int offset, int count) {
        // read and make the necessary changes
    }
}

3 个答案:

答案 0 :(得分:2)

实际上,可以通过IIS 7.0+中的HttpModule 修改IIS中HttpRequest POST的内容。我有这个问题,并且能够解决它。我发布以供将来参考,因为没有很多帖子详细说明何时/为什么它将起作用或不起作用。

这是一个故障排除清单:

  1. 确保您的模块和任何其他模块未访问Request对象,以便在将过滤器添加到请求过滤器之前评估输入流。例如,访问Request.Form["param"]将触发对输入流的评估。其中一个症状是您的过滤器Read方法永远不会被调用。

  2. 查看统一IIS管道https://msdn.microsoft.com/en-us/library/bb470252.aspx中的事件顺序。您将看到PreRequestHandlerExecute事件与第12个事件一样发生。为了最好地设置请求过滤器并将其应用,您应该在BeginRequest事件中执行此操作,这是请求验证和URL映射后的第一个事件(在HttpModule中公开,在ISAPI中还有其他事件暴露)扩展或过滤)。 ISAPI过滤器和扩展确实有一些事件可能发生在HttpModule事件之前,但是从

  3. 开始
  4. 考虑到Request.Filter是一个Streams链,它们会连续评估,将输出从一个传递到下一个的输入,它们也可以在模块接收输入之前修改请求。如果存在一些奇怪的行为,请考虑删除其他一些过滤器以隔离问题或更改它们的加载顺序。

  5. 还要考虑Stream过滤器的读取和写入方法是以块的形式调用的,因此可以多次调用它们,具有不同的偏移量,因此请确保您的重写逻辑正常运行,尤其是在替换内容时不同的总体请求或响应大小请参见下文。

  6. 如果您在“读取”或“写入”中执行搜索/替换,则需要考虑您的数据可能跨越多个读/写。在这种情况下,您可能需要考虑在MemoryStream中缓冲请求或响应流并改为对其进行操作。

  7. 如果您将问题隔离并简化为最基本的方案,您最终将确定导致其无法工作的原因。这里的简单示例演示了https://msdn.microsoft.com/en-us/library/system.web.httprequest.filter.aspx但是它没有演示在缓冲流上运行。

    我已经整理了一个示例,演示了缓冲请求和响应重写HttpModule以供参考。 https://github.com/snives/HttpModuleRewrite

答案 1 :(得分:1)

可以通过覆盖WorkerRequest来实现。您可以获得如下的当前工作人员请求:

(HttpWorkerRequest)context.GetService(typeof(HttpWorkerRequest))

您可以通过引用IIS7WorkerRequest.cs .net参考源来实现派生的工作者请求。

硬件从输入流中读取所有字节并解析数据。您应该知道HTTP Multipart-form数据规范。

答案 2 :(得分:0)

我认为无法使用http模块修改请求,但可以修改响应HttpRequest对象大部分是只读的,因此它通常在任何上下文中都是不可变的,而不仅仅是来自模块。

如果您真的很绝望,可以尝试使用反射来访问更多的http请求对象。但是,要访问,修改或调用非公开成员,您的流程需要完全信任权限 ,这在网络环境中风险很大