MINOR: http: add infrastructure to choose status codes for err / fail
At the moment, http_err_cnt and http_fail_cnt are incremented on a well-defined set of status codes, which are checked at various places. Over time, there have been some complains about 404, 401 or 407 triggering errors, or 500 triggering failures in SOAP environments for example. With a small bit field that fits in a cache line we can match the presence of a status code from 100 to 599, so that remains cheap. This patch adds two such bit fields, one per code class, and the accompanying functions to set/clear/test the codes. The arrays are preset at boot time. For now they are not used and it's not possible to adjust them.
This commit is contained in:
parent
59c01f1091
commit
3c135569c5
@ -27,15 +27,20 @@
|
||||
#include <import/ist.h>
|
||||
#include <haproxy/api.h>
|
||||
#include <haproxy/http-t.h>
|
||||
#include <haproxy/intops.h>
|
||||
|
||||
extern const int http_err_codes[HTTP_ERR_SIZE];
|
||||
extern const char *http_err_msgs[HTTP_ERR_SIZE];
|
||||
extern const struct ist http_known_methods[HTTP_METH_OTHER];
|
||||
extern const uint8_t http_char_classes[256];
|
||||
extern long http_err_status_codes[512 / sizeof(long)];
|
||||
extern long http_fail_status_codes[512 / sizeof(long)];
|
||||
|
||||
enum http_meth_t find_http_meth(const char *str, const int len);
|
||||
int http_get_status_idx(unsigned int status);
|
||||
const char *http_get_reason(unsigned int status);
|
||||
void http_status_add_range(long *array, uint low, uint high);
|
||||
void http_status_del_range(long *array, uint low, uint high);
|
||||
struct ist http_get_host_port(const struct ist host);
|
||||
int http_is_default_port(const struct ist schm, const struct ist port);
|
||||
int http_validate_scheme(const struct ist schm);
|
||||
@ -212,6 +217,18 @@ static inline int http_path_has_forbidden_char(const struct ist ist, const char
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Checks status code array <array> for the presence of status code <status>.
|
||||
* Returns non-zero if the code is present, zero otherwise. Any status code is
|
||||
* permitted.
|
||||
*/
|
||||
static inline int http_status_matches(const long *array, uint status)
|
||||
{
|
||||
if (status < 100 || status > 599)
|
||||
return 0;
|
||||
|
||||
return ha_bit_test(status - 100, array);
|
||||
}
|
||||
|
||||
#endif /* _HAPROXY_HTTP_H */
|
||||
|
||||
/*
|
||||
|
53
src/http.c
53
src/http.c
@ -344,6 +344,14 @@ const struct ist http_known_methods[HTTP_METH_OTHER] = {
|
||||
[HTTP_METH_CONNECT] = IST("CONNECT"),
|
||||
};
|
||||
|
||||
/* 500 bits to indicate for each status code from 100 to 599 if it participates
|
||||
* to the error or failure class. The last 12 bits are not assigned for now.
|
||||
* Not initialized, has to be done at boot. This is manipulated using
|
||||
* http_status_{add,del}_range().
|
||||
*/
|
||||
long http_err_status_codes[512 / sizeof(long)] = { };
|
||||
long http_fail_status_codes[512 / sizeof(long)] = { };
|
||||
|
||||
/*
|
||||
* returns a known method among HTTP_METH_* or HTTP_METH_OTHER for all unknown
|
||||
* ones.
|
||||
@ -477,6 +485,40 @@ const char *http_get_reason(unsigned int status)
|
||||
}
|
||||
}
|
||||
|
||||
/* add status codes from low to high included to status codes array <array>
|
||||
* which must be compatible with http_err_codes and http_fail_codes (i.e. 512
|
||||
* bits each). This is not thread save and is meant for being called during
|
||||
* boot only. Only status codes 100-599 are permitted.
|
||||
*/
|
||||
void http_status_add_range(long *array, uint low, uint high)
|
||||
{
|
||||
low -= 100;
|
||||
high -= 100;
|
||||
|
||||
BUG_ON(low > 499);
|
||||
BUG_ON(high > 499);
|
||||
|
||||
while (low <= high)
|
||||
ha_bit_set(low++, array);
|
||||
}
|
||||
|
||||
/* remove status codes from low to high included to status codes array <array>
|
||||
* which must be compatible with http_err_codes and http_fail_codes (i.e. 512
|
||||
* bits each). This is not thread save and is meant for being called during
|
||||
* boot only. Only status codes 100-599 are permitted.
|
||||
*/
|
||||
void http_status_del_range(long *array, uint low, uint high)
|
||||
{
|
||||
low -= 100;
|
||||
high -= 100;
|
||||
|
||||
BUG_ON(low > 499);
|
||||
BUG_ON(high > 499);
|
||||
|
||||
while (low <= high)
|
||||
ha_bit_clr(low++, array);
|
||||
}
|
||||
|
||||
/* Returns the ist string corresponding to port part (without ':') in the host
|
||||
* <host>, IST_NULL if no ':' is found or an empty IST if there is no digit. In
|
||||
* the last case, the result is the original ist trimmed to 0. So be sure to test
|
||||
@ -1430,3 +1472,14 @@ struct ist http_trim_trailing_spht(struct ist value)
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* initialize the required structures and arrays */
|
||||
static void _http_init()
|
||||
{
|
||||
/* preset the default status codes that count as errors and failures */
|
||||
http_status_add_range(http_err_status_codes, 400, 499);
|
||||
http_status_add_range(http_fail_status_codes, 500, 599);
|
||||
http_status_del_range(http_fail_status_codes, 501, 501);
|
||||
http_status_del_range(http_fail_status_codes, 505, 505);
|
||||
}
|
||||
INITCALL0(STG_INIT, _http_init);
|
||||
|
Loading…
x
Reference in New Issue
Block a user