/*
 * HTTP actions
 *
 * Copyright 2000-2018 Willy Tarreau <w@1wt.eu>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version
 * 2 of the License, or (at your option) any later version.
 *
 */

#include <sys/types.h>

#include <ctype.h>
#include <string.h>
#include <time.h>

#include <haproxy/acl.h>
#include <haproxy/action.h>
#include <haproxy/api.h>
#include <haproxy/arg.h>
#include <haproxy/capture-t.h>
#include <haproxy/cfgparse.h>
#include <haproxy/chunk.h>
#include <haproxy/global.h>
#include <haproxy/http.h>
#include <haproxy/http_ana.h>
#include <haproxy/http_htx.h>
#include <haproxy/http_rules.h>
#include <haproxy/log.h>
#include <haproxy/pattern.h>
#include <haproxy/pool.h>
#include <haproxy/regex.h>
#include <haproxy/sample.h>
#include <haproxy/sc_strm.h>
#include <haproxy/stconn.h>
#include <haproxy/tools.h>
#include <haproxy/uri_auth-t.h>
#include <haproxy/uri_normalizer.h>
#include <haproxy/version.h>


/* Release memory allocated by most of HTTP actions. Concretly, it releases
 * <arg.http>.
 */
static void release_http_action(struct act_rule *rule)
{
	struct logformat_node *lf, *lfb;

	istfree(&rule->arg.http.str);
	if (rule->arg.http.re)
		regex_free(rule->arg.http.re);
	list_for_each_entry_safe(lf, lfb, &rule->arg.http.fmt, list) {
		LIST_DELETE(&lf->list);
		release_sample_expr(lf->expr);
		free(lf->arg);
		free(lf);
	}
}

/* Release memory allocated by HTTP actions relying on an http reply. Concretly,
 * it releases <.arg.http_reply>
 */
static void release_act_http_reply(struct act_rule *rule)
{
	release_http_reply(rule->arg.http_reply);
	rule->arg.http_reply = NULL;
}


/* Check function for HTTP actions relying on an http reply. The function
 * returns 1 in success case, otherwise, it returns 0 and err is filled.
 */
static int check_act_http_reply(struct act_rule *rule, struct proxy *px, char **err)
{
	struct http_reply *reply = rule->arg.http_reply;

	if (!http_check_http_reply(reply, px, err)) {
		release_act_http_reply(rule);
		return 0;
	}
	return 1;
}


/* This function executes one of the set-{method,path,query,uri} actions. It
 * builds a string in the trash from the specified format string. It finds
 * the action to be performed in <.action>, previously filled by function
 * parse_set_req_line(). The replacement action is executed by the function
 * http_action_set_req_line(). On success, it returns ACT_RET_CONT. If an error
 * occurs while soft rewrites are enabled, the action is canceled, but the rule
 * processing continue. Otherwsize ACT_RET_ERR is returned.
 */
static enum act_return http_action_set_req_line(struct act_rule *rule, struct proxy *px,
                                                struct session *sess, struct stream *s, int flags)
{
	struct buffer *replace;
	enum act_return ret = ACT_RET_CONT;

	replace = alloc_trash_chunk();
	if (!replace)
		goto fail_alloc;

	/* If we have to create a query string, prepare a '?'. */
	if (rule->action == 2) // set-query
		replace->area[replace->data++] = '?';
	replace->data += build_logline(s, replace->area + replace->data,
				       replace->size - replace->data,
				       &rule->arg.http.fmt);

	if (http_req_replace_stline(rule->action, replace->area, replace->data, px, s) == -1)
		goto fail_rewrite;

  leave:
	free_trash_chunk(replace);
	return ret;

  fail_alloc:
	if (!(s->flags & SF_ERR_MASK))
		s->flags |= SF_ERR_RESOURCE;
	ret = ACT_RET_ERR;
	goto leave;

  fail_rewrite:
	_HA_ATOMIC_INC(&sess->fe->fe_counters.failed_rewrites);
	if (s->flags & SF_BE_ASSIGNED)
		_HA_ATOMIC_INC(&s->be->be_counters.failed_rewrites);
	if (sess->listener && sess->listener->counters)
		_HA_ATOMIC_INC(&sess->listener->counters->failed_rewrites);
	if (objt_server(s->target))
		_HA_ATOMIC_INC(&__objt_server(s->target)->counters.failed_rewrites);

	if (!(s->txn->req.flags & HTTP_MSGF_SOFT_RW)) {
		ret = ACT_RET_ERR;
		if (!(s->flags & SF_ERR_MASK))
			s->flags |= SF_ERR_PRXCOND;
	}
	goto leave;
}

/* parse an http-request action among :
 *   set-method
 *   set-path
 *   set-pathq
 *   set-query
 *   set-uri
 *
 * All of them accept a single argument of type string representing a log-format.
 * The resulting rule makes use of <http.fmt> to store the log-format list head,
 * and <.action> to store the action type as an int (0=method, 1=path, 2=query,
 * 3=uri). It returns ACT_RET_PRS_OK on success, ACT_RET_PRS_ERR on error.
 */
static enum act_parse_ret parse_set_req_line(const char **args, int *orig_arg, struct proxy *px,
                                             struct act_rule *rule, char **err)
{
	int cur_arg = *orig_arg;
	int cap = 0;

	switch (args[0][4]) {
	case 'm' :
		rule->action = 0; // set-method
		break;
	case 'p' :
		if (args[0][8] == 'q')
			rule->action = 4; // set-pathq
		else
			rule->action = 1; // set-path
		break;
	case 'q' :
		rule->action = 2; // set-query
		break;
	case 'u' :
		rule->action = 3; // set-uri
		break;
	default:
		memprintf(err, "internal error: unhandled action '%s'", args[0]);
		return ACT_RET_PRS_ERR;
	}
	rule->action_ptr = http_action_set_req_line;
	rule->release_ptr = release_http_action;
	LIST_INIT(&rule->arg.http.fmt);

	if (!*args[cur_arg] ||
	    (*args[cur_arg + 1] && strcmp(args[cur_arg + 1], "if") != 0 && strcmp(args[cur_arg + 1], "unless") != 0)) {
		memprintf(err, "expects exactly 1 argument <format>");
		return ACT_RET_PRS_ERR;
	}

	px->conf.args.ctx = ARGC_HRQ;
	if (px->cap & PR_CAP_FE)
		cap |= SMP_VAL_FE_HRQ_HDR;
	if (px->cap & PR_CAP_BE)
		cap |= SMP_VAL_BE_HRQ_HDR;
	if (!parse_logformat_string(args[cur_arg], px, &rule->arg.http.fmt, LOG_OPT_HTTP, cap, err)) {
		return ACT_RET_PRS_ERR;
	}

	(*orig_arg)++;
	return ACT_RET_PRS_OK;
}

/* This function executes the http-request normalize-uri action.
 * `rule->action` is expected to be a value from `enum act_normalize_uri`.
 *
 * On success, it returns ACT_RET_CONT. If an error
 * occurs while soft rewrites are enabled, the action is canceled, but the rule
 * processing continue. Otherwsize ACT_RET_ERR is returned.
 */
static enum act_return http_action_normalize_uri(struct act_rule *rule, struct proxy *px,
                                                 struct session *sess, struct stream *s, int flags)
{
	enum act_return ret = ACT_RET_CONT;
	struct htx *htx = htxbuf(&s->req.buf);
	const struct ist uri = htx_sl_req_uri(http_get_stline(htx));
	struct buffer *replace = alloc_trash_chunk();
	enum uri_normalizer_err err = URI_NORMALIZER_ERR_INTERNAL_ERROR;

	if (!replace)
		goto fail_alloc;

	switch ((enum act_normalize_uri) rule->action) {
		case ACT_NORMALIZE_URI_PATH_MERGE_SLASHES: {
			struct http_uri_parser parser = http_uri_parser_init(uri);
			const struct ist path = http_parse_path(&parser);
			struct ist newpath = ist2(replace->area, replace->size);

			if (!isttest(path))
				goto leave;

			err = uri_normalizer_path_merge_slashes(iststop(path, '?'), &newpath);

			if (err != URI_NORMALIZER_ERR_NONE)
				break;

			if (!http_replace_req_path(htx, newpath, 0))
				goto fail_rewrite;

			break;
		}
		case ACT_NORMALIZE_URI_PATH_STRIP_DOT: {
			struct http_uri_parser parser = http_uri_parser_init(uri);
			const struct ist path = http_parse_path(&parser);
			struct ist newpath = ist2(replace->area, replace->size);

			if (!isttest(path))
				goto leave;

			err = uri_normalizer_path_dot(iststop(path, '?'), &newpath);

			if (err != URI_NORMALIZER_ERR_NONE)
				break;

			if (!http_replace_req_path(htx, newpath, 0))
				goto fail_rewrite;

			break;
		}
		case ACT_NORMALIZE_URI_PATH_STRIP_DOTDOT:
		case ACT_NORMALIZE_URI_PATH_STRIP_DOTDOT_FULL: {
			struct http_uri_parser parser = http_uri_parser_init(uri);
			const struct ist path = http_parse_path(&parser);
			struct ist newpath = ist2(replace->area, replace->size);

			if (!isttest(path))
				goto leave;

			err = uri_normalizer_path_dotdot(iststop(path, '?'), rule->action == ACT_NORMALIZE_URI_PATH_STRIP_DOTDOT_FULL, &newpath);

			if (err != URI_NORMALIZER_ERR_NONE)
				break;

			if (!http_replace_req_path(htx, newpath, 0))
				goto fail_rewrite;

			break;
		}
		case ACT_NORMALIZE_URI_QUERY_SORT_BY_NAME: {
			struct http_uri_parser parser = http_uri_parser_init(uri);
			const struct ist path = http_parse_path(&parser);
			struct ist newquery = ist2(replace->area, replace->size);

			if (!isttest(path))
				goto leave;

			err = uri_normalizer_query_sort(istfind(path, '?'), '&', &newquery);

			if (err != URI_NORMALIZER_ERR_NONE)
				break;

			if (!http_replace_req_query(htx, newquery))
				goto fail_rewrite;

			break;
		}
		case ACT_NORMALIZE_URI_PERCENT_TO_UPPERCASE:
		case ACT_NORMALIZE_URI_PERCENT_TO_UPPERCASE_STRICT: {
			struct http_uri_parser parser = http_uri_parser_init(uri);
			const struct ist path = http_parse_path(&parser);
			struct ist newpath = ist2(replace->area, replace->size);

			if (!isttest(path))
				goto leave;

			err = uri_normalizer_percent_upper(path, rule->action == ACT_NORMALIZE_URI_PERCENT_TO_UPPERCASE_STRICT, &newpath);

			if (err != URI_NORMALIZER_ERR_NONE)
				break;

			if (!http_replace_req_path(htx, newpath, 1))
				goto fail_rewrite;

			break;
		}
		case ACT_NORMALIZE_URI_PERCENT_DECODE_UNRESERVED:
		case ACT_NORMALIZE_URI_PERCENT_DECODE_UNRESERVED_STRICT: {
			struct http_uri_parser parser = http_uri_parser_init(uri);
			const struct ist path = http_parse_path(&parser);
			struct ist newpath = ist2(replace->area, replace->size);

			if (!isttest(path))
				goto leave;

			err = uri_normalizer_percent_decode_unreserved(path, rule->action == ACT_NORMALIZE_URI_PERCENT_DECODE_UNRESERVED_STRICT, &newpath);

			if (err != URI_NORMALIZER_ERR_NONE)
				break;

			if (!http_replace_req_path(htx, newpath, 1))
				goto fail_rewrite;

			break;
		}
		case ACT_NORMALIZE_URI_FRAGMENT_STRIP: {
			struct http_uri_parser parser = http_uri_parser_init(uri);
			const struct ist path = http_parse_path(&parser);
			struct ist newpath = ist2(replace->area, replace->size);

			if (!isttest(path))
				goto leave;

			err = uri_normalizer_fragment_strip(path, &newpath);

			if (err != URI_NORMALIZER_ERR_NONE)
				break;

			if (!http_replace_req_path(htx, newpath, 1))
				goto fail_rewrite;

			break;
		}
		case ACT_NORMALIZE_URI_FRAGMENT_ENCODE: {
			struct http_uri_parser parser = http_uri_parser_init(uri);
			const struct ist path = http_parse_path(&parser);
			struct ist newpath = ist2(replace->area, replace->size);

			if (!isttest(path))
				goto leave;

			err = uri_normalizer_fragment_encode(path, &newpath);

			if (err != URI_NORMALIZER_ERR_NONE)
				break;

			if (!http_replace_req_path(htx, newpath, 1))
				goto fail_rewrite;

			break;
		}
	}

