2 ## | ____| / \ | _ \_ _|
3 ## | _| / _ \ | |_) | |
4 ## | |__ / ___ \| __/| |
5 ## |____/_/ \_\_| |___| Extended API for Apache
6 ## ____________________________________________________________________________
8 ## Annotated patch file: eapi.patch
9 ## Copyright (c) 1998-2001 Ralf S. Engelschall, All Rights Reserved.
10 ## Created on: 11-May-2004
12 ## This file assembles changes to existing Apache source files
13 ## between the original Apache and the patched variant. It can be
14 ## automatically applied to a vanilla Apache source tree with the
15 ## 'patch' tool to upgrade those files. Each patch snippet is
16 ## annotated with a short description.
18 ## This file contains all patches to the Apache source
19 ## tree which add the Extended API (EAPI) support.
22 +---------------------------------------------------------------------------
23 | Add the EAPI and EAPI_MM configuration entries which triggers the EAPI
24 | patches and configured the shared memory support via the MM library.
25 +---------------------------------------------------------------------------
26 Index: src/Configuration.tmpl
27 --- src/Configuration.tmpl 11 May 2004 18:28:09 -0000 1.1.1.8
28 +++ src/Configuration.tmpl 11 May 2004 18:32:15 -0000 1.24
32 ################################################################
33 +# Extended API (EAPI) support:
36 +# The EAPI rule enables more module hooks, a generic low-level hook
37 +# mechanism, a generic context mechanism and shared memory based pools.
40 +# Set the EAPI_MM variable to either the directory of a MM Shared Memory
41 +# Library source tree or the installation tree of MM. Alternatively you can
42 +# also use the value 'SYSTEM' which then indicates that MM is installed
43 +# under various system locations. When the MM library files cannot be found
44 +# the EAPI still can be built, but without shared memory pool support, of
50 +################################################################
51 # Dynamic Shared Object (DSO) support
53 # There is experimental support for compiling the Apache core and
55 +---------------------------------------------------------------------------
56 | Patch in implementation of the EAPI rule.
57 +---------------------------------------------------------------------------
59 --- src/Configure 11 May 2004 18:28:09 -0000 1.1.1.23
60 +++ src/Configure 11 May 2004 18:32:15 -0000 1.26
61 @@ -1855,6 +1855,72 @@
64 ####################################################################
65 +## Extended API (EAPI) support:
67 +if [ "x$RULE_EAPI" = "x" ]; then
68 + RULE_EAPI=`./helpers/CutRule EAPI $file`
70 +if [ "x$RULE_EAPI" = "xyes" ]; then
71 + echo " + enabling Extended API (EAPI)"
72 + CFLAGS="$CFLAGS -DEAPI"
73 + # some vendor compilers are too restrictive
74 + # for our ap_hook and ap_ctx sources.
76 + *IRIX-32*:*/cc|*IRIX-32*:cc )
77 + CFLAGS="$CFLAGS -woff 1048,1110,1164"
80 + # MM Shared Memory Library support for EAPI
81 + if [ "x$EAPI_MM" = "x" ]; then
82 + EAPI_MM=`egrep '^EAPI_MM=' $file | sed -n -e '$p' | awk -F= '{print $2}'`
84 + if [ "x$EAPI_MM" != "x" ]; then
87 + * ) for p in . .. ../..; do
88 + if [ -d "$p/$EAPI_MM" ]; then
89 + EAPI_MM="`echo $p/$EAPI_MM | sed -e 's;/\./;/;g'`"
95 + if [ "x$EAPI_MM" = "xSYSTEM" ]; then
96 + echo " using MM library for EAPI: (system-wide)"
97 + CFLAGS="$CFLAGS -DEAPI_MM"
98 + __INCLUDES="`mm-config --cflags`"
99 + if [ "x$__INCLUDES" != "x-I/usr/include" ]; then
100 + INCLUDES="$INCLUDES $__INCLUDES"
102 + LDFLAGS="$LDFLAGS `mm-config --ldflags`"
103 + LIBS="$LIBS `mm-config --libs`"
105 + if [ -f "$EAPI_MM/.libs/libmm.a" -a -f "$EAPI_MM/mm.h" ]; then
106 + echo " using MM library: $EAPI_MM (source-tree only)"
109 + * ) EAPI_MM="\$(SRCDIR)/$EAPI_MM" ;;
111 + CFLAGS="$CFLAGS -DEAPI_MM"
112 + INCLUDES="$INCLUDES -I$EAPI_MM"
113 + LDFLAGS="$LDFLAGS -L$EAPI_MM/.libs"
115 + elif [ -f "$EAPI_MM/bin/mm-config" ]; then
116 + echo " using MM library: $EAPI_MM (installed)"
117 + CFLAGS="$CFLAGS -DEAPI_MM"
118 + INCLUDES="$INCLUDES `$EAPI_MM/bin/mm-config --cflags`"
119 + LDFLAGS="$LDFLAGS `$EAPI_MM/bin/mm-config --ldflags`"
120 + LIBS="$LIBS `$EAPI_MM/bin/mm-config --libs`"
122 + echo "Configure:Error: Cannot find MM library under $EAPI_MM" 1>&2
130 +####################################################################
131 ## Add in the Expat library if needed/wanted.
135 +---------------------------------------------------------------------------
136 | Add the build support for the ap_hook.c and ap_ctx.c sources (Unix)
137 +---------------------------------------------------------------------------
138 Index: src/ap/Makefile.tmpl
139 --- src/ap/Makefile.tmpl 19 Jun 2002 07:20:22 -0000 1.1.1.8
140 +++ src/ap/Makefile.tmpl 19 Jun 2002 07:29:08 -0000 1.8
143 OBJS=ap_cpystrn.o ap_execve.o ap_fnmatch.o ap_getpass.o ap_md5c.o ap_signal.o \
144 ap_slack.o ap_snprintf.o ap_sha1.o ap_checkpass.o ap_base64.o ap_ebcdic.o \
146 + ap_strtol.o ap_hook.o ap_ctx.o ap_mm.o
149 $(CC) -c $(INCLUDES) $(CFLAGS) $<
151 +---------------------------------------------------------------------------
152 | Add the build support for the ap_hook.c and ap_ctx.c sources (Win32)
153 +---------------------------------------------------------------------------
155 --- src/ap/ap.mak 18 Jul 2003 15:44:30 -0000 1.1.1.10
156 +++ src/ap/ap.mak 18 Jul 2003 15:56:58 -0000 1.10
158 -@erase "$(INTDIR)\ap_cpystrn.obj"
159 -@erase "$(INTDIR)\ap_fnmatch.obj"
160 -@erase "$(INTDIR)\ap_md5c.obj"
161 + -@erase "$(INTDIR)\ap_hook.obj"
162 + -@erase "$(INTDIR)\ap_ctx.obj"
163 + -@erase "$(INTDIR)\ap_mm.obj"
164 -@erase "$(INTDIR)\ap_sha1.obj"
165 -@erase "$(INTDIR)\ap_signal.obj"
166 -@erase "$(INTDIR)\ap_slack.obj"
168 "$(INTDIR)\ap_cpystrn.obj" \
169 "$(INTDIR)\ap_fnmatch.obj" \
170 "$(INTDIR)\ap_md5c.obj" \
171 + "$(INTDIR)\ap_hook.obj" \
172 + "$(INTDIR)\ap_ctx.obj" \
173 + "$(INTDIR)\ap_mm.obj" \
174 "$(INTDIR)\ap_sha1.obj" \
175 "$(INTDIR)\ap_signal.obj" \
176 "$(INTDIR)\ap_slack.obj" \
178 -@erase "$(INTDIR)\ap_cpystrn.obj"
179 -@erase "$(INTDIR)\ap_fnmatch.obj"
180 -@erase "$(INTDIR)\ap_md5c.obj"
181 + -@erase "$(INTDIR)\ap_hook.obj"
182 + -@erase "$(INTDIR)\ap_ctx.obj"
183 + -@erase "$(INTDIR)\ap_mm.obj"
184 -@erase "$(INTDIR)\ap_sha1.obj"
185 -@erase "$(INTDIR)\ap_signal.obj"
186 -@erase "$(INTDIR)\ap_slack.obj"
188 "$(INTDIR)\ap_cpystrn.obj" \
189 "$(INTDIR)\ap_fnmatch.obj" \
190 "$(INTDIR)\ap_md5c.obj" \
191 + "$(INTDIR)\ap_hook.obj" \
192 + "$(INTDIR)\ap_ctx.obj" \
193 + "$(INTDIR)\ap_mm.obj" \
194 "$(INTDIR)\ap_sha1.obj" \
195 "$(INTDIR)\ap_signal.obj" \
196 "$(INTDIR)\ap_slack.obj" \
198 +---------------------------------------------------------------------------
199 | Replace the MODULE_MAGIC_COOKIE to allow us to distinguish between
200 | EAPI-aware modules and standard modules.
201 +---------------------------------------------------------------------------
202 Index: src/include/ap_mmn.h
203 --- src/include/ap_mmn.h 11 May 2004 18:28:12 -0000 1.1.1.13
204 +++ src/include/ap_mmn.h 11 May 2004 18:32:15 -0000 1.13
206 * in core_dir_config.
210 + * Under Extended API situations we replace the magic cookie "AP13" with
211 + * "EAPI" to let us distinguish between the EAPI module structure (which
212 + * contain additional pointers at the end) and standard module structures
213 + * (which lack at least NULL's for the pointers at the end). This is
214 + * important because standard ("AP13") modules would dump core when we
215 + * dispatch over the additional hooks because NULL's are missing at the end of
216 + * the module structure. See also the code in mod_so for details on loading
217 + * (we accept both "AP13" and "EAPI").
220 +#define MODULE_MAGIC_COOKIE_AP13 0x41503133UL /* "AP13" */
221 +#define MODULE_MAGIC_COOKIE_EAPI 0x45415049UL /* "EAPI" */
222 +#define MODULE_MAGIC_COOKIE MODULE_MAGIC_COOKIE_EAPI
224 #define MODULE_MAGIC_COOKIE 0x41503133UL /* "AP13" */
227 #ifndef MODULE_MAGIC_NUMBER_MAJOR
228 #define MODULE_MAGIC_NUMBER_MAJOR 19990320
230 +---------------------------------------------------------------------------
231 | Add the additional prototypes and defines for the
232 | shared memory pools.
233 +---------------------------------------------------------------------------
234 Index: src/include/ap_alloc.h
235 --- src/include/ap_alloc.h 11 May 2004 18:28:11 -0000 1.1.1.7
236 +++ src/include/ap_alloc.h 11 May 2004 18:32:15 -0000 1.8
238 API_EXPORT(pool *) ap_init_alloc(void); /* Set up everything */
239 void ap_cleanup_alloc(void);
240 API_EXPORT(pool *) ap_make_sub_pool(pool *); /* All pools are subpools of permanent_pool */
242 +typedef enum { AP_POOL_RD, AP_POOL_RW } ap_pool_lock_mode;
243 +int ap_shared_pool_possible(void);
244 +void ap_init_alloc_shared(int);
245 +void ap_kill_alloc_shared(void);
246 +API_EXPORT(pool *) ap_make_shared_sub_pool(pool *);
247 +API_EXPORT(int) ap_acquire_pool(pool *, ap_pool_lock_mode);
248 +API_EXPORT(int) ap_release_pool(pool *);
250 API_EXPORT(void) ap_destroy_pool(pool *);
252 /* pools have nested lifetimes -- sub_pools are destroyed when the
254 +---------------------------------------------------------------------------
255 | Add the additional context variable `ctx' for BUFF structures.
256 +---------------------------------------------------------------------------
257 Index: src/include/buff.h
258 --- src/include/buff.h 11 May 2004 18:28:12 -0000 1.1.1.8
259 +++ src/include/buff.h 11 May 2004 18:32:15 -0000 1.12
261 /* transport handle, for RPC binding handle or some such */
272 API_EXPORT(int) ap_bflsbuf(int c, BUFF *fb);
273 API_EXPORT(int) ap_bfilbuf(BUFF *fb);
276 +#define ap_bpeekc(fb) ( ((fb)->incnt == 0) ? EOF : *((fb)->inptr) )
279 #ifndef CHARSET_EBCDIC
281 #define ap_bgetc(fb) ( ((fb)->incnt == 0) ? ap_bfilbuf(fb) : \
283 +---------------------------------------------------------------------------
284 | Add the four additional Apache API module hooks.
285 +---------------------------------------------------------------------------
286 Index: src/include/http_config.h
287 --- src/include/http_config.h 11 May 2004 18:28:12 -0000 1.1.1.12
288 +++ src/include/http_config.h 11 May 2004 18:32:15 -0000 1.14
290 void (*child_exit) (server_rec *, pool *);
292 int (*post_read_request) (request_rec *);
296 + * ANSI C guarantees us that we can at least _extend_ the module structure
297 + * with additional hooks without the need to change all existing modules.
298 + * Because: ``If there are fewer initializers in the list than members of
299 + * the structure, the trailing members are initialized with 0.'' (The C
300 + * Programming Language, 2nd Ed., A8.7 Initialization). So we just
301 + * have to put our additional hooks here:
304 + * Called from within ap_add_module() right after the module structure
305 + * was linked into the Apache internal module list. It is mainly
306 + * intended to be used to define configuration defines (<IfDefine>)
307 + * which have to be available directly after a LoadModule/AddModule.
308 + * Actually this is the earliest possible hook a module can use.
311 + * Called from within ap_remove_module() right before the module
312 + * structure is kicked out from the Apache internal module list.
313 + * Actually this is last possible hook a module can use and exists for
314 + * consistency with the add_module hook.
317 + * Called right after a configuration directive line was read and
318 + * before it is processed. It is mainly intended to be used for
319 + * rewriting directives in order to provide backward compatibility to
320 + * old directive variants.
323 + * Called from within the internal new_connection() function, right
324 + * after the conn_rec structure for the new established connection was
325 + * created and before Apache starts processing the request with
326 + * ap_read_request(). It is mainly intended to be used to setup/run
327 + * connection dependent things like sending start headers for
328 + * on-the-fly compression, etc.
330 + * close_connection:
331 + * Called from within the Apache dispatching loop just before any
332 + * ap_bclose() is performed on the socket connection, but a long time
333 + * before any pool cleanups are done for the connection (which can be
334 + * too late for some applications). It is mainly intended to be used
335 + * to close/finalize connection dependent things like sending end
336 + * headers for on-the-fly compression, etc.
338 +#ifdef ULTRIX_BRAIN_DEATH
339 + void (*add_module) ();
340 + void (*remove_module) ();
341 + char *(*rewrite_command) ();
342 + void (*new_connection) ();
343 + void (*close_connection) ();
345 + void (*add_module) (struct module_struct *);
346 + void (*remove_module) (struct module_struct *);
347 + char *(*rewrite_command) (cmd_parms *, void *config, const char *);
348 + void (*new_connection) (conn_rec *);
349 + void (*close_connection) (conn_rec *);
354 /* Initializer for the first few module slots, which are only
356 +---------------------------------------------------------------------------
357 | Add the additional variable `ap_global_ctx' for holding
358 | global module context.
359 +---------------------------------------------------------------------------
360 Index: src/include/http_conf_globals.h
361 --- src/include/http_conf_globals.h 11 May 2004 18:28:12 -0000 1.1.1.14
362 +++ src/include/http_conf_globals.h 11 May 2004 18:32:15 -0000 1.15
365 extern int ap_dump_settings;
366 extern API_VAR_EXPORT int ap_extended_status;
368 +extern API_VAR_EXPORT ap_ctx *ap_global_ctx;
371 extern API_VAR_EXPORT char *ap_pid_fname;
372 extern API_VAR_EXPORT char *ap_scoreboard_fname;
374 +---------------------------------------------------------------------------
375 | First add support for the HTTPS protocol scheme via hooks,
376 | second add the additional context variable `ctx' for the
377 | conn_rec, server_rec and request_rec structures. And third
378 | add a prototype for the additional ap_add_config_define()
380 +---------------------------------------------------------------------------
381 Index: src/include/httpd.h
382 --- src/include/httpd.h 11 May 2004 18:28:12 -0000 1.1.1.23
383 +++ src/include/httpd.h 11 May 2004 18:32:15 -0000 1.33
385 /* Headers in which EVERYONE has an interest... */
387 #include "ap_config.h"
391 #include "ap_alloc.h"
393 + * Include the Extended API headers.
394 + * Don't move the position. It has to be after ap_alloc.h because it uses the
395 + * pool stuff but before buff.h because the buffer stuff uses the EAPI, too.
398 +#include "ap_hook.h"
405 #define ap_http_method(r) ap_os_http_method((void*)r)
406 #define ap_default_port(r) ap_os_default_port((void*)r)
409 +#define ap_http_method(r) (((r)->ctx != NULL && ap_ctx_get((r)->ctx, "ap::http::method") != NULL) ? ((char *)ap_ctx_get((r)->ctx, "ap::http::method")) : "http")
410 +#define ap_default_port(r) (((r)->ctx != NULL && ap_ctx_get((r)->ctx, "ap::default::port") != NULL) ? atoi((char *)ap_ctx_get((r)->ctx, "ap::default::port")) : DEFAULT_HTTP_PORT)
412 #define ap_http_method(r) "http"
413 #define ap_default_port(r) DEFAULT_HTTP_PORT
417 /* --------- Default user name and group name running standalone ---------- */
419 #define SCOREBOARD_MAINTENANCE_INTERVAL 1000000
424 + * Path to Shared Memory Files
427 +#ifndef EAPI_MM_CORE_PATH
428 +#define EAPI_MM_CORE_PATH "logs/mm"
430 +#ifndef EAPI_MM_CORE_MAXSIZE
431 +#define EAPI_MM_CORE_MAXSIZE 1024*1024*1 /* max. 1MB */
435 /* Number of requests to try to handle in a single process. If <= 0,
436 * the children don't die off. That's the default here, since I'm still
437 * interested in finding and stanching leaks.
439 API_EXPORT(const char *) ap_get_server_version(void);
440 API_EXPORT(void) ap_add_version_component(const char *component);
441 API_EXPORT(const char *) ap_get_server_built(void);
443 +API_EXPORT(void) ap_add_config_define(const char *define);
446 /* Numeric release version identifier: MMNNFFRBB: major minor fix final beta
447 * Always increases along the same track as the source branch.
449 * record to improve 64bit alignment the next time we need to break
450 * binary compatibility for some other reason.
460 char *local_host; /* used for ap_get_server_name when
461 * UseCanonicalName is set to DNS
462 * (ignores setting of HostnameLookups) */
468 /* Per-vhost config... */
470 int limit_req_line; /* limit on size of the HTTP request line */
471 int limit_req_fieldsize; /* limit on size of any request header field */
472 int limit_req_fields; /* limit on number of request header fields */
479 /* These are more like real hosts than virtual hosts */
481 +---------------------------------------------------------------------------
482 | Patch the shared memory pool support into the Apache pool facility.
483 +---------------------------------------------------------------------------
484 Index: src/main/alloc.c
485 --- src/main/alloc.c 11 May 2004 18:28:13 -0000 1.1.1.16
486 +++ src/main/alloc.c 11 May 2004 18:32:15 -0000 1.25
492 +#include "http_config.h"
493 +#include "http_conf_globals.h"
495 #include "multithread.h"
496 #include "http_log.h"
499 #define BLOCK_MINALLOC 0
502 +#if defined(EAPI) && defined(EAPI_MM)
503 +static AP_MM *mm = NULL;
506 /*****************************************************************
508 * Managing free storage blocks...
511 union block_hdr *next;
513 +#if defined(EAPI) && defined(EAPI_MM)
517 union block_hdr *global_next;
518 struct pool *owning_pool;
520 /* Get a completely new block from the system pool. Note that we rely on
521 malloc() to provide aligned memory. */
523 +#if defined(EAPI) && defined(EAPI_MM)
524 +static union block_hdr *malloc_block(int size, int is_shm)
526 static union block_hdr *malloc_block(int size)
529 union block_hdr *blok;
532 num_malloc_bytes += size + sizeof(union block_hdr);
534 request_size = size + sizeof(union block_hdr);
535 +#if defined(EAPI) && defined(EAPI_MM)
537 + blok = (union block_hdr *)ap_mm_malloc(mm, request_size);
540 blok = (union block_hdr *) malloc(request_size);
542 fprintf(stderr, "Ouch! malloc(%d) failed in malloc_block()\n",
546 debug_fill(blok, size + sizeof(union block_hdr));
547 +#if defined(EAPI) && defined(EAPI_MM)
548 + blok->h.is_shm = is_shm;
551 blok->h.first_avail = (char *) (blok + 1);
552 blok->h.endp = size + blok->h.first_avail;
555 return; /* Sanity check --- freeing empty pool? */
557 +#if defined(EAPI) && defined(EAPI_MM)
558 + if (blok->h.is_shm)
559 + (void)ap_mm_lock(mm, AP_MM_LOCK_RW);
561 (void) ap_acquire_mutex(alloc_mutex);
562 old_free_list = block_freelist;
563 block_freelist = blok;
567 (void) ap_release_mutex(alloc_mutex);
568 +#if defined(EAPI) && defined(EAPI_MM)
569 + if (blok->h.is_shm)
570 + (void)ap_mm_unlock(mm);
576 * if necessary. Must be called with alarms blocked.
579 +#if defined(EAPI) && defined(EAPI_MM)
580 +static union block_hdr *new_block(int min_size, int is_shm)
582 static union block_hdr *new_block(int min_size)
585 union block_hdr **lastptr = &block_freelist;
586 union block_hdr *blok = block_freelist;
590 while (blok != NULL) {
591 +#if defined(EAPI) && defined(EAPI_MM)
592 + if (blok->h.is_shm == is_shm &&
593 + min_size + BLOCK_MINFREE <= blok->h.endp - blok->h.first_avail) {
595 if (min_size + BLOCK_MINFREE <= blok->h.endp - blok->h.first_avail) {
597 *lastptr = blok->h.next;
599 debug_verify_filled(blok->h.first_avail, blok->h.endp,
603 min_size += BLOCK_MINFREE;
604 +#if defined(EAPI) && defined(EAPI_MM)
605 + blok = malloc_block((min_size > BLOCK_MINALLOC) ? min_size : BLOCK_MINALLOC, is_shm);
607 blok = malloc_block((min_size > BLOCK_MINALLOC) ? min_size : BLOCK_MINALLOC);
616 +#if defined(EAPI) && defined(EAPI_MM)
621 static pool *permanent_pool;
622 @@ -400,16 +447,28 @@
623 #define POOL_HDR_CLICKS (1 + ((sizeof(struct pool) - 1) / CLICK_SZ))
624 #define POOL_HDR_BYTES (POOL_HDR_CLICKS * CLICK_SZ)
626 +#if defined(EAPI) && defined(EAPI_MM)
627 +static struct pool *make_sub_pool_internal(struct pool *p, int is_shm)
629 API_EXPORT(struct pool *) ap_make_sub_pool(struct pool *p)
632 union block_hdr *blok;
637 +#if defined(EAPI) && defined(EAPI_MM)
639 + (void)ap_mm_lock(mm, AP_MM_LOCK_RW);
641 (void) ap_acquire_mutex(alloc_mutex);
643 +#if defined(EAPI) && defined(EAPI_MM)
644 + blok = new_block(POOL_HDR_BYTES, is_shm);
646 blok = new_block(POOL_HDR_BYTES);
648 new_pool = (pool *) blok->h.first_avail;
649 blok->h.first_avail += POOL_HDR_BYTES;
651 @@ -428,12 +487,38 @@
652 p->sub_pools = new_pool;
655 +#if defined(EAPI) && defined(EAPI_MM)
656 + new_pool->is_shm = is_shm;
659 (void) ap_release_mutex(alloc_mutex);
660 +#if defined(EAPI) && defined(EAPI_MM)
662 + (void)ap_mm_unlock(mm);
670 +#if defined(EAPI_MM)
671 +API_EXPORT(struct pool *) ap_make_sub_pool(struct pool *p)
673 + return make_sub_pool_internal(p, 0);
675 +API_EXPORT(struct pool *) ap_make_shared_sub_pool(struct pool *p)
677 + return make_sub_pool_internal(p, 1);
680 +API_EXPORT(struct pool *) ap_make_shared_sub_pool(struct pool *p)
688 static void stack_var_init(char *s)
695 +int ap_shared_pool_possible(void)
697 + return ap_mm_useable();
702 static void dump_stats(void)
705 return permanent_pool;
709 +void ap_init_alloc_shared(int early)
711 +#if defined(EAPI_MM)
717 + /* process very early on startup */
718 + mm_size = ap_mm_maxsize();
719 + if (mm_size > EAPI_MM_CORE_MAXSIZE)
720 + mm_size = EAPI_MM_CORE_MAXSIZE;
721 + mm_path = ap_server_root_relative(permanent_pool,
722 + ap_psprintf(permanent_pool, "%s.%ld",
723 + EAPI_MM_CORE_PATH, (long)getpid()));
724 + if ((mm = ap_mm_create(mm_size, mm_path)) == NULL) {
725 + fprintf(stderr, "Ouch! ap_mm_create(%d, \"%s\") failed\n", mm_size, mm_path);
726 + err1 = ap_mm_error();
728 + err1 = "-unknown-";
729 + err2 = strerror(errno);
731 + err2 = "-unknown-";
732 + fprintf(stderr, "Error: MM: %s: OS: %s\n", err1, err2);
737 + /* process a lot later on startup */
739 + ap_mm_permission(mm, (_S_IREAD|_S_IWRITE), ap_user_id, -1);
741 + ap_mm_permission(mm, (S_IRUSR|S_IWUSR), ap_user_id, -1);
744 +#endif /* EAPI_MM */
748 +void ap_kill_alloc_shared(void)
750 +#if defined(EAPI_MM)
755 +#endif /* EAPI_MM */
760 void ap_cleanup_alloc(void)
762 ap_destroy_mutex(alloc_mutex);
763 @@ -490,10 +634,18 @@
767 +#if defined(EAPI) && defined(EAPI_MM)
769 + (void)ap_mm_lock(mm, AP_MM_LOCK_RW);
771 (void) ap_acquire_mutex(alloc_mutex);
773 ap_destroy_pool(a->sub_pools);
774 (void) ap_release_mutex(alloc_mutex);
775 +#if defined(EAPI) && defined(EAPI_MM)
777 + (void)ap_mm_unlock(mm);
779 /* Don't hold the mutex during cleanups. */
780 run_cleanups(a->cleanups);
786 +#if defined(EAPI) && defined(EAPI_MM)
788 + (void)ap_mm_lock(mm, AP_MM_LOCK_RW);
790 (void) ap_acquire_mutex(alloc_mutex);
792 if (a->parent->sub_pools == a)
794 a->sub_next->sub_prev = a->sub_prev;
796 (void) ap_release_mutex(alloc_mutex);
797 +#if defined(EAPI) && defined(EAPI_MM)
799 + (void)ap_mm_unlock(mm);
802 free_blocks(a->first);
805 return bytes_in_block_list(block_freelist);
809 +API_EXPORT(int) ap_acquire_pool(pool *p, ap_pool_lock_mode mode)
811 +#if defined(EAPI_MM)
814 + return ap_mm_lock(mm, mode == AP_POOL_RD ? AP_MM_LOCK_RD : AP_MM_LOCK_RW);
820 +API_EXPORT(int) ap_release_pool(pool *p)
822 +#if defined(EAPI_MM)
825 + return ap_mm_unlock(mm);
832 /*****************************************************************
835 @@ -716,16 +900,31 @@
839 +#if defined(EAPI) && defined(EAPI_MM)
841 + (void)ap_mm_lock(mm, AP_MM_LOCK_RW);
843 (void) ap_acquire_mutex(alloc_mutex);
845 +#if defined(EAPI) && defined(EAPI_MM)
846 + blok = new_block(size, a->is_shm);
848 blok = new_block(size);
850 a->last->h.next = blok;
853 blok->h.owning_pool = a;
855 +#if defined(EAPI) && defined(EAPI_MM)
856 + blok->h.is_shm = a->is_shm;
859 (void) ap_release_mutex(alloc_mutex);
860 +#if defined(EAPI) && defined(EAPI_MM)
862 + (void)ap_mm_unlock(mm);
867 @@ -842,6 +1041,11 @@
869 if (size < AP_PSPRINTF_MIN_SIZE)
870 size = AP_PSPRINTF_MIN_SIZE;
871 +#if defined(EAPI) && defined(EAPI_MM)
872 + if (ps->block->h.is_shm)
873 + ptr = ap_mm_realloc(ps->base, size);
876 ptr = realloc(ps->base, size);
878 fputs("Ouch! Out of memory!\n", stderr);
879 @@ -865,9 +1069,21 @@
880 size = AP_PSPRINTF_MIN_SIZE;
882 /* must try another blok */
883 +#if defined(EAPI) && defined(EAPI_MM)
884 + if (blok->h.is_shm)
885 + (void)ap_mm_lock(mm, AP_MM_LOCK_RW);
887 (void) ap_acquire_mutex(alloc_mutex);
888 +#if defined(EAPI) && defined(EAPI_MM)
889 + nblok = new_block(size, blok->h.is_shm);
891 nblok = new_block(size);
893 (void) ap_release_mutex(alloc_mutex);
894 +#if defined(EAPI) && defined(EAPI_MM)
895 + if (blok->h.is_shm)
896 + (void)ap_mm_unlock(mm);
898 memcpy(nblok->h.first_avail, blok->h.first_avail, cur_len);
899 ps->vbuff.curpos = nblok->h.first_avail + cur_len;
900 /* save a byte for the NUL terminator */
901 @@ -876,10 +1092,18 @@
902 /* did we allocate the current blok? if so free it up */
903 if (ps->got_a_new_block) {
904 debug_fill(blok->h.first_avail, blok->h.endp - blok->h.first_avail);
905 +#if defined(EAPI) && defined(EAPI_MM)
906 + if (blok->h.is_shm)
907 + (void)ap_mm_lock(mm, AP_MM_LOCK_RW);
909 (void) ap_acquire_mutex(alloc_mutex);
910 blok->h.next = block_freelist;
911 block_freelist = blok;
912 (void) ap_release_mutex(alloc_mutex);
913 +#if defined(EAPI) && defined(EAPI_MM)
914 + if (blok->h.is_shm)
915 + (void)ap_mm_unlock(mm);
919 ps->got_a_new_block = 1;
920 @@ -898,6 +1122,11 @@
924 +#if defined(EAPI) && defined(EAPI_MM)
926 + ps.base = ap_mm_malloc(mm, 512);
929 ps.base = malloc(512);
930 if (ps.base == NULL) {
931 fputs("Ouch! Out of memory!\n", stderr);
932 @@ -910,6 +1139,11 @@
933 *ps.vbuff.curpos++ = '\0';
936 +#if defined(EAPI) && defined(EAPI_MM)
938 + ptr = ap_mm_realloc(ptr, (char *)ps.vbuff.curpos - (char *)ptr);
941 ptr = realloc(ptr, (char *)ps.vbuff.curpos - (char *)ptr);
943 fputs("Ouch! Out of memory!\n", stderr);
945 +---------------------------------------------------------------------------
946 | Patch the low-level buffer routines to additionally allow
947 | modules to intercept the I/O processing via hooks.
948 +---------------------------------------------------------------------------
949 Index: src/main/buff.c
950 --- src/main/buff.c 11 May 2004 18:28:14 -0000 1.1.1.15
951 +++ src/main/buff.c 11 May 2004 18:32:15 -0000 1.23
957 + if (!ap_hook_call("ap::buff::read", &rv, fb, buf, nbyte))
959 rv = read(fb->fd_in, buf, nbyte);
964 #if defined (WIN32) || defined(NETWARE) || defined(CYGWIN_WINSOCK)
965 if (fb->flags & B_SOCKET) {
967 + if (!ap_hook_call("ap::buff::recvwithtimeout", &rv, fb, buf, nbyte))
969 rv = ap_recvwithtimeout(fb->fd_in, buf, nbyte, 0);
970 if (rv == SOCKET_ERROR)
971 errno = WSAGetLastError();
977 + if (!ap_hook_call("ap::buff::write", &rv, fb, buf, nbyte))
980 rv = sfwrite(fb->sf_out, buf, nbyte);
984 #if defined(WIN32) || defined(NETWARE)
985 if (fb->flags & B_SOCKET) {
987 + if (!ap_hook_call("ap::buff::sendwithtimeout", &rv, fb, buf, nbyte))
989 rv = ap_sendwithtimeout(fb->fd, buf, nbyte, 0);
990 if (rv == SOCKET_ERROR)
991 errno = WSAGetLastError();
993 fb->callback_data = NULL;
994 fb->filter_callback = NULL;
997 + fb->ctx = ap_ctx_new(p);
1003 @@ -1073,6 +1089,9 @@
1008 + if (!ap_hook_call("ap::buff::writev", &rv, fb, &vec[i], nvec -i))
1010 rv = writev(fb->fd, &vec[i], nvec - i);
1011 while (rv == -1 && (errno == EINTR || errno == EAGAIN)
1012 && !(fb->flags & B_EOUT));
1014 +---------------------------------------------------------------------------
1015 | Add the implementation of the additional `add_module' and
1016 | `rewrite_command' module hooks. Additionally the `ctx'
1017 | variables are initialized.
1018 +---------------------------------------------------------------------------
1019 Index: src/main/http_config.c
1020 --- src/main/http_config.c 11 May 2004 18:28:14 -0000 1.1.1.17
1021 +++ src/main/http_config.c 11 May 2004 18:32:15 -0000 1.20
1022 @@ -557,6 +557,20 @@
1025 #endif /*_OSD_POSIX*/
1029 + * Invoke the `add_module' hook inside the now existing set
1030 + * of modules to let them all now that this module was added.
1034 + for (m2 = top_module; m2 != NULL; m2 = m2->next)
1035 + if (m2->magic == MODULE_MAGIC_COOKIE_EAPI)
1036 + if (m2->add_module != NULL)
1037 + (*m2->add_module)(m);
1043 @@ -571,6 +585,21 @@
1049 + * Invoke the `remove_module' hook inside the now existing
1050 + * set of modules to let them all now that this module is
1055 + for (m2 = top_module; m2 != NULL; m2 = m2->next)
1056 + if (m2->magic == MODULE_MAGIC_COOKIE_EAPI)
1057 + if (m2->remove_module != NULL)
1058 + (*m2->remove_module)(m);
1064 /* We are the top module, special case */
1065 @@ -964,6 +993,27 @@
1066 const command_rec *cmd;
1067 module *mod = top_module;
1071 + * Invoke the `rewrite_command' of modules to allow
1072 + * they to rewrite the directive line before we
1078 + for (m = top_module; m != NULL; m = m->next) {
1079 + if (m->magic == MODULE_MAGIC_COOKIE_EAPI) {
1080 + if (m->rewrite_command != NULL) {
1081 + cp = (m->rewrite_command)(parms, config, l);
1090 if ((l[0] == '#') || (!l[0]))
1093 @@ -1424,6 +1474,10 @@
1094 s->limit_req_fieldsize = main_server->limit_req_fieldsize;
1095 s->limit_req_fields = main_server->limit_req_fields;
1098 + s->ctx = ap_ctx_new(p);
1103 return ap_parse_vhost_addrs(p, hostname, s);
1104 @@ -1535,6 +1589,10 @@
1105 s->module_config = create_server_config(p, s);
1106 s->lookup_defaults = create_default_per_dir_config(p);
1109 + s->ctx = ap_ctx_new(p);
1116 +---------------------------------------------------------------------------
1117 | Add the ap_global_ctx variable and the new
1118 | ap_add_config_define() function. Additionally the
1119 | implementation of the additional `new_connection' module hook
1120 | is added plus the initialization of one more `ctx' variable.
1121 +---------------------------------------------------------------------------
1122 Index: src/main/http_main.c
1123 --- src/main/http_main.c 11 May 2004 18:28:14 -0000 1.1.1.22
1124 +++ src/main/http_main.c 11 May 2004 18:32:15 -0000 1.44
1127 int ap_dump_settings = 0;
1128 API_VAR_EXPORT int ap_extended_status = 0;
1130 +API_VAR_EXPORT ap_ctx *ap_global_ctx;
1134 * The max child slot ever assigned, preserved across restarts. Necessary
1135 @@ -435,6 +438,30 @@
1140 +API_EXPORT(void) ap_add_config_define(const char *define)
1143 + var = (char **)ap_push_array(ap_server_config_defines);
1144 + *var = ap_pstrdup(pcommands, define);
1149 + * Invoke the `close_connection' hook of modules to let them do
1150 + * some connection dependent actions before we close it.
1152 +static void ap_call_close_connection_hook(conn_rec *c)
1155 + for (m = top_module; m != NULL; m = m->next)
1156 + if (m->magic == MODULE_MAGIC_COOKIE_EAPI)
1157 + if (m->close_connection != NULL)
1158 + (*m->close_connection)(c);
1164 static APACHE_TLS int volatile exit_after_unblock = 0;
1166 @@ -1541,6 +1568,10 @@
1167 ap_log_transaction(log_req);
1171 + ap_call_close_connection_hook(save_req->connection);
1174 ap_bsetflag(save_req->connection->client, B_EOUT, 1);
1175 ap_bclose(save_req->connection->client);
1177 @@ -1549,6 +1580,9 @@
1178 ap_longjmp(jmpbuffer, 1);
1180 else { /* abort the connection */
1182 + ap_call_close_connection_hook(current_conn);
1184 ap_bsetflag(current_conn->client, B_EOUT, 1);
1185 ap_bclose(current_conn->client);
1186 current_conn->aborted = 1;
1187 @@ -1851,10 +1885,16 @@
1188 /* Send any leftover data to the client, but never try to again */
1190 if (ap_bflush(r->connection->client) == -1) {
1192 + ap_call_close_connection_hook(r->connection);
1195 ap_bclose(r->connection->client);
1199 + ap_call_close_connection_hook(r->connection);
1201 ap_bsetflag(r->connection->client, B_EOUT, 1);
1203 /* Close our half of the connection --- send the client a FIN */
1204 @@ -2553,6 +2593,9 @@
1205 /* Clear the pool - including any registered cleanups */
1206 ap_destroy_pool(pglobal);
1209 + ap_kill_alloc_shared();
1214 @@ -3623,6 +3666,24 @@
1215 conn->remote_addr = *remaddr;
1216 conn->remote_ip = ap_pstrdup(conn->pool,
1217 inet_ntoa(conn->remote_addr.sin_addr));
1219 + conn->ctx = ap_ctx_new(conn->pool);
1224 + * Invoke the `new_connection' hook of modules to let them do
1225 + * some connection dependent actions before we go on with
1226 + * processing the request on this connection.
1230 + for (m = top_module; m != NULL; m = m->next)
1231 + if (m->magic == MODULE_MAGIC_COOKIE_EAPI)
1232 + if (m->new_connection != NULL)
1233 + (*m->new_connection)(conn);
1239 @@ -4133,6 +4194,15 @@
1240 printf("Server's Module Magic Number: %u:%u\n",
1241 MODULE_MAGIC_NUMBER_MAJOR, MODULE_MAGIC_NUMBER_MINOR);
1242 printf("Server compiled with....\n");
1244 + printf(" -D EAPI\n");
1247 + printf(" -D EAPI_MM\n");
1248 +#ifdef EAPI_MM_CORE_PATH
1249 + printf(" -D EAPI_MM_CORE_PATH=\"" EAPI_MM_CORE_PATH "\"\n");
1253 show_os_specific_compile_settings();
1255 @@ -4307,6 +4377,22 @@
1256 ap_server_pre_read_config = ap_make_array(pcommands, 1, sizeof(char *));
1257 ap_server_post_read_config = ap_make_array(pcommands, 1, sizeof(char *));
1258 ap_server_config_defines = ap_make_array(pcommands, 1, sizeof(char *));
1262 + ap_hook_configure("ap::buff::read",
1263 + AP_HOOK_SIG4(int,ptr,ptr,int), AP_HOOK_TOPMOST);
1264 + ap_hook_configure("ap::buff::write",
1265 + AP_HOOK_SIG4(int,ptr,ptr,int), AP_HOOK_TOPMOST);
1266 + ap_hook_configure("ap::buff::writev",
1267 + AP_HOOK_SIG4(int,ptr,ptr,int), AP_HOOK_TOPMOST);
1268 + ap_hook_configure("ap::buff::sendwithtimeout",
1269 + AP_HOOK_SIG4(int,ptr,ptr,int), AP_HOOK_TOPMOST);
1270 + ap_hook_configure("ap::buff::recvwithtimeout",
1271 + AP_HOOK_SIG4(int,ptr,ptr,int), AP_HOOK_TOPMOST);
1273 + ap_global_ctx = ap_ctx_new(NULL);
1278 @@ -4808,6 +4894,9 @@
1280 ap_sync_scoreboard_image();
1281 if (ap_scoreboard_image->global.running_generation != ap_my_generation) {
1283 + ap_call_close_connection_hook(current_conn);
1286 clean_child_exit(0);
1288 @@ -4836,6 +4925,9 @@
1293 + ap_call_close_connection_hook(current_conn);
1295 ap_bclose(conn_io); /* just close it */
1297 if (r && r->connection
1298 @@ -4846,6 +4938,9 @@
1303 + ap_call_close_connection_hook(current_conn);
1305 ap_bsetflag(conn_io, B_EOUT, 1);
1308 @@ -5619,16 +5714,31 @@
1313 + ap_init_alloc_shared(TRUE);
1316 ap_suexec_enabled = init_suexec();
1317 server_conf = ap_read_config(pconf, ptrans, ap_server_confname);
1320 + ap_init_alloc_shared(FALSE);
1323 if (ap_configtestonly) {
1324 fprintf(stderr, "Syntax OK\n");
1326 + clean_parent_exit(0);
1331 if (ap_dump_settings) {
1333 + clean_parent_exit(0);
1339 child_timeouts = !ap_standalone || one_process;
1340 @@ -5776,6 +5886,10 @@
1341 ap_destroy_pool(r->pool);
1345 + ap_call_close_connection_hook(conn);
1351 @@ -6152,6 +6266,9 @@
1352 ap_kill_cleanups_for_socket(ptrans, csd);
1356 + ap_call_close_connection_hook(current_conn);
1358 ap_bclose(conn_io); /* just close it */
1360 if (r && r->connection
1361 @@ -6162,6 +6279,9 @@
1366 + ap_call_close_connection_hook(current_conn);
1368 ap_bsetflag(conn_io, B_EOUT, 1);
1371 @@ -7737,6 +7857,10 @@
1372 if (!conf_specified)
1373 ap_cpystrn(ap_server_confname, SERVER_CONFIG_FILE, sizeof(ap_server_confname));
1376 + ap_init_alloc_shared(TRUE);
1379 if (!ap_os_is_path_absolute(ap_server_confname))
1380 ap_cpystrn(ap_server_confname,
1381 ap_server_root_relative(pcommands, ap_server_confname),
1382 @@ -7777,6 +7901,9 @@
1383 #else /* ndef WIN32 */
1384 server_conf = ap_read_config(pconf, ptrans, ap_server_confname);
1387 + ap_init_alloc_shared(FALSE);
1390 if (ap_configtestonly) {
1391 fprintf(stderr, "%s: Syntax OK\n", ap_server_root_relative(pcommands, ap_server_confname));
1393 +---------------------------------------------------------------------------
1394 | Just add the initialization of the `ctx' variable for
1395 | conn_rec structures.
1396 +---------------------------------------------------------------------------
1397 Index: src/main/http_request.c
1398 --- src/main/http_request.c 11 May 2004 18:28:15 -0000 1.1.1.18
1399 +++ src/main/http_request.c 11 May 2004 18:32:15 -0000 1.18
1400 @@ -1363,6 +1363,10 @@
1402 new->method = r->method;
1403 new->method_number = r->method_number;
1405 + /* initialize context _BEFORE_ ap_parse_uri() call */
1406 + new->ctx = r->ctx;
1408 ap_parse_uri(new, new_uri);
1409 new->request_config = ap_create_request_config(r->pool);
1410 new->per_dir_config = r->server->lookup_defaults;
1412 +---------------------------------------------------------------------------
1413 | Just add the initialization of the `ctx' variable for
1414 | request_rec structures.
1415 +---------------------------------------------------------------------------
1416 Index: src/main/http_protocol.c
1417 --- src/main/http_protocol.c 11 May 2004 18:28:15 -0000 1.1.1.20
1418 +++ src/main/http_protocol.c 11 May 2004 18:32:15 -0000 1.20
1419 @@ -1160,6 +1160,10 @@
1420 r->status = HTTP_REQUEST_TIME_OUT; /* Until we get a request */
1421 r->the_request = NULL;
1424 + r->ctx = ap_ctx_new(r->pool);
1427 #ifdef CHARSET_EBCDIC
1428 ap_bsetflag(r->connection->client, B_ASCII2EBCDIC, r->ebcdic.conv_in = 1);
1429 ap_bsetflag(r->connection->client, B_EBCDIC2ASCII, r->ebcdic.conv_out = 1);
1430 @@ -1316,6 +1320,11 @@
1431 rnew->read_body = REQUEST_NO_BODY;
1433 rnew->main = (request_rec *) r;
1436 + rnew->ctx = r->ctx;
1441 API_EXPORT(void) ap_finalize_sub_req_protocol(request_rec *sub)
1443 +---------------------------------------------------------------------------
1444 | Add support for loading both EAPI and AP13 modules.
1445 +---------------------------------------------------------------------------
1446 Index: src/modules/standard/mod_so.c
1447 --- src/modules/standard/mod_so.c 11 May 2004 18:28:20 -0000 1.1.1.11
1448 +++ src/modules/standard/mod_so.c 11 May 2004 18:32:16 -0000 1.12
1449 @@ -226,11 +226,24 @@
1450 * Make sure the found module structure is really a module structure
1454 + if ( modp->magic != MODULE_MAGIC_COOKIE_AP13
1455 + && modp->magic != MODULE_MAGIC_COOKIE_EAPI) {
1457 if (modp->magic != MODULE_MAGIC_COOKIE) {
1459 return ap_pstrcat(cmd->pool, "API module structure `", modname,
1460 "' in file ", szModuleFile, " is garbled -"
1461 " perhaps this is not an Apache module DSO?", NULL);
1464 + if (modp->magic == MODULE_MAGIC_COOKIE_AP13) {
1465 + ap_log_error(APLOG_MARK, APLOG_WARNING|APLOG_NOERRNO, NULL,
1466 + "Loaded DSO %s uses plain Apache 1.3 API, "
1467 + "this module might crash under EAPI! "
1468 + "(please recompile it with -DEAPI)", filename);
1473 * Add this module to the Apache core structures
1475 +---------------------------------------------------------------------------
1476 | Add additional logging functions to the CustomLog directive
1477 | which can be used by other modules to create additional
1478 | logfile tags. Actually we add two types of hooks: One hook
1479 | for intercepting the new and generic %x (eXtension) tag and
1480 | one hook for creating new %x tags at all.
1481 +---------------------------------------------------------------------------
1482 Index: src/modules/standard/mod_log_config.c
1483 --- src/modules/standard/mod_log_config.c 11 May 2004 18:28:20 -0000 1.1.1.15
1484 +++ src/modules/standard/mod_log_config.c 11 May 2004 18:32:16 -0000 1.28
1486 typedef const char *(*item_key_func) (request_rec *, char *);
1494 int condition_sense;
1495 @@ -541,15 +544,36 @@
1500 +static struct log_item_list *find_log_func(pool *p, char k)
1502 static struct log_item_list *find_log_func(char k)
1507 + struct log_item_list *lil;
1510 for (i = 0; log_item_keys[i].ch; ++i)
1511 if (k == log_item_keys[i].ch) {
1512 return &log_item_keys[i];
1516 + if (ap_hook_status(ap_psprintf(p, "ap::mod_log_config::log_%c", k))
1517 + != AP_HOOK_STATE_NOTEXISTANT) {
1518 + lil = (struct log_item_list *)
1519 + ap_pcalloc(p, sizeof(struct log_item_list));
1524 + lil->want_orig_default = 0;
1532 @@ -675,7 +699,11 @@
1537 + l = find_log_func(p, *s++);
1539 l = find_log_func(*s++);
1545 return ap_pstrcat(p, "Unrecognized LogFormat directive %",
1552 if (it->want_orig == -1) {
1553 it->want_orig = l->want_orig_default;
1554 @@ -745,6 +776,15 @@
1556 /* We do. Do it... */
1559 + if (item->func == NULL) {
1561 + ap_hook_use(ap_psprintf(r->pool, "ap::mod_log_config::log_%c", item->ch),
1562 + AP_HOOK_SIG3(ptr,ptr,ptr), AP_HOOK_DECLINE(NULL),
1563 + &cp, r, item->arg);
1567 cp = (*item->func) (item->want_orig ? orig : r, item->arg);
1568 return cp ? cp : "-";
1571 +---------------------------------------------------------------------------
1572 | Allow RewriteCond and RewriteRule directives to lookup
1573 | variables from other modules.
1574 +---------------------------------------------------------------------------
1575 Index: src/modules/standard/mod_rewrite.c
1576 --- src/modules/standard/mod_rewrite.c 11 May 2004 18:28:20 -0000 1.1.1.19
1577 +++ src/modules/standard/mod_rewrite.c 11 May 2004 18:32:16 -0000 1.17
1578 @@ -3848,6 +3848,15 @@
1580 #endif /* ndef WIN32 && NETWARE*/
1584 + ap_hook_use("ap::mod_rewrite::lookup_variable",
1585 + AP_HOOK_SIG3(ptr,ptr,ptr),
1586 + AP_HOOK_DECLINE(NULL),
1591 if (result == NULL) {
1592 return ap_pstrdup(r->pool, "");
1595 +---------------------------------------------------------------------------
1596 | Add an EAPI hook to allow other modules to add content to
1597 | the status HTML page.
1598 +---------------------------------------------------------------------------
1599 Index: src/modules/standard/mod_status.c
1600 --- src/modules/standard/mod_status.c 11 May 2004 18:28:20 -0000 1.1.1.16
1601 +++ src/modules/standard/mod_status.c 11 May 2004 18:32:16 -0000 1.13
1602 @@ -651,12 +677,23 @@
1604 "<td>?<td nowrap>?<td nowrap>..reading.. </tr>\n\n");
1606 +#ifndef NO_PRETTYPRINT
1608 + "<td nowrap><font face=\"Arial,Helvetica\" size=\"-1\">%s</font>"
1609 + "<td nowrap><font face=\"Arial,Helvetica\" size=\"-1\">%s</font>"
1610 + "<td nowrap><font face=\"Arial,Helvetica\" size=\"-1\">%s</font>"
1612 + score_record.client,
1613 + vhost ? vhost->server_hostname : "(unavailable)",
1614 + ap_escape_html(r->pool, score_record.request));
1617 "<td>%s<td nowrap>%s<td nowrap>%s</tr>\n\n",
1618 ap_escape_html(r->pool, score_record.client),
1619 vhost ? ap_escape_html(r->pool,
1620 vhost->server_hostname) : "(unavailable)",
1621 ap_escape_html(r->pool, score_record.request));
1623 } /* no_table_report */
1624 } /* !short_report */
1625 } /* if (<active child>) */
1627 +---------------------------------------------------------------------------
1628 | Add hooks to the scheme processing to allow other modules to
1629 | recognize more schemes by intercepting this processing.
1630 +---------------------------------------------------------------------------
1631 Index: src/modules/proxy/mod_proxy.c
1632 --- src/modules/proxy/mod_proxy.c 11 May 2004 18:28:16 -0000 1.1.1.14
1633 +++ src/modules/proxy/mod_proxy.c 11 May 2004 18:32:15 -0000 1.21
1635 static int proxy_fixup(request_rec *r)
1642 if (r->proxyreq == NOT_PROXY || strncmp(r->filename, "proxy:", 6) != 0)
1644 @@ -182,6 +185,14 @@
1645 url = &r->filename[6];
1647 /* canonicalise each specific scheme */
1649 + if (ap_hook_use("ap::mod_proxy::canon",
1650 + AP_HOOK_SIG3(int,ptr,ptr),
1651 + AP_HOOK_DECLINE(DECLINED),
1652 + &rc, r, url) && rc != DECLINED)
1656 if (strncasecmp(url, "http:", 5) == 0)
1657 return ap_proxy_http_canon(r, url + 5, "http", DEFAULT_HTTP_PORT);
1658 else if (strncasecmp(url, "ftp:", 4) == 0)
1659 @@ -197,9 +208,44 @@
1660 static void proxy_init(server_rec *r, pool *p)
1662 ap_proxy_garbage_init(r, p);
1664 + ap_hook_use("ap::mod_proxy::init",
1665 + AP_HOOK_SIG3(void,ptr,ptr), AP_HOOK_ALL, r, p);
1671 +static void proxy_addmod(module *m)
1673 + /* export: ap_proxy_http_canon() as `ap::mod_proxy::http::canon' */
1674 + ap_hook_configure("ap::mod_proxy::http::canon",
1675 + AP_HOOK_SIG5(int,ptr,ptr,ptr,int), AP_HOOK_TOPMOST);
1676 + ap_hook_register("ap::mod_proxy::http::canon",
1677 + ap_proxy_http_canon, AP_HOOK_NOCTX);
1679 + /* export: ap_proxy_http_handler() as `ap::mod_proxy::http::handler' */
1680 + ap_hook_configure("ap::mod_proxy::http::handler",
1681 + AP_HOOK_SIG6(int,ptr,ptr,ptr,ptr,int), AP_HOOK_TOPMOST);
1682 + ap_hook_register("ap::mod_proxy::http::handler",
1683 + ap_proxy_http_handler, AP_HOOK_NOCTX);
1685 + /* export: ap_proxyerror() as `ap::mod_proxy::error' */
1686 + ap_hook_configure("ap::mod_proxy::error",
1687 + AP_HOOK_SIG3(int,ptr,ptr), AP_HOOK_TOPMOST);
1688 + ap_hook_register("ap::mod_proxy::error",
1689 + ap_proxyerror, AP_HOOK_NOCTX);
1693 +static void proxy_remmod(module *m)
1695 + /* remove the hook references */
1696 + ap_hook_unregister("ap::mod_proxy::http::canon", ap_proxy_http_canon);
1697 + ap_hook_unregister("ap::mod_proxy::http::handler", ap_proxy_http_handler);
1698 + ap_hook_unregister("ap::mod_proxy::error", ap_proxyerror);
1703 /* Send a redirection if the request contains a hostname which is not */
1704 /* fully qualified, i.e. doesn't have a domain name appended. Some proxy */
1705 @@ -331,6 +377,14 @@
1706 * CONNECT is a special method that bypasses the normal proxy
1710 + if (!ap_hook_use("ap::mod_proxy::handler",
1711 + AP_HOOK_SIG7(int,ptr,ptr,ptr,ptr,int,ptr),
1712 + AP_HOOK_DECLINE(DECLINED),
1714 + ents[i].hostname, ents[i].port,
1715 + ents[i].protocol) || rc == DECLINED) {
1717 if (r->method_number == M_CONNECT)
1718 rc = ap_proxy_connect_handler(r, cr, url, ents[i].hostname,
1728 /* an error or success */
1729 if (rc != DECLINED && rc != HTTP_BAD_GATEWAY)
1730 @@ -354,6 +411,14 @@
1733 /* handle the scheme */
1735 + if (ap_hook_use("ap::mod_proxy::handler",
1736 + AP_HOOK_SIG7(int,ptr,ptr,ptr,ptr,int,ptr),
1737 + AP_HOOK_DECLINE(DECLINED),
1739 + NULL, 0, scheme) && rc != DECLINED)
1742 if (r->method_number == M_CONNECT) {
1743 return ap_proxy_connect_handler(r, cr, url, NULL, 0);
1745 @@ -951,4 +1016,10 @@
1746 NULL, /* child_init */
1747 NULL, /* child_exit */
1748 proxy_detect /* post read-request */
1750 + ,proxy_addmod, /* EAPI: add_module */
1751 + proxy_remmod, /* EAPI: remove_module */
1752 + NULL, /* EAPI: rewrite_command */
1753 + NULL /* EAPI: new_connection */
1757 +---------------------------------------------------------------------------
1758 | Add hooks to the HTTP processing to allow other modules
1759 | to enhance it by intercepting this processing.
1760 +---------------------------------------------------------------------------
1761 Index: src/modules/proxy/proxy_http.c
1762 --- src/modules/proxy/proxy_http.c 11 May 2004 18:28:18 -0000 1.1.1.17
1763 +++ src/modules/proxy/proxy_http.c 11 May 2004 18:32:16 -0000 1.25
1765 const char *datestr, *urlstr;
1766 int result, major, minor;
1767 const char *content_length;
1772 void *sconf = r->server->module_config;
1773 proxy_server_conf *conf =
1774 @@ -148,6 +151,12 @@
1775 return HTTP_BAD_REQUEST;
1777 destport = DEFAULT_HTTP_PORT;
1779 + ap_hook_use("ap::mod_proxy::http::handler::set_destport",
1780 + AP_HOOK_SIG2(int,ptr),
1784 strp = strchr(urlptr, '/');
1786 desthost = ap_pstrdup(p, urlptr);
1787 @@ -185,12 +194,18 @@
1788 err = ap_proxy_host2addr(proxyhost, &server_hp);
1790 return DECLINED; /* try another */
1792 + peer = ap_psprintf(p, "%s:%u", proxyhost, proxyport);
1796 server.sin_port = htons((unsigned short)destport);
1797 err = ap_proxy_host2addr(desthost, &server_hp);
1799 return ap_proxyerror(r, HTTP_INTERNAL_SERVER_ERROR, err);
1801 + peer = ap_psprintf(p, "%s:%u", desthost, destport);
1806 @@ -275,14 +290,42 @@
1807 f = ap_bcreate(p, B_RDWR | B_SOCKET);
1808 ap_bpushfd(f, sock, sock);
1812 + char *errmsg = NULL;
1813 + ap_hook_use("ap::mod_proxy::http::handler::new_connection",
1814 + AP_HOOK_SIG4(ptr,ptr,ptr,ptr),
1815 + AP_HOOK_DECLINE(NULL),
1816 + &errmsg, r, f, peer);
1817 + if (errmsg != NULL)
1818 + return ap_proxyerror(r, HTTP_BAD_GATEWAY, errmsg);
1822 ap_hard_timeout("proxy send", r);
1823 ap_bvputs(f, r->method, " ", proxyhost ? url : urlptr, " HTTP/1.1" CRLF,
1827 + int rc = DECLINED;
1828 + ap_hook_use("ap::mod_proxy::http::handler::write_host_header",
1829 + AP_HOOK_SIG6(int,ptr,ptr,ptr,int,ptr),
1830 + AP_HOOK_DECLINE(DECLINED),
1831 + &rc, r, f, desthost, destport, destportstr);
1832 + if (rc == DECLINED) {
1833 + if (destportstr != NULL && destport != DEFAULT_HTTP_PORT)
1834 + ap_bvputs(f, "Host: ", desthost, ":", destportstr, CRLF, NULL);
1836 + ap_bvputs(f, "Host: ", desthost, CRLF, NULL);
1840 /* Send Host: now, adding it to req_hdrs wouldn't be much better */
1841 if (destportstr != NULL && destport != DEFAULT_HTTP_PORT)
1842 ap_bvputs(f, "Host: ", desthost, ":", destportstr, CRLF, NULL);
1844 ap_bvputs(f, "Host: ", desthost, CRLF, NULL);
1847 if (conf->viaopt == via_block) {
1848 /* Block all outgoing Via: headers */
1850 +---------------------------------------------------------------------------
1851 | Add EAPI hooks in module structure for APXS generated samples.
1852 +---------------------------------------------------------------------------
1853 Index: src/support/apxs.pl
1854 --- src/support/apxs.pl 11 May 2004 18:28:26 -0000 1.1.1.14
1855 +++ src/support/apxs.pl 11 May 2004 18:32:16 -0000 1.14
1856 @@ -752,5 +752,11 @@
1857 NULL, /* child_init */
1858 NULL, /* child_exit */
1859 NULL /* [#0] post read-request */
1861 + ,NULL, /* EAPI: add_module */
1862 + NULL, /* EAPI: remove_module */
1863 + NULL, /* EAPI: rewrite_command */
1864 + NULL /* EAPI: new_connection */
1869 +---------------------------------------------------------------------------
1870 | Add the EAPI functions, so the stuff can be built under AIX
1871 | and similar braindead platforms as DSO.
1872 +---------------------------------------------------------------------------
1873 Index: src/support/httpd.exp
1874 --- src/support/httpd.exp 11 May 2004 18:28:26 -0000 1.1.1.13
1875 +++ src/support/httpd.exp 11 May 2004 18:32:16 -0000 1.15
1876 @@ -431,3 +431,59 @@
1877 XML_SetUnparsedEntityDeclHandler
1879 XML_UseParserAsHandlerArg
1880 +ap_add_config_define
1881 +ap_make_shared_sub_pool
1890 +ap_hook_unregister_I
1925 +ap_mm_core_permission
1930 +ap_mm_core_maxsegsize
1931 +ap_mm_core_align2page
1932 +ap_mm_core_align2word
1933 +ap_mm_lib_error_set
1934 +ap_mm_lib_error_get
1937 +---------------------------------------------------------------------------
1938 | Add the EAPI functions, so the stuff can be built under
1939 | Windows 95 and similar braindead platforms as DDL.
1940 +---------------------------------------------------------------------------
1941 Index: src/ApacheCore.def
1942 --- src/ApacheCore.def 11 May 2004 18:28:08 -0000 1.1.1.11
1943 +++ src/ApacheCore.def 11 May 2004 18:32:15 -0000 1.15
1944 @@ -448,3 +448,67 @@
1945 ap_get_chunk_size @440
1946 ap_escape_logitem @441
1949 + ; EAPI extended symbols
1950 + ; note; no ID's, so these all bind by name rather than ordinal since
1951 + ; their ordinals would change with symbol changes in the distribution
1952 + ap_add_config_define
1953 + ap_global_ctx DATA
1961 + ap_hook_register_I
1962 + ap_hook_unregister_I
1966 + ap_set_callback_and_alarm
1968 + ap_make_shared_sub_pool
1999 + ap_mm_display_info
2001 + ap_mm_core_permission
2006 + ap_mm_core_align2page
2007 + ap_mm_core_align2word
2008 + ap_mm_lib_error_set
2009 + ap_mm_lib_error_get