httpd-modules-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Waldemar Klein <>
Subject Re: How to register additional operators or functions for use in expressions?
Date Sun, 01 Apr 2012 22:58:07 GMT

/* I'm not very experienced with mailinglists, but i think it's not
good to change the subject and add something like [SOLVED], because it
won't be listed together with the other posts in the archives and by
mail client filters, or did i miss something? */

First, thanks for the replies, i already did have a short look at
those files mentioned, but after the answers i looked a lot harder,
cause i was more sure i am on the right path :)

After lots of reading and experimenting i found out how this works,
i'll try to explain it for those interested. That is, mostly i won't
explain, but point to concrete examples in the sources :)

The version of Apache i was working with is 2.4.1, so the line numbers
i mention refer to this version.

To clarify what i'm talking about, i use
(C-)function: means a function inside a C file, in the meaning of a
procedure or what a method would be in C++. It's not an entirly
accurate description but i hope it's clear what i mean.
(expr-)function: means what is used in the expression parser in the
sense of a mathematical function, usually used in a similar context to
operator. something in the lines of function ::= funcname "(" word ")"
A (C-)function that i refer to as "does the work" would be one in
which i'd actually write something like "a+b", if i'd declare a new
operator like "...ADD..."

The files to look at are:

the interesting parts here are
- the struct ap_expr_eval_ctx_t (lines 104-135): this will be filled
and passed to every call of an actual (C-)funcion that implements a
(expr-)function or operator.
- the struct ap_expor_lookup_parms (lines 254-281): this will be
filled an passed to the lookup hook (C-)function
- the typedefs (line 204+), which don't have to be actually used, but
show how a (C-)function that actually does the work has to be declared

modules/ssl/mod_ssl.c and modules/ssl/ssl_engine_vars.c
An actual example how to register additional variables and a
string-list valued (expr-)function. Operators and string-valued
functions work very similarly.

To add an operator or (expr-)function, 4 parts are needed:

(1) Module declaration. This is the same as any other module, some
register_hooks (C-)function must be called (or passed to the macro,
don't know exactly). Example in modules/ssl/mod_ssl.c (line 585-593)

(2) register hooks function: in this, also similar to other modules,
macros or somethings (not really sure what it is but it's not
important at this point) are called that define the lookup functions
which will be called in (3). Example is in modules/ssl/mod_ssl.c,
ssl_register_hooks, (line544-583) which in turn calls
ssl_var_register() (line 568) in modules/ssl/ssl_engine_vars.c (lines
185-129), where ap_hook_expr_lookup (line 128) is called. This step
would normally be done in one place (that is, call ap_hook_expr_lookup
inside ssl_register_hooks), but for some reason this was split in the
ssl module.

(3) ssl_expr_lookup (line 79-102) is given as parameter to
ap_hook_expr_lookup, and this one is called when reading httpd.conf,
when a operator (or function etc.) is encountered. Here there has to
be a check for the type (variable, unary or binary operator, function,
etc.) and name (that is if we want to register a unary op "-X" we
check for the name "X"). Then the struct ap_expr_lookup_parms has to
be filled with at least the (C-)function  pointer (line 96 for
"PeerExtList") that actually will perform the work behind the
(expr-)function or operator.

(4) the actual "working" (C-)function (in the example for
"PeerExtList" the function is expr_peer_ext_list_fn (line 66-71))
should be defined like in the according typedef from ap_expr.h. It
will recieve a ap_expr_eval_ctx_t, some optional data which we could
have passed in step (3) and the actual arguments from the httpd.conf.
Number and types of the arguments depends on type of the
(expr-)function (i.e. one for unary op's, two for binary op's, etc.).
This one will be executed when apache is running, i.e. when taking a
request for example. Those arguments will not be exactly what is
written in httpd.conf, but rather what they evaluate to during a
request, connection, etc., for example %{REMOTE_HOST} in httpd.conf
means, our function gets the actual value of the variable at the time,
not the string "%{REMOTE_HOST}".

Note that step (3) and (4) are usually just one in other modules, like
a handler or filter. This was one of the parts that confused me most

I hope writing this all down will help someone in the future, it
already did help me to understand it better.

P.S. I am german, so there might be lots of grammar errors in here. If
you find any, you may keep them all !!

View raw message