	switch (err) {
	case URI_NORMALIZER_ERR_NONE:
		break;
	case URI_NORMALIZER_ERR_INTERNAL_ERROR:
		ret = ACT_RET_ERR;
		break;
	case URI_NORMALIZER_ERR_INVALID_INPUT:
		ret = ACT_RET_INV;
		break;
	case URI_NORMALIZER_ERR_ALLOC:
		goto fail_alloc;
	}

  leave:
	free_trash_chunk(replace);
	return ret;

  fail_alloc:
	if (!(s->flags & SF_ERR_MASK))
		s->flags |= SF_ERR_RESOURCE;
	ret = ACT_RET_ERR;
	goto leave;

  fail_rewrite:
	_HA_ATOMIC_ADD(&sess->fe->fe_counters.failed_rewrites, 1);
	if (s->flags & SF_BE_ASSIGNED)
		_HA_ATOMIC_ADD(&s->be->be_counters.failed_rewrites, 1);
	if (sess->listener && sess->listener->counters)
		_HA_ATOMIC_ADD(&sess->listener->counters->failed_rewrites, 1);
	if (objt_server(s->target))
		_HA_ATOMIC_ADD(&__objt_server(s->target)->counters.failed_rewrites, 1);

	if (!(s->txn->req.flags & HTTP_MSGF_SOFT_RW)) {
		ret = ACT_RET_ERR;
		if (!(s->flags & SF_ERR_MASK))
			s->flags |= SF_ERR_PRXCOND;
	}
	goto leave;
}

/* Parses the http-request normalize-uri action. It expects a single <normalizer>
 * argument, corresponding too a value in `enum act_normalize_uri`.
 *
 * It returns ACT_RET_PRS_OK on success, ACT_RET_PRS_ERR on error.
 */
static enum act_parse_ret parse_http_normalize_uri(const char **args, int *orig_arg, struct proxy *px,
                                                   struct act_rule *rule, char **err)
{
	int cur_arg = *orig_arg;

	rule->action_ptr = http_action_normalize_uri;
	rule->release_ptr = NULL;

	if (!*args[cur_arg]) {
		memprintf(err, "missing argument <normalizer>");
		return ACT_RET_PRS_ERR;
	}

	if (strcmp(args[cur_arg], "path-merge-slashes") == 0) {
		cur_arg++;

		rule->action = ACT_NORMALIZE_URI_PATH_MERGE_SLASHES;
	}
	else if (strcmp(args[cur_arg], "path-strip-dot") == 0) {
		cur_arg++;

		rule->action = ACT_NORMALIZE_URI_PATH_STRIP_DOT;
	}
	else if (strcmp(args[cur_arg], "path-strip-dotdot") == 0) {
		cur_arg++;

		if (strcmp(args[cur_arg], "full") == 0) {
			cur_arg++;
			rule->action = ACT_NORMALIZE_URI_PATH_STRIP_DOTDOT_FULL;
		}
		else if (!*args[cur_arg]) {
			rule->action = ACT_NORMALIZE_URI_PATH_STRIP_DOTDOT;
		}
		else if (strcmp(args[cur_arg], "if") != 0 && strcmp(args[cur_arg], "unless") != 0) {
			memprintf(err, "unknown argument '%s' for 'path-strip-dotdot' normalizer", args[cur_arg]);
			return ACT_RET_PRS_ERR;
		}
	}
	else if (strcmp(args[cur_arg], "query-sort-by-name") == 0) {
		cur_arg++;

		rule->action = ACT_NORMALIZE_URI_QUERY_SORT_BY_NAME;
	}
	else if (strcmp(args[cur_arg], "percent-to-uppercase") == 0) {
		cur_arg++;

		if (strcmp(args[cur_arg], "strict") == 0) {
			cur_arg++;
			rule->action = ACT_NORMALIZE_URI_PERCENT_TO_UPPERCASE_STRICT;
		}
		else if (!*args[cur_arg]) {
			rule->action = ACT_NORMALIZE_URI_PERCENT_TO_UPPERCASE;
		}
		else if (strcmp(args[cur_arg], "if") != 0 && strcmp(args[cur_arg], "unless") != 0) {
			memprintf(err, "unknown argument '%s' for 'percent-to-uppercase' normalizer", args[cur_arg]);
			return ACT_RET_PRS_ERR;
		}
	}
	else if (strcmp(args[cur_arg], "percent-decode-unreserved") == 0) {
		cur_arg++;

		if (strcmp(args[cur_arg], "strict") == 0) {
			cur_arg++;
			rule->action = ACT_NORMALIZE_URI_PERCENT_DECODE_UNRESERVED_STRICT;
		}
		else if (!*args[cur_arg]) {
			rule->action = ACT_NORMALIZE_URI_PERCENT_DECODE_UNRESERVED;
		}
		else if (strcmp(args[cur_arg], "if") != 0 && strcmp(args[cur_arg], "unless") != 0) {
			memprintf(err, "unknown argument '%s' for 'percent-decode-unreserved' normalizer", args[cur_arg]);
			return ACT_RET_PRS_ERR;
		}
	}
	else if (strcmp(args[cur_arg], "fragment-strip") == 0) {
		cur_arg++;

		rule->action = ACT_NORMALIZE_URI_FRAGMENT_STRIP;
	}
	else if (strcmp(args[cur_arg], "fragment-encode") == 0) {
		cur_arg++;

		rule->action = ACT_NORMALIZE_URI_FRAGMENT_ENCODE;
	}
	else {
		memprintf(err, "unknown normalizer '%s'", args[cur_arg]);
		return ACT_RET_PRS_ERR;
	}

	*orig_arg = cur_arg;
	return ACT_RET_PRS_OK;
}

/* This function executes a replace-uri action. It finds its arguments in
 * <rule>.arg.http. It builds a string in the trash from the format string
 * previously filled by function parse_replace_uri() and will execute the regex
 * in <http.re> to replace the URI. It uses the format string present in
 * <http.fmt>. The component to act on (path/uri) is taken from <.action> which
 * contains 1 for the path or 3 for the URI (values used by
 * http_req_replace_stline()). On success, it returns ACT_RET_CONT. If an error
 * occurs while soft rewrites are enabled, the action is canceled, but the rule
 * processing continue. Otherwsize ACT_RET_ERR is returned.
 */
static enum act_return http_action_replace_uri(struct act_rule *rule, struct proxy *px,
                                               struct session *sess, struct stream *s, int flags)
{
	enum act_return ret = ACT_RET_CONT;
	struct buffer *replace, *output;
	struct ist uri;
	int len;

	replace = alloc_trash_chunk();
	output  = alloc_trash_chunk();
	if (!replace || !output)
		goto fail_alloc;
	uri = htx_sl_req_uri(http_get_stline(htxbuf(&s->req.buf)));

	if (rule->action == 1) { // replace-path
		struct http_uri_parser parser = http_uri_parser_init(uri);
		uri = iststop(http_parse_path(&parser), '?');
	}
	else if (rule->action == 4) { // replace-pathq
		struct http_uri_parser parser = http_uri_parser_init(uri);
		uri = http_parse_path(&parser);
	}

	if (!istlen(uri))
		goto leave;

	if (!regex_exec_match2(rule->arg.http.re, uri.ptr, uri.len, MAX_MATCH, pmatch, 0))
		goto leave;

	replace->data = build_logline(s, replace->area, replace->size, &rule->arg.http.fmt);

	/* note: uri.ptr doesn't need to be zero-terminated because it will
	 * only be used to pick pmatch references.
	 */
	len = exp_replace(output->area, output->size, uri.ptr, replace->area, pmatch);
	if (len == -1)
		goto fail_rewrite;

	if (http_req_replace_stline(rule->action, output->area, len, px, s) == -1)
		goto fail_rewrite;

  leave:
	free_trash_chunk(output);
	free_trash_chunk(replace);
	return ret;

  fail_alloc:
	if (!(s->flags & SF_ERR_MASK))
		s->flags |= SF_ERR_RESOURCE;
	ret = ACT_RET_ERR;
	goto leave;

  fail_rewrite:
	_HA_ATOMIC_INC(&sess->fe->fe_counters.failed_rewrites);
	if (s->flags & SF_BE_ASSIGNED)
		_HA_ATOMIC_INC(&s->be->be_counters.failed_rewrites);
	if (sess->listener && sess->listener->counters)
		_HA_ATOMIC_INC(&sess->listener->counters->failed_rewrites);
	if (objt_server(s->target))
		_HA_ATOMIC_INC(&__objt_server(s->target)->counters.failed_rewrites);

	if (!(s->txn->req.flags & HTTP_MSGF_SOFT_RW)) {
		ret = ACT_RET_ERR;
		if (!(s->flags & SF_ERR_MASK))
			s->flags |= SF_ERR_PRXCOND;
	}
	goto leave;
}

/* parse a "replace-uri", "replace-path" or "replace-pathq"
 * http-request action.
 * This action takes 2 arguments (a regex and a replacement format string).
 * The resulting rule makes use of <.action> to store the action (1/3 for now),
 * <http.re> to store the compiled regex, and <http.fmt> to store the log-format
 * list head. It returns ACT_RET_PRS_OK on success, ACT_RET_PRS_ERR on error.
 */
static enum act_parse_ret parse_replace_uri(const char **args, int *orig_arg, struct proxy *px,
                                            struct act_rule *rule, char **err)
{
	int cur_arg = *orig_arg;
	int cap = 0;
	char *error = NULL;

	switch (args[0][8]) {
	case 'p':
		if (args[0][12] == 'q')
			rule->action = 4; // replace-pathq, same as set-pathq
		else
			rule->action = 1; // replace-path, same as set-path
		break;
	case 'u':
		rule->action = 3; // replace-uri, same as set-uri
		break;
	default:
		memprintf(err, "internal error: unhandled action '%s'", args[0]);
		return ACT_RET_PRS_ERR;
	}

	rule->action_ptr = http_action_replace_uri;
	rule->release_ptr = release_http_action;
	LIST_INIT(&rule->arg.http.fmt);

	if (!*args[cur_arg] || !*args[cur_arg+1] ||
	    (*args[cur_arg+2] && strcmp(args[cur_arg+2], "if") != 0 && strcmp(args[cur_arg+2], "unless") != 0)) {
		memprintf(err, "expects exactly 2 arguments <match-regex> and <replace-format>");
		return ACT_RET_PRS_ERR;
	}

	if (!(rule->arg.http.re = regex_comp(args[cur_arg], 1, 1, &error))) {
		memprintf(err, "failed to parse the regex : %s", error);
		free(error);
		return ACT_RET_PRS_ERR;
	}

	px->conf.args.ctx = ARGC_HRQ;
	if (px->cap & PR_CAP_FE)
		cap |= SMP_VAL_FE_HRQ_HDR;
	if (px->cap & PR_CAP_BE)
		cap |= SMP_VAL_BE_HRQ_HDR;
	if (!parse_logformat_string(args[cur_arg + 1], px, &rule->arg.http.fmt, LOG_OPT_HTTP, cap, err)) {
		regex_free(rule->arg.http.re);
		return ACT_RET_PRS_ERR;
	}

	(*orig_arg) += 2;
	return ACT_RET_PRS_OK;
}

