Loading CHANGES +3 −0 Changes for CHANGES: 3 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -2,6 +2,9 @@ Changes with Apache 2.3.13 *) core: Add various file existance test operators to ap_expr. [Stefan Fritsch] *) mod_proxy_express: New mass reverse-proxy switch extension for mod_proxy. [Jim Jagielski] Loading docs/manual/expr.html.en +16 −4 Changes for docs/manual/expr.html.en: 16 added lines, 4 removed lines. Original line number Diff line number Diff line Loading @@ -324,15 +324,25 @@ listfunction ::= listfuncname "<strong>(</strong>" word "<strong>)</strong>" Modules may register additional unary operators.</p> <table class="bordered"><tr class="header"><th>Name</th><th>Description</th></tr> <tr><td><code>-n</code></td> <tr><td><code>-d</code></td> <td>True if file exists and is a directory</td></tr> <tr class="odd"><td><code>-e</code></td> <td>True if file (or dir or special) exists</td></tr> <tr><td><code>-f</code></td> <td>True if file exists and is regular file</td></tr> <tr class="odd"><td><code>-L</code></td> <td>True if file exists and is symlink</td></tr> <tr><td><code>-h</code></td> <td>True if file exists and is symlink (same as <code>-L</code>)</td></tr> <tr class="odd"><td><code>-n</code></td> <td>True if string is not empty</td></tr> <tr class="odd"><td><code>-z</code></td> <tr><td><code>-z</code></td> <td>True if string is empty</td></tr> <tr><td><code>-T</code></td> <tr class="odd"><td><code>-T</code></td> <td>False if string is empty, "<code>0</code>", "<code>off</code>", "<code>false</code>", or "<code>no</code>" (case insensitive). True otherwise.</td></tr> <tr class="odd"><td><code>-R</code></td> <tr><td><code>-R</code></td> <td>Same as "<code>%{REMOTE_ADDR} -ipmatch ...</code>", but more efficient </td></tr> </table> Loading Loading @@ -370,6 +380,8 @@ listfunction ::= listfuncname "<strong>(</strong>" word "<strong>)</strong>" <td>Unescape %hex encoded string, leaving URL-special characters encoded (XXX: describe better)</td></tr> <tr><td><code>file</code></td> <td>Read contents from a file</td></tr> <tr class="odd"><td><code>filesize</code></td> <td>Return size of a file (or 0 if file does not exist or is not regular file)</td></tr> </table> <p>In addition to string-valued functions, there are also list-valued functions which Loading docs/manual/expr.xml +13 −0 Changes for docs/manual/expr.xml: 13 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -347,6 +347,16 @@ listfunction ::= listfuncname "<strong>(</strong>" word "<strong>)</strong>" <columnspec><column width=".2"/><column width=".2"/><column width=".6"/></columnspec> <tr><th>Name</th><th>Description</th></tr> <tr><td><code>-d</code></td> <td>True if file exists and is a directory</td></tr> <tr><td><code>-e</code></td> <td>True if file (or dir or special) exists</td></tr> <tr><td><code>-f</code></td> <td>True if file exists and is regular file</td></tr> <tr><td><code>-L</code></td> <td>True if file exists and is symlink</td></tr> <tr><td><code>-h</code></td> <td>True if file exists and is symlink (same as <code>-L</code>)</td></tr> <tr><td><code>-n</code></td> <td>True if string is not empty</td></tr> <tr><td><code>-z</code></td> Loading Loading @@ -396,6 +406,9 @@ listfunction ::= listfuncname "<strong>(</strong>" word "<strong>)</strong>" <td>Unescape %hex encoded string, leaving URL-special characters encoded (XXX: describe better)</td></tr> <tr><td><code>file</code></td> <td>Read contents from a file</td></tr> <tr><td><code>filesize</code></td> <td>Return size of a file (or 0 if file does not exist or is not regular file)</td></tr> </table> <p>In addition to string-valued functions, there are also list-valued functions which Loading server/util_expr_eval.c +62 −0 Changes for server/util_expr_eval.c: 62 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -872,6 +872,16 @@ static const char *file_func(ap_expr_eval_ctx_t *ctx, const void *data, return buf; } static const char *filesize_func(ap_expr_eval_ctx_t *ctx, const void *data, char *arg) { apr_finfo_t sb; if (apr_stat(&sb, arg, APR_FINFO_MIN, ctx->p) == APR_SUCCESS && sb.filetype == APR_REG && sb.size > 0) return apr_psprintf(ctx->p, "%" APR_OFF_T_FMT, sb.size); else return "0"; } static const char *unescape_func(ap_expr_eval_ctx_t *ctx, const void *data, const char *arg) Loading @@ -893,6 +903,50 @@ static int op_nz(ap_expr_eval_ctx_t *ctx, const void *data, const char *arg) return (arg[0] != '\0'); } static int op_file_min(ap_expr_eval_ctx_t *ctx, const void *data, const char *arg) { apr_finfo_t sb; const char *name = (const char *)data; if (apr_stat(&sb, arg, APR_FINFO_MIN, ctx->p) != APR_SUCCESS) return 0; switch (name[0]) { case 'd': return (sb.filetype == APR_DIR); case 'e': return 1; case 'f': return (sb.filetype == APR_REG); case 's': return (sb.filetype == APR_REG && sb.size > 0); default: ap_assert(0); } return 0; } static int op_file_link(ap_expr_eval_ctx_t *ctx, const void *data, const char *arg) { apr_finfo_t sb; #if !defined(OS2) if (apr_stat(&sb, arg, APR_FINFO_MIN | APR_FINFO_LINK, ctx->p) == APR_SUCCESS && sb.filetype == APR_LNK) { return 1; } #endif return 0; } static int op_file_xbit(ap_expr_eval_ctx_t *ctx, const void *data, const char *arg) { apr_finfo_t sb; if (apr_stat(&sb, arg, APR_FINFO_PROT| APR_FINFO_LINK, ctx->p) == APR_SUCCESS && (sb.protection & (APR_UEXECUTE | APR_GEXECUTE | APR_WEXECUTE))) { return 1; } return 0; } APR_DECLARE_OPTIONAL_FN(int, ssl_is_https, (conn_rec *)); static APR_OPTIONAL_FN_TYPE(ssl_is_https) *is_https = NULL; Loading Loading @@ -1255,6 +1309,7 @@ static const struct expr_provider_single string_func_providers[] = { { escape_func, "escape", NULL }, { unescape_func, "unescape", NULL }, { file_func, "file", NULL }, { filesize_func, "filesize", NULL }, { NULL, NULL, NULL} }; /* XXX: base64 encode/decode ? */ Loading @@ -1264,6 +1319,13 @@ static const struct expr_provider_single unary_op_providers[] = { { op_nz, "z", NULL }, { op_R, "R", subnet_parse_arg }, { op_T, "T", NULL }, { op_file_min, "d", NULL }, { op_file_min, "e", NULL }, { op_file_min, "f", NULL }, { op_file_min, "s", NULL }, { op_file_link, "L", NULL }, { op_file_link, "h", NULL }, { op_file_xbit, "x", NULL }, { NULL, NULL, NULL } }; Loading Loading
CHANGES +3 −0 Changes for CHANGES: 3 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -2,6 +2,9 @@ Changes with Apache 2.3.13 *) core: Add various file existance test operators to ap_expr. [Stefan Fritsch] *) mod_proxy_express: New mass reverse-proxy switch extension for mod_proxy. [Jim Jagielski] Loading
docs/manual/expr.html.en +16 −4 Changes for docs/manual/expr.html.en: 16 added lines, 4 removed lines. Original line number Diff line number Diff line Loading @@ -324,15 +324,25 @@ listfunction ::= listfuncname "<strong>(</strong>" word "<strong>)</strong>" Modules may register additional unary operators.</p> <table class="bordered"><tr class="header"><th>Name</th><th>Description</th></tr> <tr><td><code>-n</code></td> <tr><td><code>-d</code></td> <td>True if file exists and is a directory</td></tr> <tr class="odd"><td><code>-e</code></td> <td>True if file (or dir or special) exists</td></tr> <tr><td><code>-f</code></td> <td>True if file exists and is regular file</td></tr> <tr class="odd"><td><code>-L</code></td> <td>True if file exists and is symlink</td></tr> <tr><td><code>-h</code></td> <td>True if file exists and is symlink (same as <code>-L</code>)</td></tr> <tr class="odd"><td><code>-n</code></td> <td>True if string is not empty</td></tr> <tr class="odd"><td><code>-z</code></td> <tr><td><code>-z</code></td> <td>True if string is empty</td></tr> <tr><td><code>-T</code></td> <tr class="odd"><td><code>-T</code></td> <td>False if string is empty, "<code>0</code>", "<code>off</code>", "<code>false</code>", or "<code>no</code>" (case insensitive). True otherwise.</td></tr> <tr class="odd"><td><code>-R</code></td> <tr><td><code>-R</code></td> <td>Same as "<code>%{REMOTE_ADDR} -ipmatch ...</code>", but more efficient </td></tr> </table> Loading Loading @@ -370,6 +380,8 @@ listfunction ::= listfuncname "<strong>(</strong>" word "<strong>)</strong>" <td>Unescape %hex encoded string, leaving URL-special characters encoded (XXX: describe better)</td></tr> <tr><td><code>file</code></td> <td>Read contents from a file</td></tr> <tr class="odd"><td><code>filesize</code></td> <td>Return size of a file (or 0 if file does not exist or is not regular file)</td></tr> </table> <p>In addition to string-valued functions, there are also list-valued functions which Loading
docs/manual/expr.xml +13 −0 Changes for docs/manual/expr.xml: 13 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -347,6 +347,16 @@ listfunction ::= listfuncname "<strong>(</strong>" word "<strong>)</strong>" <columnspec><column width=".2"/><column width=".2"/><column width=".6"/></columnspec> <tr><th>Name</th><th>Description</th></tr> <tr><td><code>-d</code></td> <td>True if file exists and is a directory</td></tr> <tr><td><code>-e</code></td> <td>True if file (or dir or special) exists</td></tr> <tr><td><code>-f</code></td> <td>True if file exists and is regular file</td></tr> <tr><td><code>-L</code></td> <td>True if file exists and is symlink</td></tr> <tr><td><code>-h</code></td> <td>True if file exists and is symlink (same as <code>-L</code>)</td></tr> <tr><td><code>-n</code></td> <td>True if string is not empty</td></tr> <tr><td><code>-z</code></td> Loading Loading @@ -396,6 +406,9 @@ listfunction ::= listfuncname "<strong>(</strong>" word "<strong>)</strong>" <td>Unescape %hex encoded string, leaving URL-special characters encoded (XXX: describe better)</td></tr> <tr><td><code>file</code></td> <td>Read contents from a file</td></tr> <tr><td><code>filesize</code></td> <td>Return size of a file (or 0 if file does not exist or is not regular file)</td></tr> </table> <p>In addition to string-valued functions, there are also list-valued functions which Loading
server/util_expr_eval.c +62 −0 Changes for server/util_expr_eval.c: 62 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -872,6 +872,16 @@ static const char *file_func(ap_expr_eval_ctx_t *ctx, const void *data, return buf; } static const char *filesize_func(ap_expr_eval_ctx_t *ctx, const void *data, char *arg) { apr_finfo_t sb; if (apr_stat(&sb, arg, APR_FINFO_MIN, ctx->p) == APR_SUCCESS && sb.filetype == APR_REG && sb.size > 0) return apr_psprintf(ctx->p, "%" APR_OFF_T_FMT, sb.size); else return "0"; } static const char *unescape_func(ap_expr_eval_ctx_t *ctx, const void *data, const char *arg) Loading @@ -893,6 +903,50 @@ static int op_nz(ap_expr_eval_ctx_t *ctx, const void *data, const char *arg) return (arg[0] != '\0'); } static int op_file_min(ap_expr_eval_ctx_t *ctx, const void *data, const char *arg) { apr_finfo_t sb; const char *name = (const char *)data; if (apr_stat(&sb, arg, APR_FINFO_MIN, ctx->p) != APR_SUCCESS) return 0; switch (name[0]) { case 'd': return (sb.filetype == APR_DIR); case 'e': return 1; case 'f': return (sb.filetype == APR_REG); case 's': return (sb.filetype == APR_REG && sb.size > 0); default: ap_assert(0); } return 0; } static int op_file_link(ap_expr_eval_ctx_t *ctx, const void *data, const char *arg) { apr_finfo_t sb; #if !defined(OS2) if (apr_stat(&sb, arg, APR_FINFO_MIN | APR_FINFO_LINK, ctx->p) == APR_SUCCESS && sb.filetype == APR_LNK) { return 1; } #endif return 0; } static int op_file_xbit(ap_expr_eval_ctx_t *ctx, const void *data, const char *arg) { apr_finfo_t sb; if (apr_stat(&sb, arg, APR_FINFO_PROT| APR_FINFO_LINK, ctx->p) == APR_SUCCESS && (sb.protection & (APR_UEXECUTE | APR_GEXECUTE | APR_WEXECUTE))) { return 1; } return 0; } APR_DECLARE_OPTIONAL_FN(int, ssl_is_https, (conn_rec *)); static APR_OPTIONAL_FN_TYPE(ssl_is_https) *is_https = NULL; Loading Loading @@ -1255,6 +1309,7 @@ static const struct expr_provider_single string_func_providers[] = { { escape_func, "escape", NULL }, { unescape_func, "unescape", NULL }, { file_func, "file", NULL }, { filesize_func, "filesize", NULL }, { NULL, NULL, NULL} }; /* XXX: base64 encode/decode ? */ Loading @@ -1264,6 +1319,13 @@ static const struct expr_provider_single unary_op_providers[] = { { op_nz, "z", NULL }, { op_R, "R", subnet_parse_arg }, { op_T, "T", NULL }, { op_file_min, "d", NULL }, { op_file_min, "e", NULL }, { op_file_min, "f", NULL }, { op_file_min, "s", NULL }, { op_file_link, "L", NULL }, { op_file_link, "h", NULL }, { op_file_xbit, "x", NULL }, { NULL, NULL, NULL } }; Loading