From: Christopher Faulet Date: Wed, 24 Oct 2018 09:25:02 +0000 (+0200) Subject: MINOR: proto_htx: Add functions htx_transform_header and htx_transform_header_str X-Git-Tag: v1.9-dev7~60 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=7233352fe46f9e1e167b183dad1c37e91fe658bc;p=thirdparty%2Fhaproxy.git MINOR: proto_htx: Add functions htx_transform_header and htx_transform_header_str It is more or less the same than legacy versions but adapted to be called from HTX analyzers. --- diff --git a/include/proto/proto_http.h b/include/proto/proto_http.h index 54169a1117..0d126d6b5c 100644 --- a/include/proto/proto_http.h +++ b/include/proto/proto_http.h @@ -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); diff --git a/src/proto_htx.c b/src/proto_htx.c index dec02f197e..ef1fe2d0a5 100644 --- a/src/proto_htx.c +++ b/src/proto_htx.c @@ -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. */