httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Alexei Kosut <>
Subject Thoughts on Apache 2.0 API
Date Fri, 22 Aug 1997 01:49:18 GMT
I've been doing some more thinking about the Apache API and how we should
do Apache 2.0's - which is always dangerous, because I spew out these
really long emails - and thought of another idea. I'm not sure if this is
a good one or not.

A number of APIs nowadays, like ISAPI or JNI (those two come to mind
because they are the two I've used most recently that use this apporach -
there are lots more), are designed to be implemented in a number of ways
by a number of products, and it is deisrable to have them (the APIs) work
without change on various platforms, where calling conventions of
functions and libraries may be different (Unix vs. Windows, for
example). What they end up doing is this:

Apache's current plan passes around data structures that contain
data. There are then a number of functions that are available that do
things with these data structures, possibly with additional arguments. A
good example might be rputs(). It takes as an argument a request_rec *,
and a char *. It outputs an array of chars to the client (or whatever the
request_rec actually points to), and returns the number of characters (or
possibly bytes - they're usually the same, so Apache doesn't make the
distinction - unlike, say, Java) written. This is good. Now, to be able
to use rputs(), you need to include a .h file, so your compiler knows the
syntax of the function. This is simple. You then need to make your module
aware of how to invoke the function, when it needs to. This is much more
difficult. The simple case is when your module is compiled into Apache,
and the system's linker just makes it work. When the module is
dynamically loaded, this is much harder. Most Unices' dynamic linkers do
a good job of this. Windows has a better-defined interface (DLLs), but it
has some major problems: Regardless of what the header file says, finding
the function is very dependent on how the Apache binary was written,
compiled and linked. A different version of Apache, with a different set
of available functions, will likely break the module. It also requires
an export library, and a library to link the module against. This makes
it very hard to write an Apache API module for any server but Apache, and
to make it work for more than one version of the Apache API. In fact, we
explictly deny modules from loading if they were written to a different
version of the API, even if all the features they want to use are all
present and unchanged.

How do you work around this? One way is as follows, and is how a number
of APIs do it: As with Apache, you pass a data structure to your
module. However, instead of having the API functions available as
normally linked calls, you put pointers to them into the data
structure. So instead of the following:

    rputs(string, r);

You might use this:

    r->puts(r, string);

This way, the module doesn't know or care about the internal linking
structure of Apache. There's a published specification of the request_rec
structure, including all the public variables and functions, and their
offsets. Apache can do whatever it wants behind the scenes, and it will
always work. Other servers can implement the Apache API, without having
to use the same linking order as Apache. We can add new functions,
without having to break existing modules (add them to the bottom). Doing
this would also force us to rewrite everything, giving us incentive to
create real documentation.

We'd probably want to segment it, of course, so we could have something
like r->request->puts(), or r->buff->bcreate(), or r->alloc->strdup(),
etc... That would make it easier, because you'd need to make several
instances of all this (cmd_rec would also need it, as would whatever you
pass to the init, child init and child exit functions). And a module
would only need to #include one file, not ten, to do useful things.

I think this could be a nice thing to have. And Ben, if you mention C++,
all I can do is sigh and say "yes".

-- Alexei Kosut <>

View raw message