mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-01-29 17:42:54 +00:00
MEDIUM: http: add the ability to redefine http-err-codes and http-fail-codes
The new global keywords "http-err-codes" and "http-fail-codes" allow to redefine which HTTP status codes indicate a client-induced error or a server error, as tracked by stick-table counters. This is only done globally, though everything was done so that it could easily be extended to a per-proxy mechanism if there was a real need for this (but it would eat quite more RAM then). A simple reg-test was added (http-err-fail.vtc).
This commit is contained in:
parent
9d827e1049
commit
4cc25f26f9
@ -1919,6 +1919,40 @@ hard-stop-after <time>
|
||||
|
||||
See also: grace
|
||||
|
||||
http-err-codes [+-]<range>[,...] [...]
|
||||
Replace, reduce or extend the list of status codes that define an error as
|
||||
considered by the termination codes and the "http_err_cnt" counter in stick
|
||||
tables. The default range for errors is 400 to 499, but in certain contexts
|
||||
some users prefer to exclude specific codes, especially when tracking client
|
||||
errors (e.g. 404 on systems with dynamically generated contents). See also
|
||||
"http-fail-codes" and "http_err_cnt".
|
||||
|
||||
A range specified without '+' nor '-' redefines the existing range to the new
|
||||
one. A range starting with '+' extends the existing range to also include the
|
||||
specified one, which may or may not overlap with the existing one. A range
|
||||
starting with '-' removes the specified range from the existing one. A range
|
||||
consists in a number from 100 to 599, optionally followed by "-" followed by
|
||||
another number greater than or equal to the first one to indicate the high
|
||||
boundary of the range. Multiple ranges may be delimited by commas for a same
|
||||
add/del/ replace operation.
|
||||
|
||||
Example:
|
||||
http-err-codes 400,402-444,446-480,490 # sets exactly these codes
|
||||
http-err-codes 400-499 -450 +500 # sets 400 to 500 except 450
|
||||
http-err-codes -450-459 # removes 450 to 459 from range
|
||||
http-err-codes +501,505 # adds 501 and 505 to range
|
||||
|
||||
http-fail-codes [+-]<range>[,...] [...]
|
||||
Replace, reduce or extend the list of status codes that define a failure as
|
||||
considered by the termination codes and the "http_fail_cnt" counter in stick
|
||||
tables. The default range for failures is 500 to 599 except 501 and 505 which
|
||||
can be triggered by clients, and normally indicate a failure from the server
|
||||
to process the request. Some users prefer to exclude certain codes in certain
|
||||
contexts where it is known they're not relevant, such as 500 in certain SOAP
|
||||
environments as it doesn't translate a server fault there. The syntax is
|
||||
exactly the same as for http-err-codes above. See also "http-err-codes" and
|
||||
"http_fail_cnt".
|
||||
|
||||
httpclient.resolvers.disabled <on|off>
|
||||
Disable the DNS resolution of the httpclient. Prevent the creation of the
|
||||
"default" resolvers section.
|
||||
|
84
reg-tests/http-rules/http-err-fail.vtc
Normal file
84
reg-tests/http-rules/http-err-fail.vtc
Normal file
@ -0,0 +1,84 @@
|
||||
varnishtest "test for http-err-codes/http-fail-codes redefinitions"
|
||||
|
||||
feature cmd "$HAPROXY_PROGRAM -cc 'version_atleast(3.0-dev1)'"
|
||||
feature ignore_unknown_macro
|
||||
|
||||
server s2 {
|
||||
rxreq
|
||||
txresp -status 220
|
||||
} -start
|
||||
|
||||
server s3 {
|
||||
rxreq
|
||||
txresp -status 300
|
||||
} -start
|
||||
|
||||
server s4 {
|
||||
rxreq
|
||||
txresp -status 400
|
||||
} -start
|
||||
|
||||
server s5 {
|
||||
rxreq
|
||||
txresp -status 555
|
||||
} -start
|
||||
|
||||
|
||||
haproxy h1 -conf {
|
||||
global
|
||||
http-err-codes 220 +300-499 -300-399 # only 220, 400-499 remain
|
||||
http-fail-codes -550-580 +555,599,556-566
|
||||
|
||||
defaults
|
||||
mode http
|
||||
timeout connect "${HAPROXY_TEST_TIMEOUT-5s}"
|
||||
timeout client "${HAPROXY_TEST_TIMEOUT-5s}"
|
||||
timeout server "${HAPROXY_TEST_TIMEOUT-5s}"
|
||||
option socket-stats
|
||||
|
||||
frontend fe
|
||||
bind "fd@${fe}"
|
||||
http-request track-sc0 path
|
||||
http-after-response add-header x-table err=%[sc0_http_err_cnt],fail=%[sc0_http_fail_cnt]
|
||||
stick-table type string size 100 store http_err_cnt,http_fail_cnt
|
||||
default_backend be
|
||||
|
||||
backend be
|
||||
use-server s2 if { path -m beg /2 }
|
||||
use-server s3 if { path -m beg /3 }
|
||||
use-server s4 if { path -m beg /4 }
|
||||
use-server s5 if { path -m beg /5 }
|
||||
|
||||
server s2 ${s2_addr}:${s2_port}
|
||||
server s3 ${s3_addr}:${s3_port}
|
||||
server s4 ${s4_addr}:${s4_port}
|
||||
server s5 ${s5_addr}:${s5_port}
|
||||
} -start
|
||||
|
||||
client c2 -connect ${h1_fe_sock} {
|
||||
txreq -url "/2"
|
||||
rxresp
|
||||
expect resp.status == 220
|
||||
expect resp.http.x-table ~ "err=1,fail=0"
|
||||
} -run
|
||||
|
||||
client c3 -connect ${h1_fe_sock} {
|
||||
txreq -url "/3"
|
||||
rxresp
|
||||
expect resp.status == 300
|
||||
expect resp.http.x-table ~ "err=0,fail=0"
|
||||
} -run
|
||||
|
||||
client c4 -connect ${h1_fe_sock} {
|
||||
txreq -url "/4"
|
||||
rxresp
|
||||
expect resp.status == 400
|
||||
expect resp.http.x-table ~ "err=1,fail=0"
|
||||
} -run
|
||||
|
||||
client c5 -connect ${h1_fe_sock} {
|
||||
txreq -url "/5"
|
||||
rxresp
|
||||
expect resp.status == 555
|
||||
expect resp.http.x-table ~ "err=0,fail=1"
|
||||
} -run
|
98
src/http.c
98
src/http.c
@ -12,6 +12,7 @@
|
||||
|
||||
#include <ctype.h>
|
||||
#include <haproxy/api.h>
|
||||
#include <haproxy/cfgparse.h>
|
||||
#include <haproxy/http.h>
|
||||
#include <haproxy/tools.h>
|
||||
|
||||
@ -1483,3 +1484,100 @@ static void _http_init()
|
||||
http_status_del_range(http_fail_status_codes, 505, 505);
|
||||
}
|
||||
INITCALL0(STG_INIT, _http_init);
|
||||
|
||||
/*
|
||||
* registered keywords below
|
||||
*/
|
||||
|
||||
/* parses a global "http-err-codes" and "http-fail-codes" directive. */
|
||||
static int http_parse_http_err_fail_codes(char **args, int section_type, struct proxy *curpx,
|
||||
const struct proxy *defpx, const char *file, int line,
|
||||
char **err)
|
||||
{
|
||||
const char *cmd = args[0];
|
||||
const char *p, *b, *e;
|
||||
int op, low, high;
|
||||
long *bitfield;
|
||||
int ret = -1;
|
||||
|
||||
if (strcmp(cmd, "http-err-codes") == 0)
|
||||
bitfield = http_err_status_codes;
|
||||
else if (strcmp(cmd, "http-fail-codes") == 0)
|
||||
bitfield = http_fail_status_codes;
|
||||
else
|
||||
ABORT_NOW();
|
||||
|
||||
if (!*args[1]) {
|
||||
memprintf(err, "Missing status codes range for '%s'.", cmd);
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* operation: <0 = remove, 0 = replace, >0 = add. The operation is only
|
||||
* reset for each new arg so that we can do +200,300,400 without
|
||||
* changing the operation.
|
||||
*/
|
||||
for (; *(p = *(++args)); ) {
|
||||
switch (*p) {
|
||||
case '+': op = 1; p++; break;
|
||||
case '-': op = -1; p++; break;
|
||||
default: op = 0; break;
|
||||
}
|
||||
|
||||
if (!*p)
|
||||
goto inval;
|
||||
|
||||
while (1) {
|
||||
b = p;
|
||||
e = p + strlen(p);
|
||||
low = read_uint(&p, e);
|
||||
if (b == e || p == b)
|
||||
goto inval;
|
||||
|
||||
high = low;
|
||||
if (*p == '-') {
|
||||
p++;
|
||||
b = p;
|
||||
high = read_uint(&p, e);
|
||||
if (b == e || p == b || (*p && *p != ','))
|
||||
goto inval;
|
||||
}
|
||||
else if (*p && *p != ',')
|
||||
goto inval;
|
||||
|
||||
if (high < low || low < 100 || high > 599) {
|
||||
memprintf(err, "Invalid status codes range '%s' in '%s'.\n"
|
||||
" Codes must be between 100 and 599 and ranges in ascending order.",
|
||||
*args, cmd);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!op)
|
||||
memset(bitfield, 0, sizeof(http_err_status_codes));
|
||||
if (op >= 0)
|
||||
http_status_add_range(bitfield, low, high);
|
||||
if (op < 0)
|
||||
http_status_del_range(bitfield, low, high);
|
||||
|
||||
if (!*p)
|
||||
break;
|
||||
/* skip ',' */
|
||||
p++;
|
||||
}
|
||||
}
|
||||
ret = 0;
|
||||
end:
|
||||
return ret;
|
||||
inval:
|
||||
memprintf(err, "Invalid status codes range '%s' in '%s' at position %lu. Ranges must be in the form [+-]{low[-{high}]}[,...].",
|
||||
*args, cmd, (ulong)(p - *args));
|
||||
goto end;
|
||||
|
||||
}
|
||||
|
||||
static struct cfg_kw_list cfg_kws = {{ },{
|
||||
{ CFG_GLOBAL, "http-err-codes", http_parse_http_err_fail_codes },
|
||||
{ CFG_GLOBAL, "http-fail-codes", http_parse_http_err_fail_codes },
|
||||
{ /* END */ }
|
||||
}};
|
||||
|
||||
INITCALL1(STG_REGISTER, cfg_register_keywords, &cfg_kws);
|
||||
|
Loading…
Reference in New Issue
Block a user