通过haproxy修改http响应的内容

modify content of http response via haproxy

我正在通过 haproxy 路由 soap 请求,其中一个响应请求的系统通过向 XML 元素添加名称空间更改了 ist 响应结构 <myresponse> 之后变为 <newnamespace:myresponse>已部署新版本。

我无法控制的客户端系统无法处理对负载的更改。因为我无法更改此客户端的代码,所以我想通过 haproxy 从响应负载中删除 newnamespace:

我已经在我的后端配置中尝试了 rspirep ^:\ "mynewnamespace:" "" 选项,但它没有任何效果

这可能吗?如果可能,怎么做?

what HAProxy is and is not部分我们可以看到,HAProxy不是:

a data scrubber : it will not modify the body of requests nor responses.

我几个月前遇到过类似的问题,看到了这个答案。既然我找到了解决问题的方法,我想 post 我的方法可以帮助其他可能被拒之门外的人。虽然坦率地说,这对你的问题来说可能有点矫枉过正

如 MoEmEn 所述,haproxy 不会修改请求或响应的主体。然而,在 haproxy's configuration guide 中,它提到了添加一些过滤器的能力,其中之一允许您压缩正文请求。这绝对修饰身材。

one of haproxy's documentation中解释了如何自己实现一个过滤器。基本上,它允许您在每个解析阶段检查 http request/response。当某事完成时,它会调用您在过滤器中定义的回调函数,然后您可以对该数据做任何您想做的事情。过滤器回调如下所示:

struct flt_ops {
    /*
     * Callbacks to manage the filter lifecycle
     */
    int  (*init)             (struct proxy *p, struct flt_conf *fconf);
    void (*deinit)           (struct proxy *p, struct flt_conf *fconf);
    int  (*check)            (struct proxy *p, struct flt_conf *fconf);
    int  (*init_per_thread)  (struct proxy *p, struct flt_conf *fconf);
    void (*deinit_per_thread)(struct proxy *p, struct flt_conf *fconf);

    /*
     * Stream callbacks
     */
    int  (*attach)            (struct stream *s, struct filter *f);
    int  (*stream_start)      (struct stream *s, struct filter *f);
    int  (*stream_set_backend)(struct stream *s, struct filter *f, struct proxy *be);
    void (*stream_stop)       (struct stream *s, struct filter *f);
    void (*detach)            (struct stream *s, struct filter *f);
    void (*check_timeouts)    (struct stream *s, struct filter *f);

    /*
     * Channel callbacks
     */
    int  (*channel_start_analyze)(struct stream *s, struct filter *f,
                                  struct channel *chn);
    int  (*channel_pre_analyze)  (struct stream *s, struct filter *f,
                                  struct channel *chn,
                                  unsigned int an_bit);
    int  (*channel_post_analyze) (struct stream *s, struct filter *f,
                                  struct channel *chn,
                                  unsigned int an_bit);
    int  (*channel_end_analyze)  (struct stream *s, struct filter *f,
                                  struct channel *chn);

    /*
     * HTTP callbacks
     */
    int  (*http_headers)       (struct stream *s, struct filter *f,
                                struct http_msg *msg);
    int  (*http_data)          (struct stream *s, struct filter *f,
                                struct http_msg *msg);
    int  (*http_chunk_trailers)(struct stream *s, struct filter *f,
                                struct http_msg *msg);
    int  (*http_end)           (struct stream *s, struct filter *f,
                                struct http_msg *msg);
    int  (*http_forward_data)  (struct stream *s, struct filter *f,
                                struct http_msg *msg,
                                unsigned int len);

    void (*http_reset)         (struct stream *s, struct filter *f,
                                struct http_msg *msg);
    void (*http_reply)         (struct stream *s, struct filter *f,
                                short status,
                                const struct buffer *msg);

    /*
     * TCP callbacks
     */
    int  (*tcp_data)        (struct stream *s, struct filter *f,
                             struct channel *chn);
    int  (*tcp_forward_data)(struct stream *s, struct filter *f,
                             struct channel *chn,
                             unsigned int len);
};

您可能感兴趣的是

http_data

因为您要删除前缀 "newnamespace:"。 Haproxy 提供了一个很好的功能来轻松删除一些东西:

/* This function writes the string <str> at position <pos> which must be in
 * buffer <b>, and moves <end> just after the end of <str>. <b>'s parameters
 * <l> and <r> are updated to be valid after the shift. The shift value
 * (positive or negative) is returned. If there's no space left, the move is
 * not done. The function does not adjust ->o because it does not make sense to
 * use it on data scheduled to be sent. For the same reason, it does not make
 * sense to call this function on unparsed data, so <orig> is not updated. The
 * string length is taken from parameter <len>. If <len> is null, the <str>
 * pointer is allowed to be null.
 */
int buffer_replace2(struct buffer *b, char *pos, char *end, const char *str, int len)

假设你发现"newnamespace:"开始于char* pos,结束于char* end,你可以调用

buffer_replace2(buf, pos, end, NULL, 0)

删除字符串。

虽然这可能有点过分,但它会解决你的问题