/* This function is just a compliant action wrapper for "set-status". */
static enum act_return action_http_set_status(struct act_rule *rule, struct proxy *px,
                                              struct session *sess, struct stream *s, int flags)
{
	if (http_res_set_status(rule->arg.http.i, rule->arg.http.str, s) == -1) {
		_HA_ATOMIC_INC(&sess->fe->fe_counters.failed_rewrites);
		if (s->flags & SF_BE_ASSIGNED)
			_HA_ATOMIC_INC(&s->be->be_counters.failed_rewrites);
		if (sess->listener && sess->listener->counters)
			_HA_ATOMIC_INC(&sess->listener->counters->failed_rewrites);
		if (objt_server(s->target))
			_HA_ATOMIC_INC(&__objt_server(s->target)->counters.failed_rewrites);

		if (!(s->txn->req.flags & HTTP_MSGF_SOFT_RW)) {
			if (!(s->flags & SF_ERR_MASK))
				s->flags |= SF_ERR_PRXCOND;
			return ACT_RET_ERR;
		}
	}

	return ACT_RET_CONT;
}

/* parse set-status action:
 * This action accepts a single argument of type int representing
 * an http status code. It returns ACT_RET_PRS_OK on success,
 * ACT_RET_PRS_ERR on error.
 */
static enum act_parse_ret parse_http_set_status(const char **args, int *orig_arg, struct proxy *px,
                                                struct act_rule *rule, char **err)
{
	char *error;

	rule->action = ACT_CUSTOM;
	rule->action_ptr = action_http_set_status;
	rule->release_ptr = release_http_action;
	LIST_INIT(&rule->arg.http.fmt);

	/* Check if an argument is available */
	if (!*args[*orig_arg]) {
		memprintf(err, "expects 1 argument: <status>; or 3 arguments: <status> reason <fmt>");
		return ACT_RET_PRS_ERR;
	}

	/* convert status code as integer */
	rule->arg.http.i = strtol(args[*orig_arg], &error, 10);
	if (*error != '\0' || rule->arg.http.i < 100 || rule->arg.http.i > 999) {
		memprintf(err, "expects an integer status code between 100 and 999");
		return ACT_RET_PRS_ERR;
	}

	(*orig_arg)++;

	/* set custom reason string */
	rule->arg.http.str = ist(NULL); // If null, we use the default reason for the status code.
	if (*args[*orig_arg] && strcmp(args[*orig_arg], "reason") == 0 &&
	    (*args[*orig_arg + 1] && strcmp(args[*orig_arg + 1], "if") != 0 && strcmp(args[*orig_arg + 1], "unless") != 0)) {
		(*orig_arg)++;
		rule->arg.http.str = ist(strdup(args[*orig_arg]));
		(*orig_arg)++;
	}

	return ACT_RET_PRS_OK;
}

/* This function executes the "reject" HTTP action. It clears the request and
 * response buffer without sending any response. It can be useful as an HTTP
 * alternative to the silent-drop action to defend against DoS attacks, and may
 * also be used with HTTP/2 to close a connection instead of just a stream.
 * The txn status is unchanged, indicating no response was sent. The termination
 * flags will indicate "PR". It always returns ACT_RET_ABRT.
 */
static enum act_return http_action_reject(struct act_rule *rule, struct proxy *px,
                                          struct session *sess, struct stream *s, int flags)
{
	sc_must_kill_conn(s->scf);
	stream_abort(s);
	s->req.analysers &= AN_REQ_FLT_END;
	s->res.analysers &= AN_RES_FLT_END;

	_HA_ATOMIC_INC(&s->be->be_counters.denied_req);
	_HA_ATOMIC_INC(&sess->fe->fe_counters.denied_req);
	if (sess->listener && sess->listener->counters)
		_HA_ATOMIC_INC(&sess->listener->counters->denied_req);

	if (!(s->flags & SF_ERR_MASK))
		s->flags |= SF_ERR_PRXCOND;
	if (!(s->flags & SF_FINST_MASK))
		s->flags |= SF_FINST_R;

	return ACT_RET_ABRT;
}

/* parse the "reject" action:
 * This action takes no argument and returns ACT_RET_PRS_OK on success,
 * ACT_RET_PRS_ERR on error.
 */
static enum act_parse_ret parse_http_action_reject(const char **args, int *orig_arg, struct proxy *px,
                                                   struct act_rule *rule, char **err)
{
	rule->action = ACT_CUSTOM;
	rule->action_ptr = http_action_reject;
	return ACT_RET_PRS_OK;
}

/* This function executes the "disable-l7-retry" HTTP action.
 * It disables L7 retries (all retry except for a connection failure). This
 * can be useful for example to avoid retrying on POST requests.
 * It just removes the L7 retry flag on the HTTP transaction, and always
 * return ACT_RET_CONT;
 */
static enum act_return http_req_disable_l7_retry(struct act_rule *rule, struct proxy *px,
                                          struct session *sess, struct stream *s, int flags)
{
	/* In theory, the TX_L7_RETRY flags isn't set at this point, but
	 * let's be future-proof and remove it anyway.
	 */
	s->txn->flags &= ~TX_L7_RETRY;
	s->txn->flags |= TX_D_L7_RETRY;
	return ACT_RET_CONT;
}

/* parse the "disable-l7-retry" action:
 * This action takes no argument and returns ACT_RET_PRS_OK on success,
 * ACT_RET_PRS_ERR on error.
 */
static enum act_parse_ret parse_http_req_disable_l7_retry(const char **args,
							  int *orig_args, struct proxy *px,
							  struct act_rule *rule, char **err)
{
	rule->action = ACT_CUSTOM;
	rule->action_ptr = http_req_disable_l7_retry;
	return ACT_RET_PRS_OK;
}

/* This function executes the "capture" action. It executes a fetch expression,
 * turns the result into a string and puts it in a capture slot. It always
 * returns 1. If an error occurs the action is cancelled, but the rule
 * processing continues.
 */
static enum act_return http_action_req_capture(struct act_rule *rule, struct proxy *px,
                                               struct session *sess, struct stream *s, int flags)
{
	struct sample *key;
	struct cap_hdr *h = rule->arg.cap.hdr;
	char **cap = s->req_cap;
	int len;

	key = sample_fetch_as_type(s->be, sess, s, SMP_OPT_DIR_REQ|SMP_OPT_FINAL, rule->arg.cap.expr, SMP_T_STR);
	if (!key)
		return ACT_RET_CONT;

	if (cap[h->index] == NULL)
		cap[h->index] = pool_alloc(h->pool);

	if (cap[h->index] == NULL) /* no more capture memory */
		return ACT_RET_CONT;

	len = key->data.u.str.data;
	if (len > h->len)
		len = h->len;

	memcpy(cap[h->index], key->data.u.str.area, len);
	cap[h->index][len] = 0;
	return ACT_RET_CONT;
}

/* This function executes the "capture" action and store the result in a
 * capture slot if exists. It executes a fetch expression, turns the result
 * into a string and puts it in a capture slot. It always returns 1. If an
 * error occurs the action is cancelled, but the rule processing continues.
 */
static enum act_return http_action_req_capture_by_id(struct act_rule *rule, struct proxy *px,
                                                     struct session *sess, struct stream *s, int flags)
{
	struct sample *key;
	struct cap_hdr *h;
	char **cap = s->req_cap;
	struct proxy *fe = strm_fe(s);
	int len;
	int i;

	/* Look for the original configuration. */
	for (h = fe->req_cap, i = fe->nb_req_cap - 1;
	     h != NULL && i != rule->arg.capid.idx ;
	     i--, h = h->next);
	if (!h)
		return ACT_RET_CONT;

	key = sample_fetch_as_type(s->be, sess, s, SMP_OPT_DIR_REQ|SMP_OPT_FINAL, rule->arg.capid.expr, SMP_T_STR);
	if (!key)
		return ACT_RET_CONT;

	if (cap[h->index] == NULL)
		cap[h->index] = pool_alloc(h->pool);

	if (cap[h->index] == NULL) /* no more capture memory */
		return ACT_RET_CONT;

	len = key->data.u.str.data;
	if (len > h->len)
		len = h->len;

	memcpy(cap[h->index], key->data.u.str.area, len);
	cap[h->index][len] = 0;
	return ACT_RET_CONT;
}

/* Check an "http-request capture" action.
 *
 * The function returns 1 in success case, otherwise, it returns 0 and err is
 * filled.
 */
static int check_http_req_capture(struct act_rule *rule, struct proxy *px, char **err)
{
	if (rule->action_ptr != http_action_req_capture_by_id)
		return 1;

	/* capture slots can only be declared in frontends, so we can't check their
	 * existence in backends at configuration parsing step
	 */
	if (px->cap & PR_CAP_FE && rule->arg.capid.idx >= px->nb_req_cap) {
		memprintf(err, "unable to find capture id '%d' referenced by http-request capture rule",
			  rule->arg.capid.idx);
		return 0;
	}

	return 1;
}

/* Release memory allocate by an http capture action */
static void release_http_capture(struct act_rule *rule)
{
	if (rule->action_ptr == http_action_req_capture)
		release_sample_expr(rule->arg.cap.expr);
	else
		release_sample_expr(rule->arg.capid.expr);
}

/* parse an "http-request capture" action. It takes a single argument which is
 * a sample fetch expression. It stores the expression into arg->act.p[0] and
 * the allocated hdr_cap struct or the preallocated "id" into arg->act.p[1].
 * It returns ACT_RET_PRS_OK on success, ACT_RET_PRS_ERR on error.
 */
static enum act_parse_ret parse_http_req_capture(const char **args, int *orig_arg, struct proxy *px,
                                                 struct act_rule *rule, char **err)
{
	struct sample_expr *expr;
	struct cap_hdr *hdr;
	int cur_arg;
	int len = 0;

	for (cur_arg = *orig_arg; cur_arg < *orig_arg + 3 && *args[cur_arg]; cur_arg++)
		if (strcmp(args[cur_arg], "if") == 0 ||
		    strcmp(args[cur_arg], "unless") == 0)
			break;

	if (cur_arg < *orig_arg + 3) {
		memprintf(err, "expects <expression> [ 'len' <length> | id <idx> ]");
		return ACT_RET_PRS_ERR;
	}

	cur_arg = *orig_arg;
	expr = sample_parse_expr((char **)args, &cur_arg, px->conf.args.file, px->conf.args.line, err, &px->conf.args, NULL);
	if (!expr)
		return ACT_RET_PRS_ERR;

	if (!(expr->fetch->val & SMP_VAL_FE_HRQ_HDR)) {
		memprintf(err,
			  "fetch method '%s' extracts information from '%s', none of which is available here",
			  args[cur_arg-1], sample_src_names(expr->fetch->use));
		release_sample_expr(expr);
		return ACT_RET_PRS_ERR;
	}

	if (!args[cur_arg] || !*args[cur_arg]) {
		memprintf(err, "expects 'len or 'id'");
		release_sample_expr(expr);
		return ACT_RET_PRS_ERR;
	}

	if (strcmp(args[cur_arg], "len") == 0) {
		cur_arg++;

		if (!(px->cap & PR_CAP_FE)) {
			memprintf(err, "proxy '%s' has no frontend capability", px->id);
			release_sample_expr(expr);
			return ACT_RET_PRS_ERR;
		}

		px->conf.args.ctx = ARGC_CAP;

		if (!args[cur_arg]) {
			memprintf(err, "missing length value");
			release_sample_expr(expr);
			return ACT_RET_PRS_ERR;
		}
		/* we copy the table name for now, it will be resolved later */
		len = atoi(args[cur_arg]);
		if (len <= 0) {
			memprintf(err, "length must be > 0");
			release_sample_expr(expr);
			return ACT_RET_PRS_ERR;
		}
		cur_arg++;

		hdr = calloc(1, sizeof(*hdr));
		if (!hdr) {
			memprintf(err, "out of memory");
			release_sample_expr(expr);
			return ACT_RET_PRS_ERR;
		}
		hdr->next = px->req_cap;
		hdr->name = NULL; /* not a header capture */
		hdr->namelen = 0;
		hdr->len = len;
		hdr->pool = create_pool("caphdr", hdr->len + 1, MEM_F_SHARED);
		hdr->index = px->nb_req_cap++;

		px->req_cap = hdr;
		px->to_log |= LW_REQHDR;

		rule->action       = ACT_CUSTOM;
		rule->action_ptr   = http_action_req_capture;
		rule->release_ptr  = release_http_capture;
		rule->arg.cap.expr = expr;
		rule->arg.cap.hdr  = hdr;
	}

