return (void *) new;
}
+static int int_order(const void *i1, const void *i2)
+{
+ return *(const int *)i1 - *(const int *)i2;
+}
+
static void *merge_proxy_dir_config(apr_pool_t *p, void *basev, void *addv)
{
proxy_dir_conf *new = (proxy_dir_conf *) apr_pcalloc(p, sizeof(proxy_dir_conf));
= apr_array_append(p, base->cookie_domains, add->cookie_domains);
new->error_override_codes
= apr_array_append(p, base->error_override_codes, add->error_override_codes);
+ /* Keep the array sorted for binary search (since "base" and "add" are
+ * already sorted, it's only needed only if both are merged).
+ */
+ if (base->error_override_codes->nelts
+ && add->error_override_codes->nelts) {
+ qsort(new->error_override_codes->elts,
+ new->error_override_codes->nelts,
+ sizeof(int), int_order);
+ }
new->interpolate_env = (add->interpolate_env == -1) ? base->interpolate_env
: add->interpolate_env;
new->preserve_host = (add->preserve_host_set == 0) ? base->preserve_host
}
else if (conf->error_override_set == 1) {
int *newcode;
- int argcode;
+ int argcode, i;
if (!apr_isdigit(arg[0]))
return "ProxyErrorOverride: status codes to intercept must be numeric";
if (!conf->error_override)
newcode = apr_array_push(conf->error_override_codes);
*newcode = argcode;
+
+ /* Keep the array sorted for binary search. */
+ for (i = conf->error_override_codes->nelts - 1; i > 0; --i) {
+ int *oldcode = &((int *)conf->error_override_codes->elts)[i - 1];
+ if (*oldcode <= argcode) {
+ break;
+ }
+ *newcode = *oldcode;
+ *oldcode = argcode;
+ newcode = oldcode;
+ }
}
else
return "ProxyErrorOverride first parameter must be one of: off | on";
return lb_workers_limit;
}
-static int error_code_overridden(proxy_dir_conf *conf, int code)
+static APR_INLINE int error_code_overridden(const int *elts, int nelts,
+ int code)
{
- int i;
- int *list = (int *) conf->error_override_codes->elts;
+ int min = 0;
+ int max = nelts - 1;
+ AP_DEBUG_ASSERT(max >= 0);
- if (apr_is_empty_array(conf->error_override_codes))
- return 0;
+ while (min < max) {
+ int mid = (min + max) / 2;
+ int val = elts[mid];
- for (i = 0; i < conf->error_override_codes->nelts; i++) {
- if (code == list[i])
+ if (val < code) {
+ min = mid + 1;
+ }
+ else if (val > code) {
+ max = mid - 1;
+ }
+ else {
return 1;
+ }
}
- return 0;
+ return elts[min] == code;
}
PROXY_DECLARE(int) ap_proxy_should_override(proxy_dir_conf *conf, int code)
if (apr_is_empty_array(conf->error_override_codes))
return ap_is_HTTP_ERROR(code);
- return error_code_overridden(conf, code);
+ /* Since error_override_codes is sorted, apply binary search. */
+ return error_code_overridden((int *)conf->error_override_codes->elts,
+ conf->error_override_codes->nelts,
+ code);
}
/* deprecated - to be removed in v2.6 */