You are viewing a plain text version of this content. The canonical link for it is here.
Posted to apreq-dev@httpd.apache.org by Joe Schaefer <jo...@sunstarsys.com> on 2003/10/24 17:42:12 UTC
[rfc] apreq_env redesign
After some googling around about linking on Win32,
I've come to the conclusion that relying on runtime
symbol resolution for the declarations in apreq_env.h
is impossible on Win32 (other non-ELF platforms may
also balk at the current design). To be 100% portable,
libapreq2 needs be using function pointers for the
apreq_env* calls, with a runtime initializer to set
everything up.
My plan is similar to the original idea of using a global
apreq_env vtable: I plan to put a static vtable pointer in
(a new file named) src/apreq_env.c and let a call to
(the new function) apreq_env_init(&new_vtable_struct)
reassign the static vtable pointer. The apreq_env_*
functions will be reimplemented as either macros or
wrapper functions that execute the appropriate vtable
entry.
The big advantage of doing this is that we'll be able to
build a shared apr-only libapreq2.so on all platforms,
and link the perl glue to *just* that (just as we currently
do for ELF-based *nix systems). This should allow the perl
glue to be useful in non-apache-2 environments like CGI.
I'd like to pursue this further, with Randy's help of
course. I can start a branch of httpd-apreq-2 cvs if folks
are unsure that such a change is truly necessary, but I'm
convinced it is.
--
Joe Schaefer
Re: [rfc] apreq_env redesign
Posted by Randy Kobes <ra...@theoryx5.uwinnipeg.ca>.
On Fri, 24 Oct 2003, Joe Schaefer wrote:
>
> After some googling around about linking on Win32,
> I've come to the conclusion that relying on runtime
> symbol resolution for the declarations in apreq_env.h
> is impossible on Win32 (other non-ELF platforms may
> also balk at the current design). To be 100% portable,
> libapreq2 needs be using function pointers for the
> apreq_env* calls, with a runtime initializer to set
> everything up.
>
> My plan is similar to the original idea of using a global
> apreq_env vtable: I plan to put a static vtable pointer in
> (a new file named) src/apreq_env.c and let a call to
> (the new function) apreq_env_init(&new_vtable_struct)
> reassign the static vtable pointer. The apreq_env_*
> functions will be reimplemented as either macros or
> wrapper functions that execute the appropriate vtable
> entry.
>
> The big advantage of doing this is that we'll be able to
> build a shared apr-only libapreq2.so on all platforms,
> and link the perl glue to *just* that (just as we currently
> do for ELF-based *nix systems). This should allow the perl
> glue to be useful in non-apache-2 environments like CGI.
>
> I'd like to pursue this further, with Randy's help of
> course. I can start a branch of httpd-apreq-2 cvs if folks
> are unsure that such a change is truly necessary, but I'm
> convinced it is.
I'm slightly biased :), but this sounds great ...
--
best regards,
randy
Re: [rfc] apreq_env redesign
Posted by Joe Schaefer <jo...@sunstarsys.com>.
Joe Schaefer <jo...@sunstarsys.com> writes:
[...]
> I'd like to pursue this further, with Randy's help of
> course. I can start a branch of httpd-apreq-2 cvs if folks
> are unsure that such a change is truly necessary, but I'm
> convinced it is.
More specifics:
1) Tag current cvs as 2.0.0-dev and start development on 2.0.1-dev.
2) Add src/apreq_env.c and remove env/libapreq_cgi.c and t/env.c.
3) Move the code in libapreq_cgi.c into apreq_env.c, and make it (CGI)
the default environment within libapreq2.so.
4) Patch apreq_env.h as follows:
Index: apreq_env.h
===================================================================
RCS file: /home/cvs/httpd-apreq-2/src/apreq_env.h,v
retrieving revision 1.19
diff -u -r1.19 apreq_env.h
--- apreq_env.h 14 Oct 2003 18:53:30 -0000 1.19
+++ apreq_env.h 25 Oct 2003 02:13:15 -0000
@@ -125,21 +125,15 @@
#endif
#endif
-/** logger */
-#define APREQ_DECLARE_LOG(f) APREQ_DECLARE_NONSTD(void)(f)(const char *file, \
- int line, int level, apr_status_t status, \
- void *env, const char *fmt, ...)
+APREQ_DECLARE_NONSTD(void) apreq_log(const char *file, int line,
+ int level, apr_status_t status,
+ void *env, const char *fmt, ...);
-
-APREQ_DECLARE_LOG(apreq_log);
APREQ_DECLARE(apr_pool_t *) apreq_env_pool(void *env);
-
-
APREQ_DECLARE(apreq_jar_t *) apreq_env_jar(void *env, apreq_jar_t *jar);
APREQ_DECLARE(apreq_request_t *) apreq_env_request(void *env,
apreq_request_t *req);
-
APREQ_DECLARE(const char *) apreq_env_query_string(void *env);
APREQ_DECLARE(const char *) apreq_env_header_in(void *env, const char *name);
@@ -148,7 +142,6 @@
#define apreq_env_cookie(env) apreq_env_header_in(env, "Cookie")
#define apreq_env_cookie2(env) apreq_env_header_in(env, "Cookie2")
-/** header out */
APREQ_DECLARE(apr_status_t)apreq_env_header_out(void *env,
const char *name,
char *val);
@@ -159,6 +152,30 @@
APREQ_DECLARE(apr_status_t) apreq_env_read(void *env,
apr_read_type_e block,
apr_off_t bytes);
+
+
+typedef struct apreq_env_t {
+ const char *name;
+ apr_uint32_t magic_number;
+ void (*log)(const char *,int,int,apr_status_t,void *,const char *,va_list);
+ apr_pool_t *(*pool)(void *);
+ apreq_jar_t *(*jar)(void *,apreq_jar_t *);
+ apreq_request_t *(*request)(void *,apreq_request_t *);
+ const char *(*query_string)(void *);
+ const char *(*header_in)(void *,const char *);
+ apr_status_t (*header_out)(void *, const char *,char *);
+ apr_status_t (*read)(void *,apr_read_type_e,apr_off_t);
+} apreq_env_t;
+
+#define APREQ_ENV_MODULE(pre, name, mmn) const apreq_env_t pre##_module = { \
+ name, mmn, pre##_log, pre##_pool, pre##_jar, pre##_request, \
+ pre##_query_string, pre##_header_in, pre##_header_out, pre##_read }
+
+
+APREQ_DECLARE(const apreq_env_t *) apreq_env_module(const apreq_env_t *mod);
+
+#define apreq_env_name (apreq_env_init(NULL)->name)
+#define apreq_env_magic_number (apreq_env_init(NULL)->magic_number)
/** @} */
#ifdef __cplusplus
==================================================
Note: apreq_env_module() is a get/set function implemented like
apreq_env_jar and apreq_env_request. So any non-cgi program
wishing to use libapreq will use that to override the CGI
defaults in apreq_env.c (before sending any http requests to
libapreq, of course).
5) Implement the remaining non-CGI modules (t/, env/mod_apreq.c)
by creating a module-private apreq_env_t struct and passing
it to apreq_env_module(). Actually I've already implemented
this in full on linux (all tests pass without any modifications
to the current test programs/modules), I'm just waiting for the
go-ahead from you guys.
6) Drop the LIBAPREQ_CGI / MOD_APREQ ifdefs for Win32 in apreq_env.h,
and drop mod_apreq from the linker options in the Win32 perl glue.
--
Joe Schaefer