	else if (strcmp(args[cur_arg], "id") == 0) {
		int id;
		char *error;

		cur_arg++;

		if (!args[cur_arg]) {
			memprintf(err, "missing id value");
			release_sample_expr(expr);
			return ACT_RET_PRS_ERR;
		}

		id = strtol(args[cur_arg], &error, 10);
		if (*error != '\0') {
			memprintf(err, "cannot parse id '%s'", args[cur_arg]);
			release_sample_expr(expr);
			return ACT_RET_PRS_ERR;
		}
		cur_arg++;

		px->conf.args.ctx = ARGC_CAP;

		rule->action       = ACT_CUSTOM;
		rule->action_ptr   = http_action_req_capture_by_id;
		rule->check_ptr    = check_http_req_capture;
		rule->release_ptr  = release_http_capture;
		rule->arg.capid.expr = expr;
		rule->arg.capid.idx  = id;
	}

	else {
		memprintf(err, "expects 'len' or 'id', found '%s'", args[cur_arg]);
		release_sample_expr(expr);
		return ACT_RET_PRS_ERR;
	}

	*orig_arg = cur_arg;
	return ACT_RET_PRS_OK;
}

/* This function executes the "capture" action and store the result in a
 * capture slot if exists. It executes a fetch expression, turns the result
 * into a string and puts it in a capture slot. It always returns 1. If an
 * error occurs the action is cancelled, but the rule processing continues.
 */
static enum act_return http_action_res_capture_by_id(struct act_rule *rule, struct proxy *px,
                                                     struct session *sess, struct stream *s, int flags)
{
	struct sample *key;
	struct cap_hdr *h;
	char **cap = s->res_cap;
	struct proxy *fe = strm_fe(s);
	int len;
	int i;

	/* Look for the original configuration. */
	for (h = fe->rsp_cap, i = fe->nb_rsp_cap - 1;
	     h != NULL && i != rule->arg.capid.idx ;
	     i--, h = h->next);
	if (!h)
		return ACT_RET_CONT;

	key = sample_fetch_as_type(s->be, sess, s, SMP_OPT_DIR_RES|SMP_OPT_FINAL, rule->arg.capid.expr, SMP_T_STR);
	if (!key)
		return ACT_RET_CONT;

	if (cap[h->index] == NULL)
		cap[h->index] = pool_alloc(h->pool);

	if (cap[h->index] == NULL) /* no more capture memory */
		return ACT_RET_CONT;

	len = key->data.u.str.data;
	if (len > h->len)
		len = h->len;

	memcpy(cap[h->index], key->data.u.str.area, len);
	cap[h->index][len] = 0;
	return ACT_RET_CONT;
}

/* Check an "http-response capture" action.
 *
 * The function returns 1 in success case, otherwise, it returns 0 and err is
 * filled.
 */
static int check_http_res_capture(struct act_rule *rule, struct proxy *px, char **err)
{
	if (rule->action_ptr != http_action_res_capture_by_id)
		return 1;

	/* capture slots can only be declared in frontends, so we can't check their
	 * existence in backends at configuration parsing step
	 */
	if (px->cap & PR_CAP_FE && rule->arg.capid.idx >= px->nb_rsp_cap) {
		memprintf(err, "unable to find capture id '%d' referenced by http-response capture rule",
			  rule->arg.capid.idx);
		return 0;
	}

	return 1;
}

/* parse an "http-response capture" action. It takes a single argument which is
 * a sample fetch expression. It stores the expression into arg->act.p[0] and
 * the allocated hdr_cap struct of the preallocated id into arg->act.p[1].
 * It returns ACT_RET_PRS_OK on success, ACT_RET_PRS_ERR on error.
 */
static enum act_parse_ret parse_http_res_capture(const char **args, int *orig_arg, struct proxy *px,
                                                 struct act_rule *rule, char **err)
{
	struct sample_expr *expr;
	int cur_arg;
	int id;
	char *error;

	for (cur_arg = *orig_arg; cur_arg < *orig_arg + 3 && *args[cur_arg]; cur_arg++)
		if (strcmp(args[cur_arg], "if") == 0 ||
		    strcmp(args[cur_arg], "unless") == 0)
			break;

	if (cur_arg < *orig_arg + 3) {
		memprintf(err, "expects <expression> id <idx>");
		return ACT_RET_PRS_ERR;
	}

	cur_arg = *orig_arg;
	expr = sample_parse_expr((char **)args, &cur_arg, px->conf.args.file, px->conf.args.line, err, &px->conf.args, NULL);
	if (!expr)
		return ACT_RET_PRS_ERR;

	if (!(expr->fetch->val & SMP_VAL_FE_HRS_HDR)) {
		memprintf(err,
			  "fetch method '%s' extracts information from '%s', none of which is available here",
			  args[cur_arg-1], sample_src_names(expr->fetch->use));
		release_sample_expr(expr);
		return ACT_RET_PRS_ERR;
	}

	if (!args[cur_arg] || !*args[cur_arg]) {
		memprintf(err, "expects 'id'");
		release_sample_expr(expr);
		return ACT_RET_PRS_ERR;
	}

	if (strcmp(args[cur_arg], "id") != 0) {
		memprintf(err, "expects 'id', found '%s'", args[cur_arg]);
		release_sample_expr(expr);
		return ACT_RET_PRS_ERR;
	}

	cur_arg++;

	if (!args[cur_arg]) {
		memprintf(err, "missing id value");
		release_sample_expr(expr);
		return ACT_RET_PRS_ERR;
	}

	id = strtol(args[cur_arg], &error, 10);
	if (*error != '\0') {
		memprintf(err, "cannot parse id '%s'", args[cur_arg]);
		release_sample_expr(expr);
		return ACT_RET_PRS_ERR;
	}
	cur_arg++;

	px->conf.args.ctx = ARGC_CAP;

	rule->action       = ACT_CUSTOM;
	rule->action_ptr   = http_action_res_capture_by_id;
	rule->check_ptr    = check_http_res_capture;
	rule->release_ptr  = release_http_capture;
	rule->arg.capid.expr = expr;
	rule->arg.capid.idx  = id;

	*orig_arg = cur_arg;
	return ACT_RET_PRS_OK;
}

/* Parse a "allow" action for a request or a response rule. It takes no argument. It
 * returns ACT_RET_PRS_OK on success, ACT_RET_PRS_ERR on error.
 */
static enum act_parse_ret parse_http_allow(const char **args, int *orig_arg, struct proxy *px,
					   struct act_rule *rule, char **err)
{
	rule->action = ACT_ACTION_ALLOW;
	rule->flags |= ACT_FLAG_FINAL;
	return ACT_RET_PRS_OK;
}

/* Parse "deny" or "tarpit" actions for a request rule or "deny" action for a
 * response rule. It returns ACT_RET_PRS_OK on success, ACT_RET_PRS_ERR on
 * error. It relies on http_parse_http_reply() to set
 * <.arg.http_reply>.
 */
static enum act_parse_ret parse_http_deny(const char **args, int *orig_arg, struct proxy *px,
					  struct act_rule *rule, char **err)
{
	int default_status;
	int cur_arg, arg = 0;

	cur_arg = *orig_arg;
	if (rule->from == ACT_F_HTTP_REQ) {
		if (strcmp(args[cur_arg - 1], "tarpit") == 0) {
			rule->action = ACT_HTTP_REQ_TARPIT;
			default_status = 500;
		}
		else {
			rule->action = ACT_ACTION_DENY;
			default_status = 403;
		}
	}
	else {
		rule->action = ACT_ACTION_DENY;
		default_status = 502;
	}

	/* If no args or only a deny_status specified, fallback on the legacy
	 * mode and use default error files despite the fact that
	 * default-errorfiles is not used. Otherwise, parse an http reply.
	 */

	/* Prepare parsing of log-format strings */
	px->conf.args.ctx = ((rule->from == ACT_F_HTTP_REQ) ? ARGC_HRQ : ARGC_HRS);

	if (!*(args[cur_arg]) || strcmp(args[cur_arg], "if") == 0 || strcmp(args[cur_arg], "unless") == 0) {
		rule->arg.http_reply = http_parse_http_reply((const char *[]){"default-errorfiles", ""}, &arg, px, default_status, err);
		goto end;
	}

	if (strcmp(args[cur_arg], "deny_status") == 0) {
		if (!*(args[cur_arg+2]) || strcmp(args[cur_arg+2], "if") == 0 || strcmp(args[cur_arg+2], "unless") == 0) {
			rule->arg.http_reply = http_parse_http_reply((const char *[]){"status", args[cur_arg+1], "default-errorfiles", ""},
								     &arg, px, default_status, err);
			*orig_arg += 2;
			goto end;
		}
		args[cur_arg] += 5; /* skip "deny_" for the parsing */
	}

	rule->arg.http_reply = http_parse_http_reply(args, orig_arg, px, default_status, err);

  end:
	if (!rule->arg.http_reply)
		return ACT_RET_PRS_ERR;

	rule->flags |= ACT_FLAG_FINAL;
	rule->check_ptr = check_act_http_reply;
	rule->release_ptr = release_act_http_reply;
	return ACT_RET_PRS_OK;
}


/* This function executes a auth action. It builds an 401/407 HTX message using
 * the corresponding proxy's error message. On success, it returns
 * ACT_RET_ABRT. If an error occurs ACT_RET_ERR is returned.
 */
static enum act_return http_action_auth(struct act_rule *rule, struct proxy *px,
					struct session *sess, struct stream *s, int flags)
{
	struct channel *req = &s->req;
	struct channel *res = &s->res;
	struct htx *htx = htx_from_buf(&res->buf);
	struct http_reply *reply;
	const char *auth_realm;
	struct http_hdr_ctx ctx;
	struct ist hdr;

	/* Auth might be performed on regular http-req rules as well as on stats */
	auth_realm = rule->arg.http.str.ptr;
	if (!auth_realm) {
		if (px->uri_auth && s->current_rule_list == &px->uri_auth->http_req_rules)
			auth_realm = STATS_DEFAULT_REALM;
		else
			auth_realm = px->id;
	}

	if (!(s->txn->flags & TX_USE_PX_CONN)) {
		s->txn->status = 401;
		hdr = ist("WWW-Authenticate");
	}
	else {
		s->txn->status = 407;
		hdr = ist("Proxy-Authenticate");
	}
	reply = http_error_message(s);
	channel_htx_truncate(res, htx);

	if (chunk_printf(&trash, "Basic realm=\"%s\"", auth_realm) == -1)
		goto fail;

	/* Write the generic 40x message */
	if (http_reply_to_htx(s, htx, reply) == -1)
		goto fail;

	/* Remove all existing occurrences of the XXX-Authenticate header */
	ctx.blk = NULL;
	while (http_find_header(htx, hdr, &ctx, 1))
		http_remove_header(htx, &ctx);

	/* Now a the right XXX-Authenticate header */
	if (!http_add_header(htx, hdr, ist2(b_orig(&trash), b_data(&trash))))
		goto fail;

	/* Finally forward the reply */
	htx_to_buf(htx, &res->buf);
	if (!http_forward_proxy_resp(s, 1))
		goto fail;

	/* Note: Only eval on the request */
	s->logs.request_ts = now_ns;
	req->analysers &= AN_REQ_FLT_END;

	if (s->sess->fe == s->be) /* report it if the request was intercepted by the frontend */
		_HA_ATOMIC_INC(&s->sess->fe->fe_counters.intercepted_req);

	if (!(s->flags & SF_ERR_MASK))
		s->flags |= SF_ERR_LOCAL;
	if (!(s->flags & SF_FINST_MASK))
		s->flags |= SF_FINST_R;

	stream_inc_http_err_ctr(s);
	return ACT_RET_ABRT;

