]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: proto_htx: Add functions htx_transform_header and htx_transform_header_str
authorChristopher Faulet <cfaulet@haproxy.com>
Wed, 24 Oct 2018 09:25:02 +0000 (11:25 +0200)
committerWilly Tarreau <w@1wt.eu>
Sun, 18 Nov 2018 21:08:56 +0000 (22:08 +0100)
It is more or less the same than legacy versions but adapted to be called from
HTX analyzers.

include/proto/proto_http.h
src/proto_htx.c

index 54169a111700efaa6efc8aad43731f59c275a36d..0d126d6b5c6e860748a4bfdcf4a03ef12337b8ac 100644 (file)
@@ -54,6 +54,7 @@ void http_txn_reset_res(struct http_txn *txn);
 
 /* Export HTX analyzers and helpers */
 // FIXME: Rename all these functions http_* once legacy code will be removed
+struct htx;
 
 int htx_wait_for_request(struct stream *s, struct channel *req, int an_bit);
 int htx_process_req_common(struct stream *s, struct channel *req, int an_bit, struct proxy *px);
@@ -67,6 +68,8 @@ int htx_request_forward_body(struct stream *s, struct channel *req, int an_bit);
 int htx_response_forward_body(struct stream *s, struct channel *res, int an_bit);
 void htx_adjust_conn_mode(struct stream *s, struct http_txn *txn);
 int htx_apply_redirect_rule(struct redirect_rule *rule, struct stream *s, struct http_txn *txn);
+int htx_transform_header_str(struct stream* s, struct channel *chn, struct htx *htx,
+                            struct ist name, const char *str, struct my_regex *re, int action);
 void htx_server_error(struct stream *s, struct stream_interface *si, int err, int finst, const struct buffer *msg);
 void htx_reply_and_close(struct stream *s, short status, struct buffer *msg);
 
index dec02f197e6ebffeaf432823b02935561ba52bf6..ef1fe2d0a5f72a20bf38f53c0383f09807740902 100644 (file)
@@ -2543,6 +2543,48 @@ int htx_apply_redirect_rule(struct redirect_rule *rule, struct stream *s, struct
        return ret;
 }
 
+int htx_transform_header_str(struct stream* s, struct channel *chn, struct htx *htx,
+                            struct ist name, const char *str, struct my_regex *re, int action)
+{
+       struct http_hdr_ctx ctx;
+       struct buffer *output = get_trash_chunk();
+
+       /* find full header is action is ACT_HTTP_REPLACE_HDR */
+       ctx.blk = NULL;
+       while (http_find_header(htx, name, &ctx, (action == ACT_HTTP_REPLACE_HDR))) {
+               if (!regex_exec_match2(re, ctx.value.ptr, ctx.value.len, MAX_MATCH, pmatch, 0))
+                       continue;
+
+               output->data = exp_replace(output->area, output->size, ctx.value.ptr, str, pmatch);
+               if (output->data == -1)
+                       return -1;
+               if (!http_replace_header_value(htx, &ctx, ist2(output->area, output->data)))
+                       return -1;
+       }
+       return 0;
+}
+
+static int htx_transform_header(struct stream* s, struct channel *chn, struct htx *htx,
+                               const struct ist name, struct list *fmt, struct my_regex *re, int action)
+{
+       struct buffer *replace;
+       int ret = -1;
+
+       replace = alloc_trash_chunk();
+       if (!replace)
+               goto leave;
+
+       replace->data = build_logline(s, replace->area, replace->size, fmt);
+       if (replace->data >= replace->size - 1)
+               goto leave;
+
+       ret = htx_transform_header_str(s, chn, htx, name, replace->area, re, action);
+
+  leave:
+       free_trash_chunk(replace);
+       return ret;
+}
+
 /* This function terminates the request because it was completly analyzed or
  * because an error was triggered during the body forwarding.
  */