1/* Licensed to the Apache Software Foundation (ASF) under one or more 2 * contributor license agreements. See the NOTICE file distributed with 3 * this work for additional information regarding copyright ownership. 4 * The ASF licenses this file to You under the Apache License, Version 2.0 5 * (the "License"); you may not use this file except in compliance with 6 * the License. You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17/** 18 * @file ap_expr.h 19 * @brief Expression parser 20 * 21 * @defgroup AP_EXPR Expression parser 22 * @ingroup APACHE_CORE 23 * @{ 24 */ 25 26#ifndef AP_EXPR_H 27#define AP_EXPR_H 28 29#include "httpd.h" 30#include "http_config.h" 31#include "ap_regex.h" 32 33#ifdef __cplusplus 34extern "C" { 35#endif 36 37/** A node in the expression parse tree */ 38typedef struct ap_expr_node ap_expr_t; 39 40/** Struct describing a parsed expression */ 41typedef struct { 42 /** The root of the actual expression parse tree */ 43 ap_expr_t *root_node; 44 /** The filename where the expression has been defined (for logging). 45 * May be NULL 46 */ 47 const char *filename; 48 /** The line number where the expression has been defined (for logging). */ 49 unsigned int line_number; 50 /** Flags relevant for the expression, see AP_EXPR_FLAG_* */ 51 unsigned int flags; 52 /** The module that is used for loglevel configuration */ 53 int module_index; 54} ap_expr_info_t; 55 56/** Use ssl_expr compatibility mode (changes the meaning of the comparison 57 * operators) 58 */ 59#define AP_EXPR_FLAG_SSL_EXPR_COMPAT 1 60/** Don't add siginificant request headers to the Vary response header */ 61#define AP_EXPR_FLAG_DONT_VARY 2 62/** Don't allow functions/vars that bypass the current request's access 63 * restrictions or would otherwise leak confidential information. 64 * Used by e.g. mod_include. 65 */ 66#define AP_EXPR_FLAG_RESTRICTED 4 67/** Expression evaluates to a string, not to a bool */ 68#define AP_EXPR_FLAG_STRING_RESULT 8 69 70 71/** 72 * Evaluate a parse tree, simple interface 73 * @param r The current request 74 * @param expr The expression to be evaluated 75 * @param err Where an error message should be stored 76 * @return > 0 if expression evaluates to true, == 0 if false, < 0 on error 77 * @note err will be set to NULL on success, or to an error message on error 78 * @note request headers used during evaluation will be added to the Vary: 79 * response header, unless ::AP_EXPR_FLAG_DONT_VARY is set. 80 */ 81AP_DECLARE(int) ap_expr_exec(request_rec *r, const ap_expr_info_t *expr, 82 const char **err); 83 84/** 85 * Evaluate a parse tree, with access to regexp backreference 86 * @param r The current request 87 * @param expr The expression to be evaluated 88 * @param nmatch size of the regex match vector pmatch 89 * @param pmatch information about regex matches 90 * @param source the string that pmatch applies to 91 * @param err Where an error message should be stored 92 * @return > 0 if expression evaluates to true, == 0 if false, < 0 on error 93 * @note err will be set to NULL on success, or to an error message on error 94 * @note nmatch/pmatch/source can be used both to make previous matches 95 * available to ap_expr_exec_re and to use ap_expr_exec_re's matches 96 * later on. 97 * @note request headers used during evaluation will be added to the Vary: 98 * response header, unless ::AP_EXPR_FLAG_DONT_VARY is set. 99 */ 100AP_DECLARE(int) ap_expr_exec_re(request_rec *r, const ap_expr_info_t *expr, 101 apr_size_t nmatch, ap_regmatch_t *pmatch, 102 const char **source, const char **err); 103 104/** Context used during evaluation of a parse tree, created by ap_expr_exec */ 105typedef struct { 106 /** the current request */ 107 request_rec *r; 108 /** the current connection */ 109 conn_rec *c; 110 /** the current virtual host */ 111 server_rec *s; 112 /** the pool to use */ 113 apr_pool_t *p; 114 /** where to store the error string */ 115 const char **err; 116 /** ap_expr_info_t for the expression */ 117 const ap_expr_info_t *info; 118 /** regex match information for back references */ 119 ap_regmatch_t *re_pmatch; 120 /** size of the vector pointed to by re_pmatch */ 121 apr_size_t re_nmatch; 122 /** the string corresponding to the re_pmatch */ 123 const char **re_source; 124 /** A string where the comma separated names of headers are stored 125 * to be later added to the Vary: header. If NULL, the caller is not 126 * interested in this information. 127 */ 128 const char **vary_this; 129 /** where to store the result string */ 130 const char **result_string; 131 /** Arbitrary context data provided by the caller for custom functions */ 132 void *data; 133 /** The current recursion level */ 134 int reclvl; 135} ap_expr_eval_ctx_t; 136 137/** 138 * Evaluate a parse tree, full featured version 139 * @param ctx The evaluation context with all data filled in 140 * @return > 0 if expression evaluates to true, == 0 if false, < 0 on error 141 * @note *ctx->err will be set to NULL on success, or to an error message on 142 * error 143 * @note request headers used during evaluation will be added to the Vary: 144 * response header if ctx->vary_this is set. 145 */ 146AP_DECLARE(int) ap_expr_exec_ctx(ap_expr_eval_ctx_t *ctx); 147 148/** 149 * Evaluate a parse tree of a string valued expression 150 * @param r The current request 151 * @param expr The expression to be evaluated 152 * @param err Where an error message should be stored 153 * @return The result string, NULL on error 154 * @note err will be set to NULL on success, or to an error message on error 155 * @note request headers used during evaluation will be added to the Vary: 156 * response header, unless ::AP_EXPR_FLAG_DONT_VARY is set. 157 */ 158AP_DECLARE(const char *) ap_expr_str_exec(request_rec *r, 159 const ap_expr_info_t *expr, 160 const char **err); 161 162/** 163 * Evaluate a parse tree of a string valued expression 164 * @param r The current request 165 * @param expr The expression to be evaluated 166 * @param nmatch size of the regex match vector pmatch 167 * @param pmatch information about regex matches 168 * @param source the string that pmatch applies to 169 * @param err Where an error message should be stored 170 * @return The result string, NULL on error 171 * @note err will be set to NULL on success, or to an error message on error 172 * @note nmatch/pmatch/source can be used both to make previous matches 173 * available to ap_expr_exec_re and to use ap_expr_exec_re's matches 174 * later on. 175 * @note request headers used during evaluation will be added to the Vary: 176 * response header, unless ::AP_EXPR_FLAG_DONT_VARY is set. 177 */ 178AP_DECLARE(const char *) ap_expr_str_exec_re(request_rec *r, 179 const ap_expr_info_t *expr, 180 apr_size_t nmatch, 181 ap_regmatch_t *pmatch, 182 const char **source, 183 const char **err); 184 185 186/** 187 * The parser can be extended with variable lookup, functions, and 188 * and operators. 189 * 190 * During parsing, the parser calls the lookup function to resolve a 191 * name into a function pointer and an opaque context for the function. 192 * If the argument to a function or operator is constant, the lookup function 193 * may also parse that argument and store the parsed data in the context. 194 * 195 * The default lookup function is the hook ::ap_expr_lookup_default which just 196 * calls ap_run_expr_lookup. Modules can use it to make functions and 197 * variables generally available. 198 * 199 * An ap_expr consumer can also provide its own custom lookup function to 200 * modify the set of variables and functions that are available. The custom 201 * lookup function can in turn call 'ap_run_expr_lookup'. 202 */ 203 204/** Unary operator, takes one string argument and returns a bool value. 205 * The name must have the form '-z' (one letter only). 206 * @param ctx The evaluation context 207 * @param data An opaque context provided by the lookup hook function 208 * @param arg The (right) operand 209 * @return 0 or 1 210 */ 211typedef int ap_expr_op_unary_t(ap_expr_eval_ctx_t *ctx, const void *data, 212 const char *arg); 213 214/** Binary operator, takes two string arguments and returns a bool value. 215 * The name must have the form '-cmp' (at least two letters). 216 * @param ctx The evaluation context 217 * @param data An opaque context provided by the lookup hook function 218 * @param arg1 The left operand 219 * @param arg2 The right operand 220 * @return 0 or 1 221 */ 222typedef int ap_expr_op_binary_t(ap_expr_eval_ctx_t *ctx, const void *data, 223 const char *arg1, const char *arg2); 224 225/** String valued function, takes a string argument and returns a string 226 * @param ctx The evaluation context 227 * @param data An opaque context provided by the lookup hook function 228 * @param arg The argument 229 * @return The functions result string, may be NULL for 'empty string' 230 */ 231typedef const char *(ap_expr_string_func_t)(ap_expr_eval_ctx_t *ctx, 232 const void *data, 233 const char *arg); 234 235/** List valued function, takes a string argument and returns a list of strings 236 * Can currently only be called following the builtin '-in' operator. 237 * @param ctx The evaluation context 238 * @param data An opaque context provided by the lookup hook function 239 * @param arg The argument 240 * @return The functions result list of strings, may be NULL for 'empty array' 241 */ 242typedef apr_array_header_t *(ap_expr_list_func_t)(ap_expr_eval_ctx_t *ctx, 243 const void *data, 244 const char *arg); 245 246/** Variable lookup function, takes no argument and returns a string 247 * @param ctx The evaluation context 248 * @param data An opaque context provided by the lookup hook function 249 * @return The expanded variable 250 */ 251typedef const char *(ap_expr_var_func_t)(ap_expr_eval_ctx_t *ctx, 252 const void *data); 253 254/** parameter struct passed to the lookup hook functions */ 255typedef struct { 256 /** type of the looked up object */ 257 int type; 258#define AP_EXPR_FUNC_VAR 0 259#define AP_EXPR_FUNC_STRING 1 260#define AP_EXPR_FUNC_LIST 2 261#define AP_EXPR_FUNC_OP_UNARY 3 262#define AP_EXPR_FUNC_OP_BINARY 4 263 /** name of the looked up object */ 264 const char *name; 265 266 int flags; 267 268 apr_pool_t *pool; 269 apr_pool_t *ptemp; 270 271 /** where to store the function pointer */ 272 const void **func; 273 /** where to store the function's context */ 274 const void **data; 275 /** where to store the error message (if any) */ 276 const char **err; 277 278 /** arg for pre-parsing (only if a simple string). 279 * For binary ops, this is the right argument. */ 280 const char *arg; 281} ap_expr_lookup_parms; 282 283/** Function for looking up the provider function for a variable, operator 284 * or function in an expression. 285 * @param parms The parameter struct, also determins where the result is 286 * stored. 287 * @return OK on success, 288 * !OK on failure, 289 * DECLINED if the requested name is not handled by this function 290 */ 291typedef int (ap_expr_lookup_fn_t)(ap_expr_lookup_parms *parms); 292 293/** Default lookup function which just calls ap_run_expr_lookup(). 294 * ap_run_expr_lookup cannot be used directly because it has the wrong 295 * calling convention under Windows. 296 */ 297AP_DECLARE_NONSTD(int) ap_expr_lookup_default(ap_expr_lookup_parms *parms); 298 299AP_DECLARE_HOOK(int, expr_lookup, (ap_expr_lookup_parms *parms)) 300 301/** 302 * Parse an expression into a parse tree 303 * @param pool Pool 304 * @param ptemp temp pool 305 * @param info The ap_expr_info_t struct (with values filled in) 306 * @param expr The expression string to parse 307 * @param lookup_fn The lookup function to use, NULL for default 308 * @return NULL on success, error message on error. 309 * A pointer to the resulting parse tree will be stored in 310 * info->root_node. 311 */ 312AP_DECLARE(const char *) ap_expr_parse(apr_pool_t *pool, apr_pool_t *ptemp, 313 ap_expr_info_t *info, const char *expr, 314 ap_expr_lookup_fn_t *lookup_fn); 315 316/** 317 * High level interface to ap_expr_parse that also creates ap_expr_info_t and 318 * uses info from cmd_parms to fill in most of it. 319 * @param cmd The cmd_parms struct 320 * @param expr The expression string to parse 321 * @param flags The flags to use, see AP_EXPR_FLAG_* 322 * @param err Set to NULL on success, error message on error 323 * @param lookup_fn The lookup function used to lookup vars, functions, and 324 * operators 325 * @param module_index The module_index to set for the expression 326 * @return The parsed expression 327 * @note Usually ap_expr_parse_cmd() should be used 328 */ 329AP_DECLARE(ap_expr_info_t *) ap_expr_parse_cmd_mi(const cmd_parms *cmd, 330 const char *expr, 331 unsigned int flags, 332 const char **err, 333 ap_expr_lookup_fn_t *lookup_fn, 334 int module_index); 335 336/** 337 * Convenience wrapper for ap_expr_parse_cmd_mi() that sets 338 * module_index = APLOG_MODULE_INDEX 339 */ 340#define ap_expr_parse_cmd(cmd, expr, flags, err, lookup_fn) \ 341 ap_expr_parse_cmd_mi(cmd, expr, flags, err, lookup_fn, APLOG_MODULE_INDEX) 342 343 /** 344 * Internal initialisation of ap_expr (for httpd internal use) 345 */ 346void ap_expr_init(apr_pool_t *pool); 347 348#ifdef __cplusplus 349} 350#endif 351 352#endif /* AP_EXPR_H */ 353/** @} */ 354