  fail:
	/* If an error occurred, remove the incomplete HTTP response from the
	 * buffer */
	channel_htx_truncate(res, htx);
	return ACT_RET_ERR;
}

/* Parse a "auth" action. It may take 2 optional arguments to define a "realm"
 * parameter. It returns ACT_RET_PRS_OK on success, ACT_RET_PRS_ERR on error.
 */
static enum act_parse_ret parse_http_auth(const char **args, int *orig_arg, struct proxy *px,
					  struct act_rule *rule, char **err)
{
	int cur_arg;

	rule->action = ACT_CUSTOM;
	rule->flags |= ACT_FLAG_FINAL;
	rule->action_ptr = http_action_auth;
	rule->release_ptr = release_http_action;
	LIST_INIT(&rule->arg.http.fmt);

	cur_arg = *orig_arg;
	if (strcmp(args[cur_arg], "realm") == 0) {
		cur_arg++;
		if (!*args[cur_arg]) {
			memprintf(err, "missing realm value.\n");
			return ACT_RET_PRS_ERR;
		}
		rule->arg.http.str = ist(strdup(args[cur_arg]));
		cur_arg++;
	}

	*orig_arg = cur_arg;
	return ACT_RET_PRS_OK;
}

/* This function executes a early-hint action. It adds an HTTP Early Hint HTTP
 * 103 response header with <.arg.http.str> name and with a value built
 * according to <.arg.http.fmt> log line format. If it is the first early-hint
 * rule of series, the 103 response start-line is added first. At the end, if
 * the next rule is not an early-hint rule or if it is the last rule, the EOH
 * block is added to terminate the response. On success, it returns
 * ACT_RET_CONT. If an error occurs while soft rewrites are enabled, the action
 * is canceled, but the rule processing continue. Otherwsize ACT_RET_ERR is
 * returned.
 */
static enum act_return http_action_early_hint(struct act_rule *rule, struct proxy *px,
					      struct session *sess, struct stream *s, int flags)
{
	struct act_rule *next_rule;
	struct channel *res = &s->res;
	struct htx *htx = htx_from_buf(&res->buf);
	struct buffer *value = alloc_trash_chunk();
	enum act_return ret = ACT_RET_CONT;

	if (!(s->txn->req.flags & HTTP_MSGF_VER_11))
		goto leave;

	if (!value) {
		if (!(s->flags & SF_ERR_MASK))
			s->flags |= SF_ERR_RESOURCE;
		goto error;
	}

	/* if there is no pending 103 response, start a new response. Otherwise,
	 * continue to add link to a previously started response
         */
	if (s->txn->status != 103) {
		struct htx_sl *sl;
		unsigned int flags = (HTX_SL_F_IS_RESP|HTX_SL_F_VER_11|
				      HTX_SL_F_XFER_LEN|HTX_SL_F_BODYLESS);

		sl = htx_add_stline(htx, HTX_BLK_RES_SL, flags,
				    ist("HTTP/1.1"), ist("103"), ist("Early Hints"));
		if (!sl)
			goto error;
		sl->info.res.status = 103;
		s->txn->status = 103;
	}

	/* Add the HTTP Early Hint HTTP 103 response header */
	value->data = build_logline(s, b_tail(value), b_room(value), &rule->arg.http.fmt);
	if (!htx_add_header(htx, rule->arg.http.str, ist2(b_head(value), b_data(value))))
		goto error;

	/* if it is the last rule or the next one is not an early-hint or an
	 * conditional early-hint, terminate the current response.
	 */
	next_rule = LIST_NEXT(&rule->list, typeof(rule), list);
	if (&next_rule->list == s->current_rule_list || next_rule->action_ptr != http_action_early_hint || next_rule->cond) {
		if (!htx_add_endof(htx, HTX_BLK_EOH))
			goto error;
		if (!http_forward_proxy_resp(s, 0))
			goto error;
		s->txn->status = 0;
	}

  leave:
	free_trash_chunk(value);
	return ret;

  error:
	/* If an error occurred during an Early-hint rule, remove the incomplete
	 * HTTP 103 response from the buffer */
	channel_htx_truncate(res, htx);
	ret = ACT_RET_ERR;
	s->txn->status = 0;
	goto leave;
}

/* This function executes a set-header or add-header actions. It builds a string
 * in the trash from the specified format string. It finds the action to be
 * performed in <.action>, previously filled by function parse_set_header(). The
 * replacement action is executed by the function http_action_set_header(). On
 * success, it returns ACT_RET_CONT. If an error occurs while soft rewrites are
 * enabled, the action is canceled, but the rule processing continue. Otherwsize
 * ACT_RET_ERR is returned.
 */
static enum act_return http_action_set_header(struct act_rule *rule, struct proxy *px,
					      struct session *sess, struct stream *s, int flags)
{
	struct http_msg *msg = ((rule->from == ACT_F_HTTP_REQ) ? &s->txn->req : &s->txn->rsp);
	struct htx *htx = htxbuf(&msg->chn->buf);
	enum act_return ret = ACT_RET_CONT;
	struct buffer *replace;
	struct http_hdr_ctx ctx;
	struct ist n, v;

	replace = alloc_trash_chunk();
	if (!replace)
		goto fail_alloc;

	replace->data = build_logline(s, replace->area, replace->size, &rule->arg.http.fmt);
	n = rule->arg.http.str;
	v = ist2(replace->area, replace->data);

	if (rule->action == 0) { // set-header
		/* remove all occurrences of the header */
		ctx.blk = NULL;
		while (http_find_header(htx, n, &ctx, 1))
			http_remove_header(htx, &ctx);
	}

	/* Now add header */
	if (!http_add_header(htx, n, v))
		goto fail_rewrite;

  leave:
	free_trash_chunk(replace);
	return ret;

  fail_alloc:
	if (!(s->flags & SF_ERR_MASK))
		s->flags |= SF_ERR_RESOURCE;
	ret = ACT_RET_ERR;
	goto leave;

  fail_rewrite:
	_HA_ATOMIC_INC(&sess->fe->fe_counters.failed_rewrites);
	if (s->flags & SF_BE_ASSIGNED)
		_HA_ATOMIC_INC(&s->be->be_counters.failed_rewrites);
	if (sess->listener && sess->listener->counters)
		_HA_ATOMIC_INC(&sess->listener->counters->failed_rewrites);
	if (objt_server(s->target))
		_HA_ATOMIC_INC(&__objt_server(s->target)->counters.failed_rewrites);

	if (!(msg->flags & HTTP_MSGF_SOFT_RW)) {
		ret = ACT_RET_ERR;
		if (!(s->flags & SF_ERR_MASK))
			s->flags |= SF_ERR_PRXCOND;
	}
	goto leave;
}

/* Parse a "set-header", "add-header" or "early-hint" actions. It takes an
 * header name and a log-format string as arguments. It returns ACT_RET_PRS_OK
 * on success, ACT_RET_PRS_ERR on error.
 *
 * Note: same function is used for the request and the response. However
 * "early-hint" rules are only supported for request rules.
 */
static enum act_parse_ret parse_http_set_header(const char **args, int *orig_arg, struct proxy *px,
						   struct act_rule *rule, char **err)
{
	int cap = 0, cur_arg;
	const char *p;

	if (args[*orig_arg-1][0] == 'e') {
		rule->action = ACT_CUSTOM;
		rule->action_ptr = http_action_early_hint;
	}
	else {
		if (args[*orig_arg-1][0] == 's')
			rule->action = 0; // set-header
		else
			rule->action = 1; // add-header
		rule->action_ptr = http_action_set_header;
	}
	rule->release_ptr = release_http_action;
	LIST_INIT(&rule->arg.http.fmt);

	cur_arg = *orig_arg;
	if (!*args[cur_arg] || !*args[cur_arg+1]) {
		memprintf(err, "expects exactly 2 arguments");
		return ACT_RET_PRS_ERR;
	}


	rule->arg.http.str = ist(strdup(args[cur_arg]));

	if (rule->from == ACT_F_HTTP_REQ) {
		px->conf.args.ctx = ARGC_HRQ;
		if (px->cap & PR_CAP_FE)
			cap |= SMP_VAL_FE_HRQ_HDR;
		if (px->cap & PR_CAP_BE)
			cap |= SMP_VAL_BE_HRQ_HDR;
	}
	else{
		px->conf.args.ctx =  ARGC_HRS;
		if (px->cap & PR_CAP_FE)
			cap |= SMP_VAL_FE_HRS_HDR;
		if (px->cap & PR_CAP_BE)
			cap |= SMP_VAL_BE_HRS_HDR;
	}

	cur_arg++;
	if (!parse_logformat_string(args[cur_arg], px, &rule->arg.http.fmt, LOG_OPT_HTTP, cap, err)) {
		istfree(&rule->arg.http.str);
		return ACT_RET_PRS_ERR;
	}

	free(px->conf.lfs_file);
	px->conf.lfs_file = strdup(px->conf.args.file);
	px->conf.lfs_line = px->conf.args.line;

	/* some characters are totally forbidden in header names and
	 * may happen by accident when writing configs, causing strange
	 * failures in field. Better catch these ones early, nobody will
	 * miss them. In particular, a colon at the end (or anywhere
	 * after the first char) or a space/cr anywhere due to misplaced
	 * quotes are hard to spot.
	 */
	for (p = istptr(rule->arg.http.str); p < istend(rule->arg.http.str); p++) {
		if (HTTP_IS_TOKEN(*p))
			continue;
		if (p == istptr(rule->arg.http.str) && *p == ':')
			continue;
		/* we only report this as-is but it will not cause an error */
		memprintf(err, "header name '%s' contains forbidden character '%c'", istptr(rule->arg.http.str), *p);
		break;
	}

	*orig_arg = cur_arg + 1;
	return ACT_RET_PRS_OK;
}

/* This function executes a replace-header or replace-value actions. It
 * builds a string in the trash from the specified format string. It finds
 * the action to be performed in <.action>, previously filled by function
 * parse_replace_header(). The replacement action is executed by the function
 * http_action_replace_header(). On success, it returns ACT_RET_CONT. If an error
 * occurs while soft rewrites are enabled, the action is canceled, but the rule
 * processing continue. Otherwsize ACT_RET_ERR is returned.
 */
static enum act_return http_action_replace_header(struct act_rule *rule, struct proxy *px,
						  struct session *sess, struct stream *s, int flags)
{
	struct http_msg *msg = ((rule->from == ACT_F_HTTP_REQ) ? &s->txn->req : &s->txn->rsp);
	struct htx *htx = htxbuf(&msg->chn->buf);
	enum act_return ret = ACT_RET_CONT;
	struct buffer *replace;
	int r;

	replace = alloc_trash_chunk();
	if (!replace)
		goto fail_alloc;

	replace->data = build_logline(s, replace->area, replace->size, &rule->arg.http.fmt);

	r = http_replace_hdrs(s, htx, rule->arg.http.str, replace->area, rule->arg.http.re, (rule->action == 0));
	if (r == -1)
		goto fail_rewrite;

  leave:
	free_trash_chunk(replace);
	return ret;

  fail_alloc:
	if (!(s->flags & SF_ERR_MASK))
		s->flags |= SF_ERR_RESOURCE;
	ret = ACT_RET_ERR;
	goto leave;

  fail_rewrite:
	_HA_ATOMIC_INC(&sess->fe->fe_counters.failed_rewrites);
	if (s->flags & SF_BE_ASSIGNED)
		_HA_ATOMIC_INC(&s->be->be_counters.failed_rewrites);
	if (sess->listener && sess->listener->counters)
		_HA_ATOMIC_INC(&sess->listener->counters->failed_rewrites);
	if (objt_server(s->target))
		_HA_ATOMIC_INC(&__objt_server(s->target)->counters.failed_rewrites);

	if (!(msg->flags & HTTP_MSGF_SOFT_RW)) {
		ret = ACT_RET_ERR;
		if (!(s->flags & SF_ERR_MASK))
			s->flags |= SF_ERR_PRXCOND;
	}
	goto leave;
}

