* builds a string in the trash from the specified format string. It finds
* the action to be performed in <http.action>, previously filled by function
* parse_set_req_line(). The replacement action is excuted by the function
- * http_action_set_req_line(). It always returns ACT_RET_CONT. If an error
- * occurs the action is canceled, but the rule processing continue.
+ * 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)
replace = alloc_trash_chunk();
if (!replace)
- goto leave;
+ goto fail_alloc;
/* If we have to create a query string, prepare a '?'. */
if (rule->arg.http.action == 2)
replace->size - replace->data,
&rule->arg.http.logfmt);
- http_req_replace_stline(rule->arg.http.action, replace->area,
- replace->data, px, s);
+ if (http_req_replace_stline(rule->arg.http.action, replace->area,
+ replace->data, px, s) == -1)
+ goto fail_rewrite;
-leave:
+ 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->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;
+ goto leave;
}
/* parse an http-request action among :
* in p[1] to replace the URI. It uses the format string present in act.p[2..3].
* The component to act on (path/uri) is taken from act.p[0] which contains 1
* for the path or 3 for the URI (values used by http_req_replace_stline()).
- * It always returns ACT_RET_CONT. If an error occurs, the action is canceled,
- * but the rule processing continues.
+ * 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)
replace = alloc_trash_chunk();
output = alloc_trash_chunk();
if (!replace || !output)
- goto leave;
+ goto fail_alloc;
uri = htx_sl_req_uri(http_get_stline(htxbuf(&s->req.buf)));
if (rule->arg.act.p[0] == (void *)1)
*/
len = exp_replace(output->area, output->size, uri.ptr, replace->area, pmatch);
if (len == -1)
- goto leave;
+ goto fail_rewrite;
- http_req_replace_stline((long)rule->arg.act.p[0], output->area, len, px, s);
+ if (http_req_replace_stline((long)rule->arg.act.p[0], output->area, len, px, s) == -1)
+ goto fail_rewrite;
-leave:
+ 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_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->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;
+ goto leave;
}
/* parse a "replace-uri" or "replace-path" http-request action.
static enum act_return action_http_set_status(struct act_rule *rule, struct proxy *px,
struct session *sess, struct stream *s, int flags)
{
- http_res_set_status(rule->arg.status.code, rule->arg.status.reason, s);
+ if (http_res_set_status(rule->arg.status.code, rule->arg.status.reason, s) == -1) {
+ _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->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))
+ return ACT_RET_ERR;
+ }
+
return ACT_RET_CONT;
}
const struct ist name, struct list *fmt, struct my_regex *re, int action)
{
struct buffer *replace;
- int ret = -1;
+ int ret = 0;
replace = alloc_trash_chunk();
- if (!replace) {
- if (!(s->flags & SF_ERR_MASK))
- s->flags |= SF_ERR_RESOURCE;
- goto leave;
- }
+ if (!replace)
+ goto fail_alloc;
replace->data = build_logline(s, replace->area, replace->size, fmt);
if (replace->data >= replace->size - 1)
- goto leave;
+ goto fail_rewrite;
- ret = http_transform_header_str(s, chn, htx, name, replace->area, re, action);
+ if (http_transform_header_str(s, chn, htx, name, replace->area, re, action) == -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 = -1;
+ goto leave;
+
+ fail_rewrite:
+ _HA_ATOMIC_ADD(&s->sess->fe->fe_counters.failed_rewrites, 1);
+ if (s->flags & SF_BE_ASSIGNED)
+ _HA_ATOMIC_ADD(&s->be->be_counters.failed_rewrites, 1);
+ if (s->sess->listener->counters)
+ _HA_ATOMIC_ADD(&s->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 = -1;
+ goto leave;
}
}
/* This function replace the HTTP status code and the associated message. The
- * variable <status> contains the new status code. This function never fails.
+ * variable <status> contains the new status code. This function never fails. It
+ * returns 0 in case of success, -1 in case of internal error.
*/
-void http_res_set_status(unsigned int status, const char *reason, struct stream *s)
+int http_res_set_status(unsigned int status, const char *reason, struct stream *s)
{
struct htx *htx = htxbuf(&s->res.buf);
char *res;
if (reason == NULL)
reason = http_get_reason(status);
- if (http_replace_res_status(htx, ist2(trash.area, trash.data)))
- http_replace_res_reason(htx, ist2(reason, strlen(reason)));
+ if (!http_replace_res_status(htx, ist2(trash.area, trash.data)))
+ return -1;
+ if (!http_replace_res_reason(htx, ist2(reason, strlen(reason))))
+ return -1;
+ return 0;
}
/* Executes the http-request rules <rules> for stream <s>, proxy <px> and
}
if (!http_add_header(htx, n, v)) {
- static unsigned char rate_limit = 0;
-
- if ((rate_limit++ & 255) == 0) {
- send_log(px, LOG_WARNING, "Proxy %s failed to add or set the request header '%.*s' for request #%u. You might need to increase tune.maxrewrite.", px->id, (int)n.len, n.ptr, s->uniq_id);
- }
-
_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 (!http_add_header(htx, n, v)) {
- static unsigned char rate_limit = 0;
-
- if ((rate_limit++ & 255) == 0) {
- send_log(px, LOG_WARNING, "Proxy %s failed to add or set the response header '%.*s' for request #%u. You might need to increase tune.maxrewrite.", px->id, (int)n.len, n.ptr, s->uniq_id);
- }
-
_HA_ATOMIC_ADD(&sess->fe->fe_counters.failed_rewrites, 1);
_HA_ATOMIC_ADD(&s->be->be_counters.failed_rewrites, 1);
if (sess->listener->counters)