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.
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
{
unsigned long hash = 0;
int c;
+ int slashes = 0;
if (px->lbprm.tot_weight == 0)
return NULL;
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;
}
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 */
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]) {
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;