about ACL usage.
http-response { allow | deny | add-header <name> <fmt> | set-nice <nice> |
- capture <sample> id <id> |
+ capture <sample> id <id> | redirect <rule> |
set-header <name> <fmt> | del-header <name> |
replace-header <name> <regex-match> <replace-fmt> |
replace-value <name> <regex-match> <replace-fmt> |
a previous directive "http-response capture" or with the "declare capture"
keyword.
+ - "redirect" : this performs an HTTP redirection based on a redirect rule.
+ This supports a format string similarly to "http-request redirect" rules,
+ with the exception that only the "location" type of redirect is possible
+ on the response. See the "redirect" keyword for the rule's syntax. When
+ a redirect rule is applied during a response, connections to the server
+ are closed so that no data can be forwarded from the server to the client.
+
There is no limit to the number of http-response statements per instance.
It is important to know that http-response rules are processed very early in
}
-/* Executes the http-response rules <rules> for stream <s>, proxy <px> and
- * transaction <txn>. Returns 3 states: HTTP_RULE_RES_CONT, HTTP_RULE_RES_YIELD
- * or HTTP_RULE_RES_STOP. If *CONT is returned, the process can continue the
- * evaluation of next rule list. If *STOP is returned, the process must stop
- * the evaluation. It may set the TX_SVDENY on txn->flags if it encounters a deny
- * rule. If *YIELD is returned, the czller must call again the function with
- * the same context.
+/* Executes the http-response rules <rules> for stream <s> and proxy <px>. It
+ * returns one of 5 possible statuses: HTTP_RULE_RES_CONT, HTTP_RULE_RES_STOP,
+ * HTTP_RULE_RES_DONE, HTTP_RULE_RES_YIELD, or HTTP_RULE_RES_BADREQ. If *CONT
+ * is returned, the process can continue the evaluation of next rule list. If
+ * *STOP or *DONE is returned, the process must stop the evaluation. If *BADREQ
+ * is returned, it means the operation could not be processed and a server error
+ * must be returned. It may set the TX_SVDENY on txn->flags if it encounters a
+ * deny rule. If *YIELD is returned, the caller must call again the function
+ * with the same context.
*/
static enum rule_result
http_res_get_intercept_rule(struct proxy *px, struct list *rules, struct stream *s)
break;
}
+ case HTTP_RES_ACT_REDIR:
+ if (!http_apply_redirect_rule(rule->arg.redir, s, txn))
+ return HTTP_RULE_RES_BADREQ;
+ return HTTP_RULE_RES_DONE;
+
case HTTP_RES_ACT_CUSTOM_CONT:
if (!rule->action_ptr(rule, px, s)) {
s->current_rule = rule;
s->res.analysers = AN_RES_HTTP_XFER_BODY;
req->msg_state = HTTP_MSG_CLOSED;
res->msg_state = HTTP_MSG_DONE;
+ /* Trim any possible response */
+ res->chn->buf->i = 0;
+ res->next = res->sov = 0;
} else {
/* keep-alive not possible */
if (unlikely(txn->flags & TX_USE_PX_CONN)) {
struct proxy *rule_set = cur_proxy;
/* evaluate http-response rules */
- if (ret == HTTP_RULE_RES_CONT)
+ if (ret == HTTP_RULE_RES_CONT) {
ret = http_res_get_intercept_rule(cur_proxy, &cur_proxy->http_res_rules, s);
+ if (ret == HTTP_RULE_RES_BADREQ)
+ goto return_srv_prx_502;
+
+ if (ret == HTTP_RULE_RES_DONE) {
+ rep->analysers &= ~an_bit;
+ rep->analyse_exp = TICK_ETERNITY;
+ return 1;
+ }
+ }
+
/* we need to be called again. */
if (ret == HTTP_RULE_RES_YIELD) {
channel_dont_close(rep);
proxy->conf.lfs_line = proxy->conf.args.line;
cur_arg += 2;
+ } else if (strcmp(args[0], "redirect") == 0) {
+ struct redirect_rule *redir;
+ char *errmsg = NULL;
+
+ if ((redir = http_parse_redirect_rule(file, linenum, proxy, (const char **)args + 1, &errmsg, 1, 1)) == NULL) {
+ Alert("parsing [%s:%d] : error detected in %s '%s' while parsing 'http-response %s' rule : %s.\n",
+ file, linenum, proxy_type_str(proxy), proxy->id, args[0], errmsg);
+ goto out_err;
+ }
+
+ /* this redirect rule might already contain a parsed condition which
+ * we'll pass to the http-request rule.
+ */
+ rule->action = HTTP_RES_ACT_REDIR;
+ rule->arg.redir = redir;
+ rule->cond = redir->cond;
+ redir->cond = NULL;
+ cur_arg = 2;
+ return rule;
} else if (((custom = action_http_res_custom(args[0])) != NULL)) {
char *errmsg = NULL;
cur_arg = 1;