/* Parse a "replace-header" or "replace-value" actions. It takes an header name,
 * a regex and replacement string as arguments. It returns ACT_RET_PRS_OK on
 * success, ACT_RET_PRS_ERR on error.
 */
static enum act_parse_ret parse_http_replace_header(const char **args, int *orig_arg, struct proxy *px,
						    struct act_rule *rule, char **err)
{
	int cap = 0, cur_arg;

	if (args[*orig_arg-1][8] == 'h')
		rule->action = 0; // replace-header
	else
		rule->action = 1; // replace-value
	rule->action_ptr = http_action_replace_header;
	rule->release_ptr = release_http_action;
	LIST_INIT(&rule->arg.http.fmt);

	cur_arg = *orig_arg;
	if (!*args[cur_arg] || !*args[cur_arg+1] || !*args[cur_arg+2]) {
		memprintf(err, "expects exactly 3 arguments");
		return ACT_RET_PRS_ERR;
	}

	rule->arg.http.str = ist(strdup(args[cur_arg]));

	cur_arg++;
	if (!(rule->arg.http.re = regex_comp(args[cur_arg], 1, 1, err))) {
		istfree(&rule->arg.http.str);
		return ACT_RET_PRS_ERR;
	}

	if (rule->from == ACT_F_HTTP_REQ) {
		px->conf.args.ctx = ARGC_HRQ;
		if (px->cap & PR_CAP_FE)
			cap |= SMP_VAL_FE_HRQ_HDR;
		if (px->cap & PR_CAP_BE)
			cap |= SMP_VAL_BE_HRQ_HDR;
	}
	else{
		px->conf.args.ctx =  ARGC_HRS;
		if (px->cap & PR_CAP_FE)
			cap |= SMP_VAL_FE_HRS_HDR;
		if (px->cap & PR_CAP_BE)
			cap |= SMP_VAL_BE_HRS_HDR;
	}

	cur_arg++;
	if (!parse_logformat_string(args[cur_arg], px, &rule->arg.http.fmt, LOG_OPT_HTTP, cap, err)) {
		istfree(&rule->arg.http.str);
		regex_free(rule->arg.http.re);
		return ACT_RET_PRS_ERR;
	}

	free(px->conf.lfs_file);
	px->conf.lfs_file = strdup(px->conf.args.file);
	px->conf.lfs_line = px->conf.args.line;

	*orig_arg = cur_arg + 1;
	return ACT_RET_PRS_OK;
}

/* This function executes a del-header action with selected matching mode for
 * header name. It finds the matching method to be performed in <.action>, previously
 * filled by function parse_http_del_header(). On success, it returns ACT_RET_CONT.
 * Otherwise ACT_RET_ERR is returned.
 */
static enum act_return http_action_del_header(struct act_rule *rule, struct proxy *px,
						  struct session *sess, struct stream *s, int flags)
{
	struct http_hdr_ctx ctx;
	struct http_msg *msg = ((rule->from == ACT_F_HTTP_REQ) ? &s->txn->req : &s->txn->rsp);
	struct htx *htx = htxbuf(&msg->chn->buf);
	enum act_return ret = ACT_RET_CONT;

	/* remove all occurrences of the header */
	ctx.blk = NULL;
	switch (rule->action) {
	case PAT_MATCH_STR:
		while (http_find_header(htx, rule->arg.http.str, &ctx, 1))
			http_remove_header(htx, &ctx);
		break;
	case PAT_MATCH_BEG:
		while (http_find_pfx_header(htx, rule->arg.http.str, &ctx, 1))
			http_remove_header(htx, &ctx);
		break;
	case PAT_MATCH_END:
		while (http_find_sfx_header(htx, rule->arg.http.str, &ctx, 1))
			http_remove_header(htx, &ctx);
		break;
	case PAT_MATCH_SUB:
		while (http_find_sub_header(htx, rule->arg.http.str, &ctx, 1))
			http_remove_header(htx, &ctx);
		break;
	case PAT_MATCH_REG:
		while (http_match_header(htx, rule->arg.http.re, &ctx, 1))
			http_remove_header(htx, &ctx);
		break;
	default:
		return ACT_RET_ERR;
	}
	return ret;
}

/* Parse a "del-header" action. It takes string as a required argument,
 * optional flag (currently only -m) and optional matching method of input string
 * with header name to be deleted. Default matching method is exact match (-m str).
 * It returns ACT_RET_PRS_OK on success, ACT_RET_PRS_ERR on error.
 */
static enum act_parse_ret parse_http_del_header(const char **args, int *orig_arg, struct proxy *px,
						struct act_rule *rule, char **err)
{
	int cur_arg;
	int pat_idx;

	/* set exact matching (-m str) as default */
	rule->action = PAT_MATCH_STR;
	rule->action_ptr = http_action_del_header;
	rule->release_ptr = release_http_action;
	LIST_INIT(&rule->arg.http.fmt);

	cur_arg = *orig_arg;
	if (!*args[cur_arg]) {
		memprintf(err, "expects at least 1 argument");
		return ACT_RET_PRS_ERR;
	}

	rule->arg.http.str = ist(strdup(args[cur_arg]));
	px->conf.args.ctx = (rule->from == ACT_F_HTTP_REQ ? ARGC_HRQ : ARGC_HRS);

	if (strcmp(args[cur_arg+1], "-m") == 0) {
		cur_arg++;
		if (!*args[cur_arg+1]) {
			memprintf(err, "-m flag expects exactly 1 argument");
			return ACT_RET_PRS_ERR;
		}

		cur_arg++;
		pat_idx = pat_find_match_name(args[cur_arg]);
		switch (pat_idx) {
		case PAT_MATCH_REG:
			if (!(rule->arg.http.re = regex_comp(rule->arg.http.str.ptr, 1, 1, err)))
				return ACT_RET_PRS_ERR;
			__fallthrough;
		case PAT_MATCH_STR:
		case PAT_MATCH_BEG:
		case PAT_MATCH_END:
		case PAT_MATCH_SUB:
			rule->action = pat_idx;
			break;
		default:
			memprintf(err, "-m with unsupported matching method '%s'", args[cur_arg]);
			return ACT_RET_PRS_ERR;
		}
	}

	*orig_arg = cur_arg + 1;
	return ACT_RET_PRS_OK;
}

/* Release memory allocated by an http redirect action. */
static void release_http_redir(struct act_rule *rule)
{
	struct logformat_node *lf, *lfb;
	struct redirect_rule *redir;

	redir = rule->arg.redir;
	if (!redir)
		return;

	LIST_DELETE(&redir->list);
	if (redir->cond) {
		prune_acl_cond(redir->cond);
		free(redir->cond);
	}
	free(redir->rdr_str);
	free(redir->cookie_str);
	list_for_each_entry_safe(lf, lfb, &redir->rdr_fmt, list) {
		LIST_DELETE(&lf->list);
		release_sample_expr(lf->expr);
		free(lf->arg);
		free(lf);
	}
	free(redir);
}

/* Parse a "redirect" action. It returns ACT_RET_PRS_OK on success,
 * ACT_RET_PRS_ERR on error.
 */
static enum act_parse_ret parse_http_redirect(const char **args, int *orig_arg, struct proxy *px,
					      struct act_rule *rule, char **err)
{
	struct redirect_rule *redir;
	int dir, cur_arg;

	rule->action = ACT_HTTP_REDIR;
	rule->release_ptr = release_http_redir;

	cur_arg = *orig_arg;

	dir = (rule->from == ACT_F_HTTP_REQ ? 0 : 1);
	if ((redir = http_parse_redirect_rule(px->conf.args.file, px->conf.args.line, px, &args[cur_arg], err, 1, dir)) == NULL)
		return ACT_RET_PRS_ERR;

	if (!(redir->flags & REDIRECT_FLAG_IGNORE_EMPTY))
		rule->flags |= ACT_FLAG_FINAL;

	rule->arg.redir = redir;
	rule->cond = redir->cond;
	redir->cond = NULL;

	/* skip all arguments */
	while (*args[cur_arg])
		cur_arg++;

	*orig_arg = cur_arg;
	return ACT_RET_PRS_OK;
}

/* This function executes a add-acl, del-acl, set-map or del-map actions. On
 * success, it returns ACT_RET_CONT. Otherwsize ACT_RET_ERR is returned.
 */
static enum act_return http_action_set_map(struct act_rule *rule, struct proxy *px,
					   struct session *sess, struct stream *s, int flags)
{
	struct pat_ref *ref;
	struct buffer *key = NULL, *value = NULL;
	enum act_return ret = ACT_RET_CONT;

	/* collect reference */
	ref = pat_ref_lookup(rule->arg.map.ref);
	if (!ref)
		goto leave;

	/* allocate key */
	key = alloc_trash_chunk();
	if (!key)
		goto fail_alloc;

	/* collect key */
	key->data = build_logline(s, key->area, key->size, &rule->arg.map.key);
	key->area[key->data] = '\0';

	switch (rule->action) {
	case 0: // add-acl
		/* add entry only if it does not already exist */
		HA_SPIN_LOCK(PATREF_LOCK, &ref->lock);
		if (pat_ref_find_elt(ref, key->area) == NULL)
			pat_ref_add(ref, key->area, NULL, NULL);
		HA_SPIN_UNLOCK(PATREF_LOCK, &ref->lock);
		break;

	case 1: // set-map
		/* allocate value */
		value = alloc_trash_chunk();
		if (!value)
			goto fail_alloc;

		/* collect value */
		value->data = build_logline(s, value->area, value->size, &rule->arg.map.value);
		value->area[value->data] = '\0';

		HA_SPIN_LOCK(PATREF_LOCK, &ref->lock);
		if (pat_ref_find_elt(ref, key->area) != NULL) {
			/* update entry if it exists */
			pat_ref_set(ref, key->area, value->area, NULL);
		}
		else {
			/* insert a new entry */
			pat_ref_add(ref, key->area, value->area, NULL);
		}
		HA_SPIN_UNLOCK(PATREF_LOCK, &ref->lock);
		break;

	case 2: // del-acl
	case 3: // del-map
		/* returned code: 1=ok, 0=ko */
		HA_SPIN_LOCK(PATREF_LOCK, &ref->lock);
		pat_ref_delete(ref, key->area);
		HA_SPIN_UNLOCK(PATREF_LOCK, &ref->lock);
		break;

	default:
		ret = ACT_RET_ERR;
	}


  leave:
	free_trash_chunk(key);
	free_trash_chunk(value);
	return ret;

  fail_alloc:
	if (!(s->flags & SF_ERR_MASK))
		s->flags |= SF_ERR_RESOURCE;
	ret = ACT_RET_ERR;
	goto leave;
}

/* Release memory allocated by an http map/acl action. */
static void release_http_map(struct act_rule *rule)
{
	struct logformat_node *lf, *lfb;

	free(rule->arg.map.ref);
	list_for_each_entry_safe(lf, lfb, &rule->arg.map.key, list) {
		LIST_DELETE(&lf->list);
		release_sample_expr(lf->expr);
		free(lf->arg);
		free(lf);
	}
	if (rule->action == 1) {
		list_for_each_entry_safe(lf, lfb, &rule->arg.map.value, list) {
			LIST_DELETE(&lf->list);
			release_sample_expr(lf->expr);
			free(lf->arg);
			free(lf);
		}
	}
}

/* Parse a "add-acl", "del-acl", "set-map" or "del-map" actions. It takes one or
 * two log-format string as argument depending on the action. The action is
 * stored in <.action> as an int (0=add-acl, 1=set-map, 2=del-acl,
 * 3=del-map). It returns ACT_RET_PRS_OK on success, ACT_RET_PRS_ERR on error.
 */
static enum act_parse_ret parse_http_set_map(const char **args, int *orig_arg, struct proxy *px,
					     struct act_rule *rule, char **err)
{
	int cap = 0, cur_arg;

	if (args[*orig_arg-1][0] == 'a') // add-acl
		rule->action = 0;
	else if (args[*orig_arg-1][0] == 's') // set-map
		rule->action = 1;
	else if (args[*orig_arg-1][4] == 'a') // del-acl
		rule->action = 2;
	else if (args[*orig_arg-1][4] == 'm') // del-map
		rule->action = 3;
	else {
		memprintf(err, "internal error: unhandled action '%s'", args[0]);
		return ACT_RET_PRS_ERR;
	}
	rule->action_ptr = http_action_set_map;
	rule->release_ptr = release_http_map;

