Commit 6b121669 authored by Stefan Fritsch's avatar Stefan Fritsch
Browse files

Add various file existance test operators to ap_expr


git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1103097 13f79535-47bb-0310-9956-ffa450edef68
parent 9cb18db5
Loading
Loading
Loading
Loading
+3 −0
Changes for CHANGES: 3 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -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]

+16 −4
Changes for docs/manual/expr.html.en: 16 added lines, 4 removed lines.
Original line number Diff line number Diff line
@@ -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>
@@ -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
+13 −0
Changes for docs/manual/expr.xml: 13 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -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>
@@ -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
+62 −0
Changes for server/util_expr_eval.c: 62 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -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)
@@ -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;

@@ -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 ? */
@@ -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 }
};