mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-03-02 17:41:47 +00:00
[MEDIUM] add support for URI hash depth and length limits
This patch adds two optional arguments "len" and "depth" to "balance uri". They are used to limit the length in characters of the analysis, as well as the number of directory components it applies to.
This commit is contained in:
parent
e7dd2f29b9
commit
9c30fc161f
@ -745,6 +745,20 @@ balance url_param <param> [check_post [<max_wait>]]
|
||||
that changing a server's weight on the fly will have no
|
||||
effect.
|
||||
|
||||
This algorithm support two optional parameters "len" and
|
||||
"depth", both followed by a positive integer number. These
|
||||
options may be helpful when it is needed to balance servers
|
||||
based on the beginning of the URI only. The "len" parameter
|
||||
indicates that the algorithm should only consider that many
|
||||
characters at the beginning of the URI to compute the hash.
|
||||
Note that having "len" set to 1 rarely makes sense since most
|
||||
URIs start with a leading "/".
|
||||
|
||||
The "depth" parameter indicates the maximum directory depth
|
||||
to be used to compute the hash. One level is counted for each
|
||||
slash in the request. If both parameters are specified, the
|
||||
evaluation stops when either is reached.
|
||||
|
||||
url_param The URL parameter specified in argument will be looked up in
|
||||
the query string of each HTTP GET request.
|
||||
|
||||
@ -783,9 +797,10 @@ balance url_param <param> [check_post [<max_wait>]]
|
||||
server's weight on the fly will have no effect.
|
||||
|
||||
<arguments> is an optional list of arguments which may be needed by some
|
||||
algorithms. Right now, only the "url_param" algorithm supports
|
||||
an optional argument.
|
||||
algorithms. Right now, only "url_param" and "uri" support an
|
||||
optional argument.
|
||||
|
||||
balance uri [len <len>] [depth <depth>]
|
||||
balance url_param <param> [check_post [<max_wait>]]
|
||||
|
||||
The definition of the load balancing algorithm is mandatory for a backend
|
||||
|
@ -159,6 +159,7 @@ static inline struct server *get_server_uh(struct proxy *px, char *uri, int uri_
|
||||
{
|
||||
unsigned long hash = 0;
|
||||
int c;
|
||||
int slashes = 0;
|
||||
|
||||
if (px->lbprm.tot_weight == 0)
|
||||
return NULL;
|
||||
@ -166,10 +167,19 @@ static inline struct server *get_server_uh(struct proxy *px, char *uri, int uri_
|
||||
if (px->lbprm.map.state & PR_MAP_RECALC)
|
||||
recalc_server_map(px);
|
||||
|
||||
if (px->uri_len_limit)
|
||||
uri_len = MIN(uri_len, px->uri_len_limit);
|
||||
|
||||
while (uri_len--) {
|
||||
c = *uri++;
|
||||
if (c == '?')
|
||||
if (c == '/') {
|
||||
slashes++;
|
||||
if (slashes == px->uri_dirs_depth1) /* depth+1 */
|
||||
break;
|
||||
}
|
||||
else if (c == '?')
|
||||
break;
|
||||
|
||||
hash = c + (hash << 6) + (hash << 16) - hash;
|
||||
}
|
||||
|
||||
|
@ -166,6 +166,8 @@ struct proxy {
|
||||
char *url_param_name; /* name of the URL parameter used for hashing */
|
||||
int url_param_len; /* strlen(url_param_name), computed only once */
|
||||
unsigned url_param_post_limit; /* if checking POST body for URI parameter, max body to wait for */
|
||||
int uri_len_limit; /* character limit for uri balancing algorithm */
|
||||
int uri_dirs_depth1; /* directories+1 (slashes) limit for uri balancing algorithm */
|
||||
char *appsession_name; /* name of the cookie to look for */
|
||||
int appsession_name_len; /* strlen(appsession_name), computed only once */
|
||||
int appsession_len; /* length of the appsession cookie value to be used */
|
||||
|
@ -1973,8 +1973,36 @@ int backend_parse_balance(const char **args, char *err, int errlen, struct proxy
|
||||
curproxy->lbprm.algo |= BE_LB_ALGO_SH;
|
||||
}
|
||||
else if (!strcmp(args[0], "uri")) {
|
||||
int arg = 1;
|
||||
|
||||
curproxy->lbprm.algo &= ~BE_LB_ALGO;
|
||||
curproxy->lbprm.algo |= BE_LB_ALGO_UH;
|
||||
|
||||
while (*args[arg]) {
|
||||
if (!strcmp(args[arg], "len")) {
|
||||
if (!*args[arg+1] || (atoi(args[arg+1]) <= 0)) {
|
||||
snprintf(err, errlen, "'balance uri len' expects a positive integer (got '%s').", args[arg+1]);
|
||||
return -1;
|
||||
}
|
||||
curproxy->uri_len_limit = atoi(args[arg+1]);
|
||||
arg += 2;
|
||||
}
|
||||
else if (!strcmp(args[arg], "depth")) {
|
||||
if (!*args[arg+1] || (atoi(args[arg+1]) <= 0)) {
|
||||
snprintf(err, errlen, "'balance uri depth' expects a positive integer (got '%s').", args[arg+1]);
|
||||
return -1;
|
||||
}
|
||||
/* hint: we store the position of the ending '/' (depth+1) so
|
||||
* that we avoid a comparison while computing the hash.
|
||||
*/
|
||||
curproxy->uri_dirs_depth1 = atoi(args[arg+1]) + 1;
|
||||
arg += 2;
|
||||
}
|
||||
else {
|
||||
snprintf(err, errlen, "'balance uri' only accepts parameters 'len' and 'depth' (got '%s').", args[arg]);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!strcmp(args[0], "url_param")) {
|
||||
if (!*args[1]) {
|
||||
@ -1987,7 +2015,7 @@ int backend_parse_balance(const char **args, char *err, int errlen, struct proxy
|
||||
free(curproxy->url_param_name);
|
||||
curproxy->url_param_name = strdup(args[1]);
|
||||
curproxy->url_param_len = strlen(args[1]);
|
||||
if ( *args[2] ) {
|
||||
if (*args[2]) {
|
||||
if (strcmp(args[2], "check_post")) {
|
||||
snprintf(err, errlen, "'balance url_param' only accepts check_post modifier.");
|
||||
return -1;
|
||||
|
Loading…
Reference in New Issue
Block a user