From: Stefan Fritsch Date: Sun, 7 Nov 2010 22:06:33 +0000 (+0000) Subject: Implement "reqenv", "note", "-z", "-n" in ap_expr. X-Git-Tag: 2.3.9~84 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6056703807266adac0064413280da73cf138781b;p=thirdparty%2Fapache%2Fhttpd.git Implement "reqenv", "note", "-z", "-n" in ap_expr. Make "env" ssl_expr compatible git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1032408 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/docs/manual/expr.xml b/docs/manual/expr.xml index a4d2594aa1c..56a7909564f 100644 --- a/docs/manual/expr.xml +++ b/docs/manual/expr.xml @@ -264,9 +264,9 @@ listfunction ::= listfuncname "(" word ")" NameDescription -n - String is not empty (XXX: not yet implemented) + String is not empty -z - String is empty (XXX: not yet implemented) + String is empty @@ -286,10 +286,15 @@ listfunction ::= listfuncname "(" word ")" Get HTTP request header resp Get HTTP response header + reqenv + Lookup request environment variable osenv Lookup operating system environment variable + note + Lookup request environment variable env - Lookup request environment variable (XXX: will need to be changed for better ssl_expr compat) + Reqturn first match of note, reqenv, + osenv tolower Convert string to lower case toupper diff --git a/server/util_expr_eval.c b/server/util_expr_eval.c index 153b2467d9b..2b80e73efb9 100644 --- a/server/util_expr_eval.c +++ b/server/util_expr_eval.c @@ -693,46 +693,55 @@ AP_DECLARE(int) ap_expr_exec(request_rec *r, const ap_expr_info_t *info, const c return (rc ? 1 : 0); } -static const char *req_func(ap_expr_eval_ctx *ctx, const char *name, - const char *arg) +static const char *req_table_func(ap_expr_eval_ctx *ctx, const void *data, + const char *arg) { - if (ctx->r) - return apr_table_get(ctx->r->headers_in, arg); - else + const char *name = (const char *)data; + apr_table_t *t; + if (!ctx->r) return ""; -} -static const char *resp_func(ap_expr_eval_ctx *ctx, const char *name, - const char *arg) -{ - if (ctx->r) - return apr_table_get(ctx->r->headers_out, arg); + if (name[3] == 's') /* resp */ + t = ctx->r->headers_out; + else if (name[4] == 'e') /* reqenv */ + t = ctx->r->subprocess_env; + else if (name[0] == 'n') /* notes */ + t = ctx->r->notes; else - return ""; + t = ctx->r->headers_in; + return apr_table_get(t, arg); } -static const char *env_func(ap_expr_eval_ctx *ctx, const char *name, +static const char *env_func(ap_expr_eval_ctx *ctx, const void *data, const char *arg) { - if (ctx->r) - return apr_table_get(ctx->r->subprocess_env, arg); - else - return ""; + const char *res; + /* this order is for ssl_expr compatibility */ + if (ctx->r) { + if ((res = apr_table_get(ctx->r->notes, arg)) != NULL) + return res; + else if ((res = apr_table_get(ctx->r->subprocess_env, arg)) != NULL) + return res; + } + return getenv(arg); } -static const char *osenv_func(ap_expr_eval_ctx *ctx, const char *name, const char *arg) +static const char *osenv_func(ap_expr_eval_ctx *ctx, const void *data, + const char *arg) { return getenv(arg); } -static const char *tolower_func(ap_expr_eval_ctx *ctx, const char *name, const char *arg) +static const char *tolower_func(ap_expr_eval_ctx *ctx, const void *data, + const char *arg) { char *result = apr_pstrdup(ctx->p, arg); ap_str_tolower(result); return result; } -static const char *toupper_func(ap_expr_eval_ctx *ctx, const char *name, const char *arg) +static const char *toupper_func(ap_expr_eval_ctx *ctx, const void *data, + const char *arg) { char *p; char *result = apr_pstrdup(ctx->p, arg); @@ -744,13 +753,14 @@ static const char *toupper_func(ap_expr_eval_ctx *ctx, const char *name, const c return result; } -static const char *escape_func(ap_expr_eval_ctx *ctx, const char *name, const char *arg) +static const char *escape_func(ap_expr_eval_ctx *ctx, const void *data, + const char *arg) { return ap_escape_uri(ctx->p, arg); } #define MAX_FILE_SIZE 10*1024*1024 -static const char *file_func(ap_expr_eval_ctx *ctx, const char *name, char *arg) +static const char *file_func(ap_expr_eval_ctx *ctx, const void *data, char *arg) { apr_file_t *fp; char *buf; @@ -794,7 +804,8 @@ static const char *file_func(ap_expr_eval_ctx *ctx, const char *name, char *arg) } -static const char *unescape_func(ap_expr_eval_ctx *ctx, const char *name, const char *arg) +static const char *unescape_func(ap_expr_eval_ctx *ctx, const void *data, + const char *arg) { char *result = apr_pstrdup(ctx->p, arg); if (ap_unescape_url(result)) @@ -804,6 +815,15 @@ static const char *unescape_func(ap_expr_eval_ctx *ctx, const char *name, const } +static int op_nz(ap_expr_eval_ctx *ctx, const void *data, const char *arg) +{ + const char *name = (const char *)data; + if (name[0] == 'z') + return (arg[0] == '\0'); + else + return (arg[0] != '\0'); +} + APR_DECLARE_OPTIONAL_FN(int, ssl_is_https, (conn_rec *)); static APR_OPTIONAL_FN_TYPE(ssl_is_https) *is_https = NULL; @@ -1025,10 +1045,11 @@ static const struct expr_provider_multi var_providers[] = { static const struct expr_provider_single string_func_providers[] = { { osenv_func, "osenv" }, { env_func, "env" }, - { resp_func, "resp" }, - { req_func, "req" }, + { req_table_func, "resp" }, + { req_table_func, "req" }, /* 'http' as alias for 'req' for compatibility with ssl_expr */ - { req_func, "http" }, + { req_table_func, "http" }, + { req_table_func, "note" }, { tolower_func, "tolower" }, { toupper_func, "toupper" }, { escape_func, "escape" }, @@ -1038,6 +1059,11 @@ static const struct expr_provider_single string_func_providers[] = { }; /* XXX: base64 encode/decode ? */ +static const struct expr_provider_single unary_op_providers[] = { + { op_nz, "n" }, + { op_nz, "z" }, + { NULL, NULL} +}; static int core_expr_lookup(ap_expr_lookup_parms *parms) { switch (parms->type) { @@ -1069,6 +1095,18 @@ static int core_expr_lookup(ap_expr_lookup_parms *parms) } break; } + case AP_EXPR_FUNC_OP_UNARY: { + const struct expr_provider_single *prov = unary_op_providers; + while (prov->func) { + if (strcasecmp(prov->name, parms->name) == 0) { + *parms->func = prov->func; + *parms->data = prov->name; + return OK; + } + prov++; + } + break; + } default: break; }