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