From: Stefan Fritsch Date: Sat, 14 May 2011 15:12:33 +0000 (+0000) Subject: Also add the -U and -F operators for doing subrequest lookups to ap_expr. X-Git-Tag: 2.3.13~140 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=a88e191cd578b8d765fb199d34618ddb7d2428bf;p=apache Also add the -U and -F operators for doing subrequest lookups to ap_expr. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1103126 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/docs/manual/expr.html.en b/docs/manual/expr.html.en index f0e9c20775..f2e0f95cf2 100644 --- a/docs/manual/expr.html.en +++ b/docs/manual/expr.html.en @@ -319,21 +319,38 @@ listfunction ::= listfuncname "(" word ")"

Unary operators

-

Unary operators have the form "-[a-zA-Z]", i.e. a - minus and one character. The name is case sensitive. +

Unary operators take one argument and have the form + "-[a-zA-Z]", i.e. a minus and one character. + The name is case sensitive. Modules may register additional unary operators.

- + - + - + - + - + + + + + diff --git a/docs/manual/expr.xml b/docs/manual/expr.xml index bc2604e82c..d61f21dc3f 100644 --- a/docs/manual/expr.xml +++ b/docs/manual/expr.xml @@ -339,8 +339,9 @@ listfunction ::= listfuncname "(" word ")"
Unary operators -

Unary operators have the form "-[a-zA-Z]", i.e. a - minus and one character. The name is case sensitive. +

Unary operators take one argument and have the form + "-[a-zA-Z]", i.e. a minus and one character. + The name is case sensitive. Modules may register additional unary operators.

NameDescription
-dTrue if file exists and is a directory
The argument is treated as a filename. + True if the file exists and is a directory
-eTrue if file (or dir or special) exists
The argument is treated as a filename. + True if the file (or dir or special) exists
-fTrue if file exists and is regular file
The argument is treated as a filename. + True if the file exists and is regular file
-LTrue if file exists and is symlink
The argument is treated as a filename. + True if the file exists and is symlink
-hTrue if file exists and is symlink (same as -L)
The argument is treated as a filename. + True if the file exists and is symlink + (same as -L)
-FTrue if string is a valid file, accessible via all the server's + currently-configured access controls for that path. This uses an + internal subrequest to do the check, so use it with care - it can + impact your server's performance!
-UTrue if string is a valid URL, accessible via all the server's + currently-configured access controls for that path. This uses an + internal subrequest to do the check, so use it with care - it can + impact your server's performance!
-n True if string is not empty
-z
@@ -348,15 +349,31 @@ listfunction ::= listfuncname "(" word ")" - + - + - + - + - + + + + + diff --git a/server/util_expr_eval.c b/server/util_expr_eval.c index 57a328b18f..96c489d781 100644 --- a/server/util_expr_eval.c +++ b/server/util_expr_eval.c @@ -22,6 +22,7 @@ #include "http_log.h" #include "http_core.h" #include "http_protocol.h" +#include "http_request.h" #include "ap_provider.h" #include "util_expr_private.h" @@ -37,6 +38,8 @@ APR_HOOK_STRUCT( AP_IMPLEMENT_HOOK_RUN_FIRST(int, expr_lookup, (ap_expr_lookup_parms *parms), (parms), DECLINED) +#define LOG_MARK(info) __FILE__, __LINE__, (info)->module_index + static const char *ap_expr_eval_string_func(ap_expr_eval_ctx_t *ctx, const ap_expr_t *info, const ap_expr_t *args); @@ -722,14 +725,14 @@ AP_DECLARE(int) ap_expr_exec_re(request_rec *r, const ap_expr_info_t *info, *err = NULL; rc = ap_expr_eval(&ctx, info->root_node); if (*err != NULL) { - ap_log_rerror(__FILE__, __LINE__, info->module_index, APLOG_ERR, 0, - r, "Evaluation of expression from %s:%d failed: %s", + ap_log_rerror(LOG_MARK(info), APLOG_ERR, 0, r, + "Evaluation of expression from %s:%d failed: %s", info->filename, info->line_number, *err); return -1; } else { rc = rc ? 1 : 0; - ap_log_rerror(__FILE__, __LINE__, info->module_index, APLOG_TRACE4, 0, - r, "Evaluation of expression from %s:%d gave: %d", + ap_log_rerror(LOG_MARK(info), APLOG_TRACE4, 0, r, + "Evaluation of expression from %s:%d gave: %d", info->filename, info->line_number, rc); if (vary_this) @@ -946,6 +949,49 @@ static int op_file_xbit(ap_expr_eval_ctx_t *ctx, const void *data, const char *a return 0; } +static int op_url_subr(ap_expr_eval_ctx_t *ctx, const void *data, const char *arg) +{ + int rc = 0; + request_rec *rsub, *r = ctx->r; + if (!r) + return 0; + /* avoid some infinite recursions */ + if (r->main && r->main->uri && r->uri && strcmp(r->main->uri, r->uri) == 0) + return 0; + + rsub = ap_sub_req_lookup_uri(arg, r, NULL); + if (rsub->status < 400) { + rc = 1; + } + ap_log_rerror(LOG_MARK(ctx->info), APLOG_TRACE5, 0, r, + "Subrequest for -U %s at %s:%d gave status: %d", + arg, ctx->info->filename, ctx->info->line_number, + rsub->status); + ap_destroy_sub_req(rsub); + return rc; +} + +static int op_file_subr(ap_expr_eval_ctx_t *ctx, const void *data, const char *arg) +{ + int rc = 0; + apr_finfo_t sb; + request_rec *rsub, *r = ctx->r; + if (!r) + return 0; + rsub = ap_sub_req_lookup_file(arg, r, NULL); + if (rsub->status < 300 && + /* double-check that file exists since default result is 200 */ + apr_stat(&sb, rsub->filename, APR_FINFO_MIN, ctx->p) == APR_SUCCESS) { + rc = 1; + } + ap_log_rerror(LOG_MARK(ctx->info), APLOG_TRACE5, 0, r, + "Subrequest for -F %s at %s:%d gave status: %d", + arg, ctx->info->filename, ctx->info->line_number, + rsub->status); + ap_destroy_sub_req(rsub); + return rc; +} + APR_DECLARE_OPTIONAL_FN(int, ssl_is_https, (conn_rec *)); static APR_OPTIONAL_FN_TYPE(ssl_is_https) *is_https = NULL; @@ -1326,6 +1372,8 @@ static const struct expr_provider_single unary_op_providers[] = { { op_file_link, "L", NULL }, { op_file_link, "h", NULL }, { op_file_xbit, "x", NULL }, + { op_file_subr, "F", NULL }, + { op_url_subr, "U", NULL }, { NULL, NULL, NULL } };
NameDescription
-dTrue if file exists and is a directory
The argument is treated as a filename. + True if the file exists and is a directory
-eTrue if file (or dir or special) exists
The argument is treated as a filename. + True if the file (or dir or special) exists
-fTrue if file exists and is regular file
The argument is treated as a filename. + True if the file exists and is regular file
-LTrue if file exists and is symlink
The argument is treated as a filename. + True if the file exists and is symlink
-hTrue if file exists and is symlink (same as -L)
The argument is treated as a filename. + True if the file exists and is symlink + (same as -L)
-FTrue if string is a valid file, accessible via all the server's + currently-configured access controls for that path. This uses an + internal subrequest to do the check, so use it with care - it can + impact your server's performance!
-UTrue if string is a valid URL, accessible via all the server's + currently-configured access controls for that path. This uses an + internal subrequest to do the check, so use it with care - it can + impact your server's performance!
-n True if string is not empty
-z