	cur_arg = *orig_arg;
	if (rule->action == 1 && (!*args[cur_arg] || !*args[cur_arg+1])) {
		/* 2 args for set-map */
		memprintf(err, "expects exactly 2 arguments");
		return ACT_RET_PRS_ERR;
	}
	else if (!*args[cur_arg]) {
		/* only one arg for other actions */
		memprintf(err, "expects exactly 1 arguments");
		return ACT_RET_PRS_ERR;
	}

	/*
	 * '+ 8' for 'set-map(' (same for del-map)
	 * '- 9' for 'set-map(' + trailing ')'  (same for del-map)
	 */
	rule->arg.map.ref = my_strndup(args[cur_arg-1] + 8, strlen(args[cur_arg-1]) - 9);

	if (rule->from == ACT_F_HTTP_REQ) {
		px->conf.args.ctx = ARGC_HRQ;
		if (px->cap & PR_CAP_FE)
			cap |= SMP_VAL_FE_HRQ_HDR;
		if (px->cap & PR_CAP_BE)
			cap |= SMP_VAL_BE_HRQ_HDR;
	}
	else{
		px->conf.args.ctx =  ARGC_HRS;
		if (px->cap & PR_CAP_FE)
			cap |= SMP_VAL_FE_HRS_HDR;
		if (px->cap & PR_CAP_BE)
			cap |= SMP_VAL_BE_HRS_HDR;
	}

	/* key pattern */
	LIST_INIT(&rule->arg.map.key);
	if (!parse_logformat_string(args[cur_arg], px, &rule->arg.map.key, LOG_OPT_HTTP, cap, err)) {
		free(rule->arg.map.ref);
		return ACT_RET_PRS_ERR;
	}

	if (rule->action == 1) {
		/* value pattern for set-map only */
		cur_arg++;
		LIST_INIT(&rule->arg.map.value);
		if (!parse_logformat_string(args[cur_arg], px, &rule->arg.map.value, LOG_OPT_HTTP, cap, err)) {
			free(rule->arg.map.ref);
			return ACT_RET_PRS_ERR;
		}
	}

	free(px->conf.lfs_file);
	px->conf.lfs_file = strdup(px->conf.args.file);
	px->conf.lfs_line = px->conf.args.line;

	*orig_arg = cur_arg + 1;
	return ACT_RET_PRS_OK;
}

/* This function executes a track-sc* actions. On success, it returns
 * ACT_RET_CONT. Otherwsize ACT_RET_ERR is returned.
 */
static enum act_return http_action_track_sc(struct act_rule *rule, struct proxy *px,
					    struct session *sess, struct stream *s, int flags)
{
	struct stktable *t;
	struct stksess *ts;
	struct stktable_key *key;
	void *ptr1, *ptr2, *ptr3, *ptr4, *ptr5, *ptr6;
	int opt;

	ptr1 = ptr2 = ptr3 = ptr4 = ptr5 = ptr6 = NULL;
	opt = ((rule->from == ACT_F_HTTP_REQ) ? SMP_OPT_DIR_REQ : SMP_OPT_DIR_RES) | SMP_OPT_FINAL;

	t = rule->arg.trk_ctr.table.t;

	if (stkctr_entry(&s->stkctr[rule->action]))
		goto end;

	key = stktable_fetch_key(t, s->be, sess, s, opt, rule->arg.trk_ctr.expr, NULL);

	if (!key)
		goto end;
	ts = stktable_get_entry(t, key);
	if (!ts)
		goto end;

	stream_track_stkctr(&s->stkctr[rule->action], t, ts);

	/* let's count a new HTTP request as it's the first time we do it */
	ptr1 = stktable_data_ptr(t, ts, STKTABLE_DT_HTTP_REQ_CNT);
	ptr2 = stktable_data_ptr(t, ts, STKTABLE_DT_HTTP_REQ_RATE);

	/* When the client triggers a 4xx from the server, it's most often due
	 * to a missing object or permission. These events should be tracked
	 * because if they happen often, it may indicate a brute force or a
	 * vulnerability scan. Normally this is done when receiving the response
	 * but here we're tracking after this ought to have been done so we have
	 * to do it on purpose.
	 */
	if (rule->from == ACT_F_HTTP_RES && (unsigned)(s->txn->status - 400) < 100) {
		ptr3 = stktable_data_ptr(t, ts, STKTABLE_DT_HTTP_ERR_CNT);
		ptr4 = stktable_data_ptr(t, ts, STKTABLE_DT_HTTP_ERR_RATE);
	}

	if (rule->from == ACT_F_HTTP_RES && (unsigned)(s->txn->status - 500) < 100 &&
	    s->txn->status != 501 && s->txn->status != 505) {
		ptr5 = stktable_data_ptr(t, ts, STKTABLE_DT_HTTP_FAIL_CNT);
		ptr6 = stktable_data_ptr(t, ts, STKTABLE_DT_HTTP_FAIL_RATE);
	}

	if (ptr1 || ptr2 || ptr3 || ptr4 || ptr5 || ptr6) {
		HA_RWLOCK_WRLOCK(STK_SESS_LOCK, &ts->lock);

		if (ptr1)
			stktable_data_cast(ptr1, std_t_uint)++;
		if (ptr2)
			update_freq_ctr_period(&stktable_data_cast(ptr2, std_t_frqp),
					       t->data_arg[STKTABLE_DT_HTTP_REQ_RATE].u, 1);
		if (ptr3)
			stktable_data_cast(ptr3, std_t_uint)++;
		if (ptr4)
			update_freq_ctr_period(&stktable_data_cast(ptr4, std_t_frqp),
					       t->data_arg[STKTABLE_DT_HTTP_ERR_RATE].u, 1);
		if (ptr5)
			stktable_data_cast(ptr5, std_t_uint)++;
		if (ptr6)
			update_freq_ctr_period(&stktable_data_cast(ptr6, std_t_frqp),
					       t->data_arg[STKTABLE_DT_HTTP_FAIL_RATE].u, 1);

		HA_RWLOCK_WRUNLOCK(STK_SESS_LOCK, &ts->lock);

		/* If data was modified, we need to touch to re-schedule sync */
		stktable_touch_local(t, ts, 0);
	}

	stkctr_set_flags(&s->stkctr[rule->action], STKCTR_TRACK_CONTENT);
	if (sess->fe != s->be)
		stkctr_set_flags(&s->stkctr[rule->action], STKCTR_TRACK_BACKEND);

  end:
	return ACT_RET_CONT;
}

static void release_http_track_sc(struct act_rule *rule)
{
	release_sample_expr(rule->arg.trk_ctr.expr);
}

/* Parse a "track-sc*" actions. It returns ACT_RET_PRS_OK on success,
 * ACT_RET_PRS_ERR on error.
 */
static enum act_parse_ret parse_http_track_sc(const char **args, int *orig_arg, struct proxy *px,
						 struct act_rule *rule, char **err)
{
	struct sample_expr *expr;
	unsigned int where;
	unsigned int tsc_num;
	const char *tsc_num_str;
	int cur_arg;

	tsc_num_str = &args[*orig_arg-1][8];
	if (cfg_parse_track_sc_num(&tsc_num, tsc_num_str, tsc_num_str + strlen(tsc_num_str), err) == -1)
		return ACT_RET_PRS_ERR;

	cur_arg = *orig_arg;
	expr = sample_parse_expr((char **)args, &cur_arg, px->conf.args.file, px->conf.args.line,
				 err, &px->conf.args, NULL);
	if (!expr)
		return ACT_RET_PRS_ERR;

	where = 0;
	if (px->cap & PR_CAP_FE)
		where |= (rule->from == ACT_F_HTTP_REQ ? SMP_VAL_FE_HRQ_HDR : SMP_VAL_FE_HRS_HDR);
	if (px->cap & PR_CAP_BE)
		where |= (rule->from == ACT_F_HTTP_REQ ? SMP_VAL_BE_HRQ_HDR : SMP_VAL_BE_HRS_HDR);

	if (!(expr->fetch->val & where)) {
		memprintf(err, "fetch method '%s' extracts information from '%s', none of which is available here",
			  args[cur_arg-1], sample_src_names(expr->fetch->use));
		release_sample_expr(expr);
		return ACT_RET_PRS_ERR;
	}

	if (strcmp(args[cur_arg], "table") == 0) {
		cur_arg++;
		if (!*args[cur_arg]) {
			memprintf(err, "missing table name");
			release_sample_expr(expr);
			return ACT_RET_PRS_ERR;
		}

		/* we copy the table name for now, it will be resolved later */
		rule->arg.trk_ctr.table.n = strdup(args[cur_arg]);
		cur_arg++;
	}

	rule->action = tsc_num;
	rule->arg.trk_ctr.expr = expr;
	rule->action_ptr = http_action_track_sc;
	rule->release_ptr = release_http_track_sc;
	rule->check_ptr = check_trk_action;

	*orig_arg = cur_arg;
	return ACT_RET_PRS_OK;
}

static enum act_return action_timeout_set_stream_timeout(struct act_rule *rule,
                                                         struct proxy *px,
                                                         struct session *sess,
                                                         struct stream *s,
                                                         int flags)
{
	struct sample *key;

	if (rule->arg.timeout.expr) {
		key = sample_fetch_as_type(px, sess, s, SMP_OPT_FINAL, rule->arg.timeout.expr, SMP_T_SINT);
		if (!key)
			return ACT_RET_CONT;

		stream_set_timeout(s, rule->arg.timeout.type, MS_TO_TICKS(key->data.u.sint));
	}
	else {
		stream_set_timeout(s, rule->arg.timeout.type, MS_TO_TICKS(rule->arg.timeout.value));
	}

	return ACT_RET_CONT;
}

/* Parse a "set-timeout" action. Returns ACT_RET_PRS_ERR if parsing error.
 */
static enum act_parse_ret parse_http_set_timeout(const char **args,
                                                 int *orig_arg,
                                                 struct proxy *px,
                                                 struct act_rule *rule, char **err)
{
	int cur_arg;

	rule->action = ACT_CUSTOM;
	rule->action_ptr = action_timeout_set_stream_timeout;
	rule->release_ptr = release_timeout_action;

	cur_arg = *orig_arg;
	if (!*args[cur_arg] || !*args[cur_arg + 1]) {
		memprintf(err, "expects exactly 2 arguments");
		return ACT_RET_PRS_ERR;
	}

	if (!(px->cap & PR_CAP_BE)) {
		memprintf(err, "proxy '%s' has no backend capability", px->id);
		return ACT_RET_PRS_ERR;
	}

	if (cfg_parse_rule_set_timeout(args, cur_arg,
	                               &rule->arg.timeout.value,
	                               &rule->arg.timeout.type,
	                               &rule->arg.timeout.expr,
	                               err,
	                               px->conf.args.file,
	                               px->conf.args.line, &px->conf.args) == -1) {
		return ACT_RET_PRS_ERR;
	}

	*orig_arg = cur_arg + 2;

	return ACT_RET_PRS_OK;
}

/* This function executes a strict-mode actions. On success, it always returns
 * ACT_RET_CONT
 */
static enum act_return http_action_strict_mode(struct act_rule *rule, struct proxy *px,
					       struct session *sess, struct stream *s, int flags)
{
	struct http_msg *msg = ((rule->from == ACT_F_HTTP_REQ) ? &s->txn->req : &s->txn->rsp);

	if (rule->action == 0) // strict-mode on
		msg->flags &= ~HTTP_MSGF_SOFT_RW;
	else // strict-mode off
		msg->flags |= HTTP_MSGF_SOFT_RW;
	return ACT_RET_CONT;
}

/* Parse a "strict-mode" action. It returns ACT_RET_PRS_OK on success,
 * ACT_RET_PRS_ERR on error.
 */
static enum act_parse_ret parse_http_strict_mode(const char **args, int *orig_arg, struct proxy *px,
						 struct act_rule *rule, char **err)
{
	int cur_arg;

	cur_arg = *orig_arg;
	if (!*args[cur_arg]) {
		memprintf(err, "expects exactly 1 arguments");
		return ACT_RET_PRS_ERR;
	}

	if (strcasecmp(args[cur_arg], "on") == 0)
		rule->action = 0; // strict-mode on
	else if (strcasecmp(args[cur_arg], "off") == 0)
		rule->action = 1; // strict-mode off
	else {
		memprintf(err, "Unexpected value '%s'. Only 'on' and 'off' are supported", args[cur_arg]);
		return ACT_RET_PRS_ERR;
	}
	rule->action_ptr = http_action_strict_mode;

	*orig_arg = cur_arg + 1;
	return ACT_RET_PRS_OK;
}

/* This function executes a return action. It builds an HTX message from an
 * errorfile, an raw file or a log-format string, depending on <.action>
 * value. On success, it returns ACT_RET_ABRT. If an error occurs ACT_RET_ERR is
 * returned.
 */
static enum act_return http_action_return(struct act_rule *rule, struct proxy *px,
					  struct session *sess, struct stream *s, int flags)
{
	struct channel *req = &s->req;

	s->txn->status = rule->arg.http_reply->status;
	if (http_reply_message(s, rule->arg.http_reply) == -1)
		return ACT_RET_ERR;

	if (rule->from == ACT_F_HTTP_REQ) {
		/* let's log the request time */
		s->logs.request_ts = now_ns;
		req->analysers &= AN_REQ_FLT_END;

		if (s->sess->fe == s->be) /* report it if the request was intercepted by the frontend */
			_HA_ATOMIC_INC(&s->sess->fe->fe_counters.intercepted_req);
	}

	if (!(s->flags & SF_ERR_MASK))
		s->flags |= SF_ERR_LOCAL;
	if (!(s->flags & SF_FINST_MASK))
		s->flags |= ((rule->from == ACT_F_HTTP_REQ) ? SF_FINST_R : SF_FINST_H);

	return ACT_RET_ABRT;
}

/* Parse a "return" action. It returns ACT_RET_PRS_OK on success,
 * ACT_RET_PRS_ERR on error. It relies on http_parse_http_reply() to set
 * <.arg.http_reply>.
 */
static enum act_parse_ret parse_http_return(const char **args, int *orig_arg, struct proxy *px,
					    struct act_rule *rule, char **err)
{
	/* Prepare parsing of log-format strings */
	px->conf.args.ctx = ((rule->from == ACT_F_HTTP_REQ) ? ARGC_HRQ : ARGC_HRS);
	rule->arg.http_reply = http_parse_http_reply(args, orig_arg, px, 200, err);
	if (!rule->arg.http_reply)
		return ACT_RET_PRS_ERR;

	rule->flags |= ACT_FLAG_FINAL;
	rule->action = ACT_CUSTOM;
	rule->check_ptr = check_act_http_reply;
	rule->action_ptr = http_action_return;
	rule->release_ptr = release_act_http_reply;
	return ACT_RET_PRS_OK;
}



/* This function executes a wait-for-body action. It waits for the message
 * payload for a max configured time (.arg.p[0]) and eventually for only first
 * <arg.p[1]> bytes (0 means no limit). It relies on http_wait_for_msg_body()
 * function. it returns ACT_RET_CONT when conditions are met to stop to wait.
 * Otherwise ACT_RET_YIELD is returned to wait for more data. ACT_RET_INV is
 * returned if a parsing error is raised by lower level and ACT_RET_ERR if an
 * internal error occurred. Finally ACT_RET_ABRT is returned when a timeout
 * occurred.
 */
static enum act_return http_action_wait_for_body(struct act_rule *rule, struct proxy *px,
						 struct session *sess, struct stream *s, int flags)
{
	struct channel *chn = ((rule->from == ACT_F_HTTP_REQ) ? &s->req : &s->res);
	unsigned int time = (uintptr_t)rule->arg.act.p[0];
	unsigned int bytes = (uintptr_t)rule->arg.act.p[1];

	switch (http_wait_for_msg_body(s, chn, time, bytes)) {
	case HTTP_RULE_RES_CONT:
		return ACT_RET_CONT;
	case HTTP_RULE_RES_YIELD:
		return ACT_RET_YIELD;
	case HTTP_RULE_RES_BADREQ:
		return ACT_RET_INV;
	case HTTP_RULE_RES_ERROR:
		return ACT_RET_ERR;
	case HTTP_RULE_RES_ABRT:
		return ACT_RET_ABRT;
	default:
		return ACT_RET_ERR;
	}
}

/* Parse a "wait-for-body" action. It returns ACT_RET_PRS_OK on success,
 * ACT_RET_PRS_ERR on error.
 */
static enum act_parse_ret parse_http_wait_for_body(const char **args, int *orig_arg, struct proxy *px,
						   struct act_rule *rule, char **err)
{
	int cur_arg;
	unsigned int time, bytes;
	const char *res;

	cur_arg = *orig_arg;
	if (!*args[cur_arg]) {
		memprintf(err, "expects time <time> [ at-least <bytes> ]");
		return ACT_RET_PRS_ERR;
	}

	time = UINT_MAX; /* To be sure it is set */
	bytes = 0; /* Default value, wait all the body */
	while (*(args[cur_arg])) {
		if (strcmp(args[cur_arg], "time") == 0) {
			if (!*args[cur_arg + 1]) {
				memprintf(err, "missing argument for '%s'", args[cur_arg]);
				return ACT_RET_PRS_ERR;
			}
			res = parse_time_err(args[cur_arg+1], &time, TIME_UNIT_MS);
			if (res == PARSE_TIME_OVER) {
				memprintf(err, "time overflow (maximum value is 2147483647 ms or ~24.8 days)");
				return ACT_RET_PRS_ERR;
			}
			if (res == PARSE_TIME_UNDER) {
				memprintf(err, "time underflow (minimum non-null value is 1 ms)");
				return ACT_RET_PRS_ERR;
			}
			if (res) {
				memprintf(err, "unexpected character '%c'", *res);
				return ACT_RET_PRS_ERR;
			}
			cur_arg++;
		}
		else if (strcmp(args[cur_arg], "at-least") == 0) {
			if (!*args[cur_arg + 1]) {
				memprintf(err, "missing argument for '%s'", args[cur_arg]);
				return ACT_RET_PRS_ERR;
			}
			res = parse_size_err(args[cur_arg+1], &bytes);
			if (res) {
				memprintf(err, "unexpected character '%c'", *res);
				return ACT_RET_PRS_ERR;
			}
			cur_arg++;
		}
		else
			break;
		cur_arg++;
	}

	if (time == UINT_MAX) {
		memprintf(err, "expects time <time> [ at-least <bytes> ]");
		return ACT_RET_PRS_ERR;
	}

	rule->arg.act.p[0] = (void *)(uintptr_t)time;
	rule->arg.act.p[1] = (void *)(uintptr_t)bytes;

	*orig_arg = cur_arg;

	rule->action = ACT_CUSTOM;
	rule->action_ptr = http_action_wait_for_body;
	return ACT_RET_PRS_OK;
}

/************************************************************************/
/*   All supported http-request action keywords must be declared here.  */
/************************************************************************/

static struct action_kw_list http_req_actions = {
	.kw = {
		{ "add-acl",          parse_http_set_map,              KWF_MATCH_PREFIX },
		{ "add-header",       parse_http_set_header,           0 },
		{ "allow",            parse_http_allow,                0 },
		{ "auth",             parse_http_auth,                 0 },
		{ "capture",          parse_http_req_capture,          0 },
		{ "del-acl",          parse_http_set_map,              KWF_MATCH_PREFIX },
		{ "del-header",       parse_http_del_header,           0 },
		{ "del-map",          parse_http_set_map,              KWF_MATCH_PREFIX },
		{ "deny",             parse_http_deny,                 0 },
		{ "disable-l7-retry", parse_http_req_disable_l7_retry, 0 },
		{ "early-hint",       parse_http_set_header,           0 },
		{ "normalize-uri",    parse_http_normalize_uri,        KWF_EXPERIMENTAL },
		{ "redirect",         parse_http_redirect,             0 },
		{ "reject",           parse_http_action_reject,        0 },
		{ "replace-header",   parse_http_replace_header,       0 },
		{ "replace-path",     parse_replace_uri,               0 },
		{ "replace-pathq",    parse_replace_uri,               0 },
		{ "replace-uri",      parse_replace_uri,               0 },
		{ "replace-value",    parse_http_replace_header,       0 },
		{ "return",           parse_http_return,               0 },
		{ "set-header",       parse_http_set_header,           0 },
		{ "set-map",          parse_http_set_map,              KWF_MATCH_PREFIX },
		{ "set-method",       parse_set_req_line,              0 },
		{ "set-path",         parse_set_req_line,              0 },
		{ "set-pathq",        parse_set_req_line,              0 },
		{ "set-query",        parse_set_req_line,              0 },
		{ "set-uri",          parse_set_req_line,              0 },
		{ "strict-mode",      parse_http_strict_mode,          0 },
		{ "tarpit",           parse_http_deny,                 0 },
		{ "track-sc",         parse_http_track_sc,             KWF_MATCH_PREFIX },
		{ "set-timeout",      parse_http_set_timeout,          0 },
		{ "wait-for-body",    parse_http_wait_for_body,        0 },
		{ NULL, NULL }
	}
};

INITCALL1(STG_REGISTER, http_req_keywords_register, &http_req_actions);

static struct action_kw_list http_res_actions = {
	.kw = {
		{ "add-acl",         parse_http_set_map,        KWF_MATCH_PREFIX },
		{ "add-header",      parse_http_set_header,     0 },
		{ "allow",           parse_http_allow,          0 },
		{ "capture",         parse_http_res_capture,    0 },
		{ "del-acl",         parse_http_set_map,        KWF_MATCH_PREFIX },
		{ "del-header",      parse_http_del_header,     0 },
		{ "del-map",         parse_http_set_map,        KWF_MATCH_PREFIX },
		{ "deny",            parse_http_deny,           0 },
		{ "redirect",        parse_http_redirect,       0 },
		{ "replace-header",  parse_http_replace_header, 0 },
		{ "replace-value",   parse_http_replace_header, 0 },
		{ "return",          parse_http_return,         0 },
		{ "set-header",      parse_http_set_header,     0 },
		{ "set-map",         parse_http_set_map,        KWF_MATCH_PREFIX },
		{ "set-status",      parse_http_set_status,     0 },
		{ "strict-mode",     parse_http_strict_mode,    0 },
		{ "track-sc",        parse_http_track_sc,       KWF_MATCH_PREFIX },
		{ "wait-for-body",   parse_http_wait_for_body,  0 },
		{ NULL, NULL }
	}
};

INITCALL1(STG_REGISTER, http_res_keywords_register, &http_res_actions);

static struct action_kw_list http_after_res_actions = {
	.kw = {
		{ "add-header",      parse_http_set_header,     0 },
		{ "allow",           parse_http_allow,          0 },
		{ "capture",         parse_http_res_capture,    0 },
		{ "del-acl",          parse_http_set_map,       KWF_MATCH_PREFIX },
		{ "del-header",      parse_http_del_header,     0 },
		{ "del-map",          parse_http_set_map,       KWF_MATCH_PREFIX },
		{ "replace-header",  parse_http_replace_header, 0 },
		{ "replace-value",   parse_http_replace_header, 0 },
		{ "set-header",      parse_http_set_header,     0 },
		{ "set-map",         parse_http_set_map,        KWF_MATCH_PREFIX },
		{ "set-status",      parse_http_set_status,     0 },
		{ "strict-mode",     parse_http_strict_mode,    0 },
		{ NULL, NULL }
	}
};

INITCALL1(STG_REGISTER, http_after_res_keywords_register, &http_after_res_actions);

/*
 * Local variables:
 *  c-indent-level: 8
 *  c-basic-offset: 8
 * End:
 */
