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: 30-Mar-2001
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 1999/08/17 11:21:38 1.1.1.5
28 +++ src/Configuration.tmpl 2000/10/09 12:15:02 1.21
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 2001/02/28 19:40:46 1.1.1.14
60 +++ src/Configure 2001/02/28 19:44:33 1.16
61 @@ -1808,6 +1808,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 | tail -1 | 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.
133 if [ -d ./lib/expat-lite/ ]; then
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 2000/10/12 08:17:28 1.1.1.6
140 +++ src/ap/Makefile.tmpl 2000/10/12 08:31:47 1.6
144 OBJS=ap_cpystrn.o ap_execve.o ap_fnmatch.o ap_getpass.o ap_md5c.o ap_signal.o \
145 - ap_slack.o ap_snprintf.o ap_sha1.o ap_checkpass.o ap_base64.o
146 + ap_slack.o ap_snprintf.o ap_sha1.o ap_checkpass.o ap_base64.o \
147 + ap_hook.o ap_ctx.o ap_mm.o
150 $(CC) -c $(INCLUDES) $(CFLAGS) $<
152 +---------------------------------------------------------------------------
153 | Add the build support for the ap_hook.c and ap_ctx.c sources (Win32)
154 +---------------------------------------------------------------------------
156 --- src/ap/ap.mak 2001/01/23 11:35:02 1.1.1.7
157 +++ src/ap/ap.mak 2001/01/23 11:48:05 1.7
159 -@erase "$(INTDIR)\ap_cpystrn.obj"
160 -@erase "$(INTDIR)\ap_fnmatch.obj"
161 -@erase "$(INTDIR)\ap_md5c.obj"
162 + -@erase "$(INTDIR)\ap_hook.obj"
163 + -@erase "$(INTDIR)\ap_ctx.obj"
164 + -@erase "$(INTDIR)\ap_mm.obj"
165 -@erase "$(INTDIR)\ap_sha1.obj"
166 -@erase "$(INTDIR)\ap_signal.obj"
167 -@erase "$(INTDIR)\ap_slack.obj"
169 "$(INTDIR)\ap_cpystrn.obj" \
170 "$(INTDIR)\ap_fnmatch.obj" \
171 "$(INTDIR)\ap_md5c.obj" \
172 + "$(INTDIR)\ap_hook.obj" \
173 + "$(INTDIR)\ap_ctx.obj" \
174 + "$(INTDIR)\ap_mm.obj" \
175 "$(INTDIR)\ap_sha1.obj" \
176 "$(INTDIR)\ap_signal.obj" \
177 "$(INTDIR)\ap_slack.obj" \
179 -@erase "$(INTDIR)\ap_cpystrn.obj"
180 -@erase "$(INTDIR)\ap_fnmatch.obj"
181 -@erase "$(INTDIR)\ap_md5c.obj"
182 + -@erase "$(INTDIR)\ap_hook.obj"
183 + -@erase "$(INTDIR)\ap_ctx.obj"
184 + -@erase "$(INTDIR)\ap_mm.obj"
185 -@erase "$(INTDIR)\ap_sha1.obj"
186 -@erase "$(INTDIR)\ap_signal.obj"
187 -@erase "$(INTDIR)\ap_slack.obj"
189 "$(INTDIR)\ap_cpystrn.obj" \
190 "$(INTDIR)\ap_fnmatch.obj" \
191 "$(INTDIR)\ap_md5c.obj" \
192 + "$(INTDIR)\ap_hook.obj" \
193 + "$(INTDIR)\ap_ctx.obj" \
194 + "$(INTDIR)\ap_mm.obj" \
195 "$(INTDIR)\ap_sha1.obj" \
196 "$(INTDIR)\ap_signal.obj" \
197 "$(INTDIR)\ap_slack.obj" \
199 +---------------------------------------------------------------------------
200 | Replace the MODULE_MAGIC_COOKIE to allow us to distinguish between
201 | EAPI-aware modules and standard modules.
202 +---------------------------------------------------------------------------
203 Index: src/include/ap_mmn.h
204 --- src/include/ap_mmn.h 2001/01/23 11:35:07 1.1.1.8
205 +++ src/include/ap_mmn.h 2001/01/23 11:48:05 1.8
207 * 19990320.10 - add ap_is_rdirectory() and ap_stripprefix()
211 + * Under Extended API situations we replace the magic cookie "AP13" with
212 + * "EAPI" to let us distinguish between the EAPI module structure (which
213 + * contain additional pointers at the end) and standard module structures
214 + * (which lack at least NULL's for the pointers at the end). This is
215 + * important because standard ("AP13") modules would dump core when we
216 + * dispatch over the additional hooks because NULL's are missing at the end of
217 + * the module structure. See also the code in mod_so for details on loading
218 + * (we accept both "AP13" and "EAPI").
221 +#define MODULE_MAGIC_COOKIE_AP13 0x41503133UL /* "AP13" */
222 +#define MODULE_MAGIC_COOKIE_EAPI 0x45415049UL /* "EAPI" */
223 +#define MODULE_MAGIC_COOKIE MODULE_MAGIC_COOKIE_EAPI
225 #define MODULE_MAGIC_COOKIE 0x41503133UL /* "AP13" */
228 #ifndef MODULE_MAGIC_NUMBER_MAJOR
229 #define MODULE_MAGIC_NUMBER_MAJOR 19990320
231 +---------------------------------------------------------------------------
232 | Add the additional prototypes and defines for the
233 | shared memory pools.
234 +---------------------------------------------------------------------------
235 Index: src/include/ap_alloc.h
236 --- src/include/ap_alloc.h 2001/02/28 19:40:47 1.1.1.3
237 +++ src/include/ap_alloc.h 2001/02/28 19:44:33 1.4
239 pool * ap_init_alloc(void); /* Set up everything */
240 void ap_cleanup_alloc(void);
241 API_EXPORT(pool *) ap_make_sub_pool(pool *); /* All pools are subpools of permanent_pool */
243 +typedef enum { AP_POOL_RD, AP_POOL_RW } ap_pool_lock_mode;
244 +int ap_shared_pool_possible(void);
245 +void ap_init_alloc_shared(int);
246 +void ap_kill_alloc_shared(void);
247 +API_EXPORT(pool *) ap_make_shared_sub_pool(pool *);
248 +API_EXPORT(int) ap_acquire_pool(pool *, ap_pool_lock_mode);
249 +API_EXPORT(int) ap_release_pool(pool *);
251 API_EXPORT(void) ap_destroy_pool(pool *);
253 /* pools have nested lifetimes -- sub_pools are destroyed when the
255 +---------------------------------------------------------------------------
256 | Add the additional context variable `ctx' for BUFF structures.
257 +---------------------------------------------------------------------------
258 Index: src/include/buff.h
259 --- src/include/buff.h 2001/01/23 11:35:07 1.1.1.4
260 +++ src/include/buff.h 2001/01/23 11:48:05 1.8
262 /* transport handle, for RPC binding handle or some such */
273 /* Internal routines */
274 API_EXPORT(int) ap_bflsbuf(int c, BUFF *fb);
275 API_EXPORT(int) ap_bfilbuf(BUFF *fb);
278 +#define ap_bpeekc(fb) ( ((fb)->incnt == 0) ? EOF : *((fb)->inptr) )
281 #ifndef CHARSET_EBCDIC
284 +---------------------------------------------------------------------------
285 | Add the four additional Apache API module hooks.
286 +---------------------------------------------------------------------------
287 Index: src/include/http_config.h
288 --- src/include/http_config.h 2001/01/23 11:35:07 1.1.1.8
289 +++ src/include/http_config.h 2001/01/23 11:48:05 1.10
291 void (*child_exit) (server_rec *, pool *);
293 int (*post_read_request) (request_rec *);
297 + * ANSI C guarantees us that we can at least _extend_ the module structure
298 + * with additional hooks without the need to change all existing modules.
299 + * Because: ``If there are fewer initializers in the list than members of
300 + * the structure, the trailing members are initialized with 0.'' (The C
301 + * Programming Language, 2nd Ed., A8.7 Initialization). So we just
302 + * have to put our additional hooks here:
305 + * Called from within ap_add_module() right after the module structure
306 + * was linked into the Apache internal module list. It is mainly
307 + * intended to be used to define configuration defines (<IfDefine>)
308 + * which have to be available directly after a LoadModule/AddModule.
309 + * Actually this is the earliest possible hook a module can use.
312 + * Called from within ap_remove_module() right before the module
313 + * structure is kicked out from the Apache internal module list.
314 + * Actually this is last possible hook a module can use and exists for
315 + * consistency with the add_module hook.
318 + * Called right after a configuration directive line was read and
319 + * before it is processed. It is mainly intended to be used for
320 + * rewriting directives in order to provide backward compatibility to
321 + * old directive variants.
324 + * Called from within the internal new_connection() function, right
325 + * after the conn_rec structure for the new established connection was
326 + * created and before Apache starts processing the request with
327 + * ap_read_request(). It is mainly intended to be used to setup/run
328 + * connection dependent things like sending start headers for
329 + * on-the-fly compression, etc.
331 + * close_connection:
332 + * Called from within the Apache dispatching loop just before any
333 + * ap_bclose() is performed on the socket connection, but a long time
334 + * before any pool cleanups are done for the connection (which can be
335 + * too late for some applications). It is mainly intended to be used
336 + * to close/finalize connection dependent things like sending end
337 + * headers for on-the-fly compression, etc.
339 +#ifdef ULTRIX_BRAIN_DEATH
340 + void (*add_module) ();
341 + void (*remove_module) ();
342 + char *(*rewrite_command) ();
343 + void (*new_connection) ();
344 + void (*close_connection) ();
346 + void (*add_module) (struct module_struct *);
347 + void (*remove_module) (struct module_struct *);
348 + char *(*rewrite_command) (cmd_parms *, void *config, const char *);
349 + void (*new_connection) (conn_rec *);
350 + void (*close_connection) (conn_rec *);
355 /* Initializer for the first few module slots, which are only
357 +---------------------------------------------------------------------------
358 | Add the additional variable `ap_global_ctx' for holding
359 | global module context.
360 +---------------------------------------------------------------------------
361 Index: src/include/http_conf_globals.h
362 --- src/include/http_conf_globals.h 2001/01/23 11:35:07 1.1.1.8
363 +++ src/include/http_conf_globals.h 2001/01/23 11:48:05 1.9
365 extern int ap_listenbacklog;
366 extern int ap_dump_settings;
367 extern API_VAR_EXPORT int ap_extended_status;
369 +extern API_VAR_EXPORT ap_ctx *ap_global_ctx;
372 extern API_VAR_EXPORT char *ap_pid_fname;
373 extern API_VAR_EXPORT char *ap_scoreboard_fname;
375 +---------------------------------------------------------------------------
376 | Export the ap_set_callback_and_alarm() function because this
377 | first is a useful thing and second we need it because all
378 | other API/timeout functions deal with a request_rec while
379 | some modules need a generic timeout mechanism.
380 +---------------------------------------------------------------------------
381 Index: src/include/http_main.h
382 --- src/include/http_main.h 2001/01/23 11:35:07 1.1.1.5
383 +++ src/include/http_main.h 2001/01/23 11:48:05 1.5
385 API_EXPORT(void) ap_sync_scoreboard_image(void);
386 int ap_update_child_status(int child_num, int status, request_rec *r);
387 void ap_time_process_request(int child_num, int status);
389 +API_EXPORT(unsigned int) ap_set_callback_and_alarm(void (*fn) (int), int x);
391 unsigned int ap_set_callback_and_alarm(void (*fn) (int), int x);
393 API_EXPORT(int) ap_check_alarm(void);
395 void setup_signal_names(char *prefix);
397 +---------------------------------------------------------------------------
398 | First add support for the HTTPS protocol scheme via hooks,
399 | second add the additional context variable `ctx' for the
400 | conn_rec, server_rec and request_rec structures. And third
401 | add a prototype for the additional ap_add_config_define()
403 +---------------------------------------------------------------------------
404 Index: src/include/httpd.h
405 --- src/include/httpd.h 2001/02/28 19:40:48 1.1.1.14
406 +++ src/include/httpd.h 2001/02/28 19:44:33 1.23
408 /* Headers in which EVERYONE has an interest... */
410 #include "ap_config.h"
414 #include "ap_alloc.h"
416 + * Include the Extended API headers.
417 + * Don't move the position. It has to be after ap_alloc.h because it uses the
418 + * pool stuff but before buff.h because the buffer stuff uses the EAPI, too.
421 +#include "ap_hook.h"
428 #define DEFAULT_HTTP_PORT 80
429 #define DEFAULT_HTTPS_PORT 443
430 #define ap_is_default_port(port,r) ((port) == ap_default_port(r))
432 +#define ap_http_method(r) (ap_ctx_get((r)->ctx, "ap::http::method") != NULL ? ((char *)ap_ctx_get((r)->ctx, "ap::http::method")) : "http")
433 +#define ap_default_port(r) (ap_ctx_get((r)->ctx, "ap::default::port") != NULL ? atoi((char *)ap_ctx_get((r)->ctx, "ap::default::port")) : DEFAULT_HTTP_PORT)
435 #define ap_http_method(r) "http"
436 #define ap_default_port(r) DEFAULT_HTTP_PORT
439 /* --------- Default user name and group name running standalone ---------- */
440 /* --- These may be specified as numbers by placing a # before a number --- */
442 #define SCOREBOARD_MAINTENANCE_INTERVAL 1000000
447 + * Path to Shared Memory Files
450 +#ifndef EAPI_MM_CORE_PATH
451 +#define EAPI_MM_CORE_PATH "logs/mm"
453 +#ifndef EAPI_MM_CORE_MAXSIZE
454 +#define EAPI_MM_CORE_MAXSIZE 1024*1024*1 /* max. 1MB */
458 /* Number of requests to try to handle in a single process. If <= 0,
459 * the children don't die off. That's the default here, since I'm still
460 * interested in finding and stanching leaks.
462 API_EXPORT(const char *) ap_get_server_version(void);
463 API_EXPORT(void) ap_add_version_component(const char *component);
464 API_EXPORT(const char *) ap_get_server_built(void);
466 +API_EXPORT(void) ap_add_config_define(const char *define);
469 /* Numeric release version identifier: MMNNFFRBB: major minor fix final beta
470 * Always increases along the same track as the source branch.
472 * record to improve 64bit alignment the next time we need to break
473 * binary compatibility for some other reason.
483 char *local_host; /* used for ap_get_server_name when
484 * UseCanonicalName is set to DNS
485 * (ignores setting of HostnameLookups) */
491 /* Per-vhost config... */
493 int limit_req_line; /* limit on size of the HTTP request line */
494 int limit_req_fieldsize; /* limit on size of any request header field */
495 int limit_req_fields; /* limit on number of request header fields */
502 /* These are more like real hosts than virtual hosts */
504 +---------------------------------------------------------------------------
505 | Patch the shared memory pool support into the Apache pool facility.
506 +---------------------------------------------------------------------------
507 Index: src/main/alloc.c
508 --- src/main/alloc.c 2001/01/23 11:35:08 1.1.1.10
509 +++ src/main/alloc.c 2001/01/23 11:48:05 1.17
515 +#include "http_config.h"
516 +#include "http_conf_globals.h"
518 #include "multithread.h"
519 #include "http_log.h"
522 #define BLOCK_MINALLOC 0
525 +#if defined(EAPI) && defined(EAPI_MM)
526 +static AP_MM *mm = NULL;
529 /*****************************************************************
531 * Managing free storage blocks...
534 union block_hdr *next;
536 +#if defined(EAPI) && defined(EAPI_MM)
540 union block_hdr *global_next;
541 struct pool *owning_pool;
543 /* Get a completely new block from the system pool. Note that we rely on
544 malloc() to provide aligned memory. */
546 +#if defined(EAPI) && defined(EAPI_MM)
547 +static union block_hdr *malloc_block(int size, int is_shm)
549 static union block_hdr *malloc_block(int size)
552 union block_hdr *blok;
554 @@ -230,12 +245,20 @@
556 num_malloc_bytes += size + sizeof(union block_hdr);
558 +#if defined(EAPI) && defined(EAPI_MM)
560 + blok = (union block_hdr *)ap_mm_malloc(mm, size + sizeof(union block_hdr));
563 blok = (union block_hdr *) malloc(size + sizeof(union block_hdr));
565 fprintf(stderr, "Ouch! malloc failed in malloc_block()\n");
568 debug_fill(blok, size + sizeof(union block_hdr));
569 +#if defined(EAPI) && defined(EAPI_MM)
570 + blok->h.is_shm = is_shm;
573 blok->h.first_avail = (char *) (blok + 1);
574 blok->h.endp = size + blok->h.first_avail;
577 return; /* Sanity check --- freeing empty pool? */
579 +#if defined(EAPI) && defined(EAPI_MM)
580 + if (blok->h.is_shm)
581 + (void)ap_mm_lock(mm, AP_MM_LOCK_RW);
583 (void) ap_acquire_mutex(alloc_mutex);
584 old_free_list = block_freelist;
585 block_freelist = blok;
589 (void) ap_release_mutex(alloc_mutex);
590 +#if defined(EAPI) && defined(EAPI_MM)
591 + if (blok->h.is_shm)
592 + (void)ap_mm_unlock(mm);
599 * if necessary. Must be called with alarms blocked.
602 +#if defined(EAPI) && defined(EAPI_MM)
603 +static union block_hdr *new_block(int min_size, int is_shm)
605 static union block_hdr *new_block(int min_size)
608 union block_hdr **lastptr = &block_freelist;
609 union block_hdr *blok = block_freelist;
613 while (blok != NULL) {
614 +#if defined(EAPI) && defined(EAPI_MM)
615 + if (blok->h.is_shm == is_shm &&
616 + min_size + BLOCK_MINFREE <= blok->h.endp - blok->h.first_avail) {
618 if (min_size + BLOCK_MINFREE <= blok->h.endp - blok->h.first_avail) {
620 *lastptr = blok->h.next;
622 debug_verify_filled(blok->h.first_avail, blok->h.endp,
626 min_size += BLOCK_MINFREE;
627 +#if defined(EAPI) && defined(EAPI_MM)
628 + blok = malloc_block((min_size > BLOCK_MINALLOC) ? min_size : BLOCK_MINALLOC, is_shm);
630 blok = malloc_block((min_size > BLOCK_MINALLOC) ? min_size : BLOCK_MINALLOC);
639 +#if defined(EAPI) && defined(EAPI_MM)
644 static pool *permanent_pool;
645 @@ -440,16 +487,28 @@
646 #define POOL_HDR_CLICKS (1 + ((sizeof(struct pool) - 1) / CLICK_SZ))
647 #define POOL_HDR_BYTES (POOL_HDR_CLICKS * CLICK_SZ)
649 +#if defined(EAPI) && defined(EAPI_MM)
650 +static struct pool *make_sub_pool_internal(struct pool *p, int is_shm)
652 API_EXPORT(struct pool *) ap_make_sub_pool(struct pool *p)
655 union block_hdr *blok;
660 +#if defined(EAPI) && defined(EAPI_MM)
662 + (void)ap_mm_lock(mm, AP_MM_LOCK_RW);
664 (void) ap_acquire_mutex(alloc_mutex);
666 +#if defined(EAPI) && defined(EAPI_MM)
667 + blok = new_block(POOL_HDR_BYTES, is_shm);
669 blok = new_block(POOL_HDR_BYTES);
671 new_pool = (pool *) blok->h.first_avail;
672 blok->h.first_avail += POOL_HDR_BYTES;
674 @@ -468,12 +527,38 @@
675 p->sub_pools = new_pool;
678 +#if defined(EAPI) && defined(EAPI_MM)
679 + new_pool->is_shm = is_shm;
682 (void) ap_release_mutex(alloc_mutex);
683 +#if defined(EAPI) && defined(EAPI_MM)
685 + (void)ap_mm_unlock(mm);
693 +#if defined(EAPI_MM)
694 +API_EXPORT(struct pool *) ap_make_sub_pool(struct pool *p)
696 + return make_sub_pool_internal(p, 0);
698 +API_EXPORT(struct pool *) ap_make_shared_sub_pool(struct pool *p)
700 + return make_sub_pool_internal(p, 1);
703 +API_EXPORT(struct pool *) ap_make_shared_sub_pool(struct pool *p)
711 static void stack_var_init(char *s)
718 +int ap_shared_pool_possible(void)
720 + return ap_mm_useable();
725 static void dump_stats(void)
728 return permanent_pool;
732 +void ap_init_alloc_shared(int early)
734 +#if defined(EAPI_MM)
740 + /* process very early on startup */
741 + mm_size = ap_mm_maxsize();
742 + if (mm_size > EAPI_MM_CORE_MAXSIZE)
743 + mm_size = EAPI_MM_CORE_MAXSIZE;
744 + mm_path = ap_server_root_relative(permanent_pool,
745 + ap_psprintf(permanent_pool, "%s.%ld",
746 + EAPI_MM_CORE_PATH, (long)getpid()));
747 + if ((mm = ap_mm_create(mm_size, mm_path)) == NULL) {
748 + fprintf(stderr, "Ouch! ap_mm_create(%d, \"%s\") failed\n", mm_size, mm_path);
749 + err1 = ap_mm_error();
751 + err1 = "-unknown-";
752 + err2 = strerror(errno);
754 + err2 = "-unknown-";
755 + fprintf(stderr, "Error: MM: %s: OS: %s\n", err1, err2);
760 + /* process a lot later on startup */
762 + ap_mm_permission(mm, (_S_IREAD|_S_IWRITE), ap_user_id, -1);
764 + ap_mm_permission(mm, (S_IRUSR|S_IWUSR), ap_user_id, -1);
767 +#endif /* EAPI_MM */
771 +void ap_kill_alloc_shared(void)
773 +#if defined(EAPI_MM)
778 +#endif /* EAPI_MM */
783 void ap_cleanup_alloc(void)
785 ap_destroy_mutex(alloc_mutex);
786 @@ -530,10 +674,18 @@
790 +#if defined(EAPI) && defined(EAPI_MM)
792 + (void)ap_mm_lock(mm, AP_MM_LOCK_RW);
794 (void) ap_acquire_mutex(alloc_mutex);
796 ap_destroy_pool(a->sub_pools);
797 (void) ap_release_mutex(alloc_mutex);
798 +#if defined(EAPI) && defined(EAPI_MM)
800 + (void)ap_mm_unlock(mm);
802 /* Don't hold the mutex during cleanups. */
803 run_cleanups(a->cleanups);
809 +#if defined(EAPI) && defined(EAPI_MM)
811 + (void)ap_mm_lock(mm, AP_MM_LOCK_RW);
813 (void) ap_acquire_mutex(alloc_mutex);
815 if (a->parent->sub_pools == a)
817 a->sub_next->sub_prev = a->sub_prev;
819 (void) ap_release_mutex(alloc_mutex);
820 +#if defined(EAPI) && defined(EAPI_MM)
822 + (void)ap_mm_unlock(mm);
825 free_blocks(a->first);
828 return bytes_in_block_list(block_freelist);
832 +API_EXPORT(int) ap_acquire_pool(pool *p, ap_pool_lock_mode mode)
834 +#if defined(EAPI_MM)
837 + return ap_mm_lock(mm, mode == AP_POOL_RD ? AP_MM_LOCK_RD : AP_MM_LOCK_RW);
843 +API_EXPORT(int) ap_release_pool(pool *p)
845 +#if defined(EAPI_MM)
848 + return ap_mm_unlock(mm);
855 /*****************************************************************
858 @@ -756,16 +940,31 @@
862 +#if defined(EAPI) && defined(EAPI_MM)
864 + (void)ap_mm_lock(mm, AP_MM_LOCK_RW);
866 (void) ap_acquire_mutex(alloc_mutex);
868 +#if defined(EAPI) && defined(EAPI_MM)
869 + blok = new_block(size, a->is_shm);
871 blok = new_block(size);
873 a->last->h.next = blok;
876 blok->h.owning_pool = a;
878 +#if defined(EAPI) && defined(EAPI_MM)
879 + blok->h.is_shm = a->is_shm;
882 (void) ap_release_mutex(alloc_mutex);
883 +#if defined(EAPI) && defined(EAPI_MM)
885 + (void)ap_mm_unlock(mm);
890 @@ -877,6 +1076,11 @@
893 size = (char *)ps->vbuff.curpos - ps->base;
894 +#if defined(EAPI) && defined(EAPI_MM)
895 + if (ps->block->h.is_shm)
896 + ptr = ap_mm_realloc(ps->base, 2*size);
899 ptr = realloc(ps->base, 2*size);
901 fputs("Ouch! Out of memory!\n", stderr);
902 @@ -897,9 +1101,21 @@
903 cur_len = strp - blok->h.first_avail;
905 /* must try another blok */
906 +#if defined(EAPI) && defined(EAPI_MM)
907 + if (blok->h.is_shm)
908 + (void)ap_mm_lock(mm, AP_MM_LOCK_RW);
910 (void) ap_acquire_mutex(alloc_mutex);
911 +#if defined(EAPI) && defined(EAPI_MM)
912 + nblok = new_block(2 * cur_len, blok->h.is_shm);
914 nblok = new_block(2 * cur_len);
916 (void) ap_release_mutex(alloc_mutex);
917 +#if defined(EAPI) && defined(EAPI_MM)
918 + if (blok->h.is_shm)
919 + (void)ap_mm_unlock(mm);
921 memcpy(nblok->h.first_avail, blok->h.first_avail, cur_len);
922 ps->vbuff.curpos = nblok->h.first_avail + cur_len;
923 /* save a byte for the NUL terminator */
924 @@ -908,10 +1124,18 @@
925 /* did we allocate the current blok? if so free it up */
926 if (ps->got_a_new_block) {
927 debug_fill(blok->h.first_avail, blok->h.endp - blok->h.first_avail);
928 +#if defined(EAPI) && defined(EAPI_MM)
929 + if (blok->h.is_shm)
930 + (void)ap_mm_lock(mm, AP_MM_LOCK_RW);
932 (void) ap_acquire_mutex(alloc_mutex);
933 blok->h.next = block_freelist;
934 block_freelist = blok;
935 (void) ap_release_mutex(alloc_mutex);
936 +#if defined(EAPI) && defined(EAPI_MM)
937 + if (blok->h.is_shm)
938 + (void)ap_mm_unlock(mm);
942 ps->got_a_new_block = 1;
943 @@ -930,6 +1154,11 @@
947 +#if defined(EAPI) && defined(EAPI_MM)
949 + ps.base = ap_mm_malloc(mm, 512);
952 ps.base = malloc(512);
953 if (ps.base == NULL) {
954 fputs("Ouch! Out of memory!\n", stderr);
955 @@ -942,6 +1171,11 @@
956 *ps.vbuff.curpos++ = '\0';
959 +#if defined(EAPI) && defined(EAPI_MM)
961 + ptr = ap_mm_realloc(ptr, (char *)ps.vbuff.curpos - (char *)ptr);
964 ptr = realloc(ptr, (char *)ps.vbuff.curpos - (char *)ptr);
966 fputs("Ouch! Out of memory!\n", stderr);
968 +---------------------------------------------------------------------------
969 | Patch the low-level buffer routines to additionally allow
970 | modules to intercept the I/O processing via hooks.
971 +---------------------------------------------------------------------------
972 Index: src/main/buff.c
973 --- src/main/buff.c 2001/01/23 11:35:08 1.1.1.10
974 +++ src/main/buff.c 2001/01/23 11:48:05 1.18
976 select() sometimes returns 1 even though the write will block. We must work around this.
980 +API_EXPORT(int) sendwithtimeout(int sock, const char *buf, int len, int flags)
982 int sendwithtimeout(int sock, const char *buf, int len, int flags)
993 +API_EXPORT(int) recvwithtimeout(int sock, char *buf, int len, int flags)
995 int recvwithtimeout(int sock, char *buf, int len, int flags)
1005 + if (!ap_hook_call("ap::buff::read", &rv, fb, buf, nbyte))
1007 rv = read(fb->fd_in, buf, nbyte);
1012 #if defined (WIN32) || defined(NETWARE)
1013 if (fb->flags & B_SOCKET) {
1015 + if (!ap_hook_call("ap::buff::recvwithtimeout", &rv, fb, buf, nbyte))
1017 rv = recvwithtimeout(fb->fd_in, buf, nbyte, 0);
1018 if (rv == SOCKET_ERROR)
1019 errno = WSAGetLastError();
1025 + if (!ap_hook_call("ap::buff::write", &rv, fb, buf, nbyte))
1027 #if defined (B_SFIO)
1028 rv = sfwrite(fb->sf_out, buf, nbyte);
1032 #if defined(WIN32) || defined(NETWARE)
1033 if (fb->flags & B_SOCKET) {
1035 + if (!ap_hook_call("ap::buff::sendwithtimeout", &rv, fb, buf, nbyte))
1037 rv = sendwithtimeout(fb->fd, buf, nbyte, 0);
1038 if (rv == SOCKET_ERROR)
1039 errno = WSAGetLastError();
1040 @@ -438,6 +457,10 @@
1041 (size_t) SF_UNBOUND, 1, SF_WRITE);
1045 + fb->ctx = ap_ctx_new(p);
1051 @@ -1084,6 +1107,9 @@
1056 + if (!ap_hook_call("ap::buff::writev", &rv, fb, &vec[i], nvec -i))
1058 rv = writev(fb->fd, &vec[i], nvec - i);
1059 while (rv == -1 && (errno == EINTR || errno == EAGAIN)
1060 && !(fb->flags & B_EOUT));
1062 +---------------------------------------------------------------------------
1063 | Add the implementation of the additional `add_module' and
1064 | `rewrite_command' module hooks. Additionally the `ctx'
1065 | variables are initialized.
1066 +---------------------------------------------------------------------------
1067 Index: src/main/http_config.c
1068 --- src/main/http_config.c 2001/01/29 19:36:42 1.1.1.11
1069 +++ src/main/http_config.c 2001/01/29 19:38:39 1.14
1070 @@ -599,6 +599,20 @@
1073 #endif /*_OSD_POSIX*/
1077 + * Invoke the `add_module' hook inside the now existing set
1078 + * of modules to let them all now that this module was added.
1082 + for (m2 = top_module; m2 != NULL; m2 = m2->next)
1083 + if (m2->magic == MODULE_MAGIC_COOKIE_EAPI)
1084 + if (m2->add_module != NULL)
1085 + (*m2->add_module)(m);
1091 @@ -613,6 +627,21 @@
1097 + * Invoke the `remove_module' hook inside the now existing
1098 + * set of modules to let them all now that this module is
1103 + for (m2 = top_module; m2 != NULL; m2 = m2->next)
1104 + if (m2->magic == MODULE_MAGIC_COOKIE_EAPI)
1105 + if (m2->remove_module != NULL)
1106 + (*m2->remove_module)(m);
1112 /* We are the top module, special case */
1113 @@ -1006,6 +1035,27 @@
1114 const command_rec *cmd;
1115 module *mod = top_module;
1119 + * Invoke the `rewrite_command' of modules to allow
1120 + * they to rewrite the directive line before we
1126 + for (m = top_module; m != NULL; m = m->next) {
1127 + if (m->magic == MODULE_MAGIC_COOKIE_EAPI) {
1128 + if (m->rewrite_command != NULL) {
1129 + cp = (m->rewrite_command)(parms, config, l);
1138 if ((l[0] == '#') || (!l[0]))
1141 @@ -1440,6 +1490,10 @@
1142 s->limit_req_fieldsize = main_server->limit_req_fieldsize;
1143 s->limit_req_fields = main_server->limit_req_fields;
1146 + s->ctx = ap_ctx_new(p);
1151 return ap_parse_vhost_addrs(p, hostname, s);
1152 @@ -1550,6 +1604,10 @@
1154 s->module_config = create_server_config(p, s);
1155 s->lookup_defaults = create_default_per_dir_config(p);
1158 + s->ctx = ap_ctx_new(p);
1164 +---------------------------------------------------------------------------
1165 | Add the ap_global_ctx variable and the new
1166 | ap_add_config_define() function. Additionally the
1167 | implementation of the additional `new_connection' module hook
1168 | is added plus the initialization of one more `ctx' variable.
1169 +---------------------------------------------------------------------------
1170 Index: src/main/http_main.c
1171 --- src/main/http_main.c 2001/02/28 19:40:49 1.1.1.13
1172 +++ src/main/http_main.c 2001/03/02 23:45:42 1.35
1174 int ap_listenbacklog;
1175 int ap_dump_settings = 0;
1176 API_VAR_EXPORT int ap_extended_status = 0;
1178 +API_VAR_EXPORT ap_ctx *ap_global_ctx;
1182 * The max child slot ever assigned, preserved across restarts. Necessary
1183 @@ -442,6 +445,30 @@
1188 +API_EXPORT(void) ap_add_config_define(const char *define)
1191 + var = (char **)ap_push_array(ap_server_config_defines);
1192 + *var = ap_pstrdup(pcommands, define);
1197 + * Invoke the `close_connection' hook of modules to let them do
1198 + * some connection dependent actions before we close it.
1200 +static void ap_call_close_connection_hook(conn_rec *c)
1203 + for (m = top_module; m != NULL; m = m->next)
1204 + if (m->magic == MODULE_MAGIC_COOKIE_EAPI)
1205 + if (m->close_connection != NULL)
1206 + (*m->close_connection)(c);
1212 static APACHE_TLS int volatile exit_after_unblock = 0;
1214 @@ -1209,6 +1236,10 @@
1215 ap_log_transaction(log_req);
1219 + ap_call_close_connection_hook(save_req->connection);
1222 ap_bsetflag(save_req->connection->client, B_EOUT, 1);
1223 ap_bclose(save_req->connection->client);
1225 @@ -1217,6 +1248,9 @@
1226 ap_longjmp(jmpbuffer, 1);
1228 else { /* abort the connection */
1230 + ap_call_close_connection_hook(current_conn);
1232 ap_bsetflag(current_conn->client, B_EOUT, 1);
1233 ap_bclose(current_conn->client);
1234 current_conn->aborted = 1;
1235 @@ -1282,7 +1316,11 @@
1240 +API_EXPORT(unsigned int) ap_set_callback_and_alarm(void (*fn) (int), int x)
1242 unsigned int ap_set_callback_and_alarm(void (*fn) (int), int x)
1247 @@ -1518,10 +1556,16 @@
1248 /* Send any leftover data to the client, but never try to again */
1250 if (ap_bflush(r->connection->client) == -1) {
1252 + ap_call_close_connection_hook(r->connection);
1255 ap_bclose(r->connection->client);
1259 + ap_call_close_connection_hook(r->connection);
1261 ap_bsetflag(r->connection->client, B_EOUT, 1);
1263 /* Close our half of the connection --- send the client a FIN */
1264 @@ -2232,6 +2276,9 @@
1265 /* Clear the pool - including any registered cleanups */
1266 ap_destroy_pool(pglobal);
1269 + ap_kill_alloc_shared();
1274 @@ -3226,6 +3273,24 @@
1275 conn->remote_addr = *remaddr;
1276 conn->remote_ip = ap_pstrdup(conn->pool,
1277 inet_ntoa(conn->remote_addr.sin_addr));
1279 + conn->ctx = ap_ctx_new(conn->pool);
1284 + * Invoke the `new_connection' hook of modules to let them do
1285 + * some connection dependent actions before we go on with
1286 + * processing the request on this connection.
1290 + for (m = top_module; m != NULL; m = m->next)
1291 + if (m->magic == MODULE_MAGIC_COOKIE_EAPI)
1292 + if (m->new_connection != NULL)
1293 + (*m->new_connection)(conn);
1299 @@ -3647,6 +3712,15 @@
1300 printf("Server's Module Magic Number: %u:%u\n",
1301 MODULE_MAGIC_NUMBER_MAJOR, MODULE_MAGIC_NUMBER_MINOR);
1302 printf("Server compiled with....\n");
1304 + printf(" -D EAPI\n");
1307 + printf(" -D EAPI_MM\n");
1308 +#ifdef EAPI_MM_CORE_PATH
1309 + printf(" -D EAPI_MM_CORE_PATH=\"" EAPI_MM_CORE_PATH "\"\n");
1312 #ifdef BIG_SECURITY_HOLE
1313 printf(" -D BIG_SECURITY_HOLE\n");
1315 @@ -3800,6 +3874,22 @@
1316 ap_server_pre_read_config = ap_make_array(pcommands, 1, sizeof(char *));
1317 ap_server_post_read_config = ap_make_array(pcommands, 1, sizeof(char *));
1318 ap_server_config_defines = ap_make_array(pcommands, 1, sizeof(char *));
1322 + ap_hook_configure("ap::buff::read",
1323 + AP_HOOK_SIG4(int,ptr,ptr,int), AP_HOOK_TOPMOST);
1324 + ap_hook_configure("ap::buff::write",
1325 + AP_HOOK_SIG4(int,ptr,ptr,int), AP_HOOK_TOPMOST);
1326 + ap_hook_configure("ap::buff::writev",
1327 + AP_HOOK_SIG4(int,ptr,ptr,int), AP_HOOK_TOPMOST);
1328 + ap_hook_configure("ap::buff::sendwithtimeout",
1329 + AP_HOOK_SIG4(int,ptr,ptr,int), AP_HOOK_TOPMOST);
1330 + ap_hook_configure("ap::buff::recvwithtimeout",
1331 + AP_HOOK_SIG4(int,ptr,ptr,int), AP_HOOK_TOPMOST);
1333 + ap_global_ctx = ap_ctx_new(NULL);
1338 @@ -4219,6 +4309,9 @@
1340 ap_sync_scoreboard_image();
1341 if (ap_scoreboard_image->global.running_generation != ap_my_generation) {
1343 + ap_call_close_connection_hook(current_conn);
1346 clean_child_exit(0);
1348 @@ -4247,6 +4340,9 @@
1353 + ap_call_close_connection_hook(current_conn);
1355 ap_bclose(conn_io); /* just close it */
1357 if (r && r->connection
1358 @@ -4257,6 +4353,9 @@
1363 + ap_call_close_connection_hook(current_conn);
1365 ap_bsetflag(conn_io, B_EOUT, 1);
1368 @@ -4981,16 +5080,31 @@
1373 + ap_init_alloc_shared(TRUE);
1376 ap_suexec_enabled = init_suexec();
1377 server_conf = ap_read_config(pconf, ptrans, ap_server_confname);
1380 + ap_init_alloc_shared(FALSE);
1383 if (ap_configtestonly) {
1384 fprintf(stderr, "Syntax OK\n");
1386 + clean_parent_exit(0);
1391 if (ap_dump_settings) {
1393 + clean_parent_exit(0);
1399 child_timeouts = !ap_standalone || one_process;
1400 @@ -5120,6 +5234,10 @@
1401 ap_destroy_pool(r->pool);
1405 + ap_call_close_connection_hook(conn);
1411 @@ -5466,6 +5584,9 @@
1412 ap_kill_cleanups_for_socket(ptrans, csd);
1416 + ap_call_close_connection_hook(current_conn);
1418 ap_bclose(conn_io); /* just close it */
1420 if (r && r->connection
1421 @@ -5476,6 +5597,9 @@
1426 + ap_call_close_connection_hook(current_conn);
1428 ap_bsetflag(conn_io, B_EOUT, 1);
1431 @@ -6989,6 +7113,10 @@
1432 if (!conf_specified)
1433 ap_cpystrn(ap_server_confname, SERVER_CONFIG_FILE, sizeof(ap_server_confname));
1436 + ap_init_alloc_shared(TRUE);
1439 if (!ap_os_is_path_absolute(ap_server_confname))
1440 ap_cpystrn(ap_server_confname,
1441 ap_server_root_relative(pcommands, ap_server_confname),
1442 @@ -7030,6 +7158,9 @@
1444 #else /* ndef WIN32 */
1445 server_conf = ap_read_config(pconf, ptrans, ap_server_confname);
1448 + ap_init_alloc_shared(FALSE);
1451 if (ap_configtestonly) {
1453 +---------------------------------------------------------------------------
1454 | Just add the initialization of the `ctx' variable for
1455 | conn_rec structures.
1456 +---------------------------------------------------------------------------
1457 Index: src/main/http_request.c
1458 --- src/main/http_request.c 2001/02/28 19:40:49 1.1.1.11
1459 +++ src/main/http_request.c 2001/02/28 19:44:34 1.10
1460 @@ -1404,6 +1404,9 @@
1461 new->no_local_copy = r->no_local_copy;
1462 new->read_length = r->read_length; /* We can only read it once */
1463 new->vlist_validator = r->vlist_validator;
1465 + new->ctx = r->ctx;
1468 ap_table_setn(new->subprocess_env, "REDIRECT_STATUS",
1469 ap_psprintf(r->pool, "%d", r->status));
1471 +---------------------------------------------------------------------------
1472 | Just add the initialization of the `ctx' variable for
1473 | request_rec structures.
1474 +---------------------------------------------------------------------------
1475 Index: src/main/http_protocol.c
1476 --- src/main/http_protocol.c 2001/02/28 19:40:49 1.1.1.12
1477 +++ src/main/http_protocol.c 2001/02/28 19:44:34 1.12
1478 @@ -1105,6 +1105,10 @@
1479 r->status = HTTP_REQUEST_TIME_OUT; /* Until we get a request */
1480 r->the_request = NULL;
1483 + r->ctx = ap_ctx_new(r->pool);
1486 #ifdef CHARSET_EBCDIC
1487 ap_bsetflag(r->connection->client, B_ASCII2EBCDIC|B_EBCDIC2ASCII, 1);
1489 @@ -1252,6 +1256,11 @@
1490 rnew->read_body = REQUEST_NO_BODY;
1492 rnew->main = (request_rec *) r;
1495 + rnew->ctx = r->ctx;
1500 void ap_finalize_sub_req_protocol(request_rec *sub)
1502 +---------------------------------------------------------------------------
1503 | Add support for loading both EAPI and AP13 modules.
1504 +---------------------------------------------------------------------------
1505 Index: src/modules/standard/mod_so.c
1506 --- src/modules/standard/mod_so.c 2001/01/23 11:35:13 1.1.1.6
1507 +++ src/modules/standard/mod_so.c 2001/01/23 11:48:08 1.7
1508 @@ -263,11 +263,24 @@
1509 * Make sure the found module structure is really a module structure
1513 + if ( modp->magic != MODULE_MAGIC_COOKIE_AP13
1514 + && modp->magic != MODULE_MAGIC_COOKIE_EAPI) {
1516 if (modp->magic != MODULE_MAGIC_COOKIE) {
1518 return ap_pstrcat(cmd->pool, "API module structure `", modname,
1519 "' in file ", szModuleFile, " is garbled -"
1520 " perhaps this is not an Apache module DSO?", NULL);
1523 + if (modp->magic == MODULE_MAGIC_COOKIE_AP13) {
1524 + ap_log_error(APLOG_MARK, APLOG_WARNING|APLOG_NOERRNO, NULL,
1525 + "Loaded DSO %s uses plain Apache 1.3 API, "
1526 + "this module might crash under EAPI! "
1527 + "(please recompile it with -DEAPI)", filename);
1532 * Add this module to the Apache core structures
1534 +---------------------------------------------------------------------------
1535 | Add additional logging functions to the CustomLog directive
1536 | which can be used by other modules to create additional
1537 | logfile tags. Actually we add two types of hooks: One hook
1538 | for intercepting the new and generic %x (eXtension) tag and
1539 | one hook for creating new %x tags at all.
1540 +---------------------------------------------------------------------------
1541 Index: src/modules/standard/mod_log_config.c
1542 --- src/modules/standard/mod_log_config.c 2001/01/23 11:35:12 1.1.1.11
1543 +++ src/modules/standard/mod_log_config.c 2001/01/23 11:48:08 1.24
1545 typedef const char *(*item_key_func) (request_rec *, char *);
1553 int condition_sense;
1554 @@ -573,15 +576,36 @@
1559 +static struct log_item_list *find_log_func(pool *p, char k)
1561 static struct log_item_list *find_log_func(char k)
1566 + struct log_item_list *lil;
1569 for (i = 0; log_item_keys[i].ch; ++i)
1570 if (k == log_item_keys[i].ch) {
1571 return &log_item_keys[i];
1575 + if (ap_hook_status(ap_psprintf(p, "ap::mod_log_config::log_%c", k))
1576 + != AP_HOOK_STATE_NOTEXISTANT) {
1577 + lil = (struct log_item_list *)
1578 + ap_pcalloc(p, sizeof(struct log_item_list));
1583 + lil->want_orig_default = 0;
1591 @@ -707,7 +731,11 @@
1596 + l = find_log_func(p, *s++);
1598 l = find_log_func(*s++);
1604 return ap_pstrcat(p, "Unrecognized LogFormat directive %",
1611 if (it->want_orig == -1) {
1612 it->want_orig = l->want_orig_default;
1613 @@ -777,6 +808,15 @@
1615 /* We do. Do it... */
1618 + if (item->func == NULL) {
1620 + ap_hook_use(ap_psprintf(r->pool, "ap::mod_log_config::log_%c", item->ch),
1621 + AP_HOOK_SIG3(ptr,ptr,ptr), AP_HOOK_DECLINE(NULL),
1622 + &cp, r, item->arg);
1626 cp = (*item->func) (item->want_orig ? orig : r, item->arg);
1627 return cp ? cp : "-";
1630 +---------------------------------------------------------------------------
1631 | Allow RewriteCond and RewriteRule directives to lookup
1632 | variables from other modules.
1633 +---------------------------------------------------------------------------
1634 Index: src/modules/standard/mod_rewrite.c
1635 --- src/modules/standard/mod_rewrite.c 2001/02/28 19:40:52 1.1.1.10
1636 +++ src/modules/standard/mod_rewrite.c 2001/02/28 19:44:34 1.8
1637 @@ -3637,6 +3637,15 @@
1639 #endif /* ndef WIN32 && NETWARE*/
1643 + ap_hook_use("ap::mod_rewrite::lookup_variable",
1644 + AP_HOOK_SIG3(ptr,ptr,ptr),
1645 + AP_HOOK_DECLINE(NULL),
1650 if (result == NULL) {
1651 return ap_pstrdup(r->pool, "");
1654 +---------------------------------------------------------------------------
1655 | Add an EAPI hook to allow other modules to add content to
1656 | the status HTML page.
1657 +---------------------------------------------------------------------------
1658 Index: src/modules/standard/mod_status.c
1659 --- src/modules/standard/mod_status.c 2001/01/23 11:35:14 1.1.1.11
1660 +++ src/modules/standard/mod_status.c 2001/01/23 11:48:08 1.8
1661 @@ -711,6 +748,12 @@
1667 + ap_hook_use("ap::mod_status::display",
1668 + AP_HOOK_SIG4(void,ptr,int,int), AP_HOOK_ALL,
1669 + r, no_table_report, short_report);
1675 +---------------------------------------------------------------------------
1676 | Add hooks to the scheme processing to allow other modules to
1677 | recognize more schemes by intercepting this processing.
1678 +---------------------------------------------------------------------------
1679 Index: src/modules/proxy/mod_proxy.c
1680 --- src/modules/proxy/mod_proxy.c 2001/01/23 11:35:10 1.1.1.8
1681 +++ src/modules/proxy/mod_proxy.c 2001/01/23 11:48:07 1.15
1683 static int proxy_fixup(request_rec *r)
1690 if (r->proxyreq == NOT_PROXY || strncmp(r->filename, "proxy:", 6) != 0)
1692 @@ -222,6 +225,14 @@
1693 url = &r->filename[6];
1695 /* canonicalise each specific scheme */
1697 + if (ap_hook_use("ap::mod_proxy::canon",
1698 + AP_HOOK_SIG3(int,ptr,ptr),
1699 + AP_HOOK_DECLINE(DECLINED),
1700 + &rc, r, url) && rc != DECLINED)
1704 if (strncasecmp(url, "http:", 5) == 0)
1705 return ap_proxy_http_canon(r, url + 5, "http", DEFAULT_HTTP_PORT);
1706 else if (strncasecmp(url, "ftp:", 4) == 0)
1707 @@ -237,9 +248,44 @@
1708 static void proxy_init(server_rec *r, pool *p)
1710 ap_proxy_garbage_init(r, p);
1712 + ap_hook_use("ap::mod_proxy::init",
1713 + AP_HOOK_SIG3(void,ptr,ptr), AP_HOOK_ALL, r, p);
1719 +static void proxy_addmod(module *m)
1721 + /* export: ap_proxy_http_canon() as `ap::mod_proxy::http::canon' */
1722 + ap_hook_configure("ap::mod_proxy::http::canon",
1723 + AP_HOOK_SIG5(int,ptr,ptr,ptr,int), AP_HOOK_TOPMOST);
1724 + ap_hook_register("ap::mod_proxy::http::canon",
1725 + ap_proxy_http_canon, AP_HOOK_NOCTX);
1727 + /* export: ap_proxy_http_handler() as `ap::mod_proxy::http::handler' */
1728 + ap_hook_configure("ap::mod_proxy::http::handler",
1729 + AP_HOOK_SIG6(int,ptr,ptr,ptr,ptr,int), AP_HOOK_TOPMOST);
1730 + ap_hook_register("ap::mod_proxy::http::handler",
1731 + ap_proxy_http_handler, AP_HOOK_NOCTX);
1733 + /* export: ap_proxyerror() as `ap::mod_proxy::error' */
1734 + ap_hook_configure("ap::mod_proxy::error",
1735 + AP_HOOK_SIG3(int,ptr,ptr), AP_HOOK_TOPMOST);
1736 + ap_hook_register("ap::mod_proxy::error",
1737 + ap_proxyerror, AP_HOOK_NOCTX);
1741 +static void proxy_remmod(module *m)
1743 + /* remove the hook references */
1744 + ap_hook_unregister("ap::mod_proxy::http::canon", ap_proxy_http_canon);
1745 + ap_hook_unregister("ap::mod_proxy::http::handler", ap_proxy_http_handler);
1746 + ap_hook_unregister("ap::mod_proxy::error", ap_proxyerror);
1751 /* Send a redirection if the request contains a hostname which is not */
1752 /* fully qualified, i.e. doesn't have a domain name appended. Some proxy */
1753 @@ -369,6 +415,14 @@
1754 /* CONNECT is a special method that bypasses the normal
1758 + if (!ap_hook_use("ap::mod_proxy::handler",
1759 + AP_HOOK_SIG7(int,ptr,ptr,ptr,ptr,int,ptr),
1760 + AP_HOOK_DECLINE(DECLINED),
1762 + ents[i].hostname, ents[i].port,
1763 + ents[i].protocol) || rc == DECLINED) {
1765 if (r->method_number == M_CONNECT)
1766 rc = ap_proxy_connect_handler(r, cr, url, ents[i].hostname,
1776 /* an error or success */
1777 if (rc != DECLINED && rc != HTTP_BAD_GATEWAY)
1778 @@ -391,6 +448,14 @@
1781 /* handle the scheme */
1783 + if (ap_hook_use("ap::mod_proxy::handler",
1784 + AP_HOOK_SIG7(int,ptr,ptr,ptr,ptr,int,ptr),
1785 + AP_HOOK_DECLINE(DECLINED),
1787 + NULL, 0, scheme) && rc != DECLINED)
1790 if (r->method_number == M_CONNECT)
1791 return ap_proxy_connect_handler(r, cr, url, NULL, 0);
1792 if (strcasecmp(scheme, "http") == 0)
1793 @@ -955,6 +1020,12 @@
1794 NULL, /* child_init */
1795 NULL, /* child_exit */
1796 proxy_detect /* post read-request */
1798 + ,proxy_addmod, /* EAPI: add_module */
1799 + proxy_remmod, /* EAPI: remove_module */
1800 + NULL, /* EAPI: rewrite_command */
1801 + NULL /* EAPI: new_connection */
1807 +---------------------------------------------------------------------------
1808 | Add hooks to the HTTP processing to allow other modules
1809 | to enhance it by intercepting this processing.
1810 +---------------------------------------------------------------------------
1811 Index: src/modules/proxy/proxy_http.c
1812 --- src/modules/proxy/proxy_http.c 2001/02/28 19:40:51 1.1.1.10
1813 +++ src/modules/proxy/proxy_http.c 2001/02/28 19:44:34 1.18
1815 const char *urlptr = NULL;
1816 const char *datestr;
1817 struct tbl_do_args tdo;
1822 void *sconf = r->server->module_config;
1823 proxy_server_conf *conf =
1824 @@ -208,6 +211,12 @@
1825 return HTTP_BAD_REQUEST;
1827 destport = DEFAULT_HTTP_PORT;
1829 + ap_hook_use("ap::mod_proxy::http::handler::set_destport",
1830 + AP_HOOK_SIG2(int,ptr),
1834 strp = strchr(urlptr, '/');
1836 desthost = ap_pstrdup(p, urlptr);
1837 @@ -245,12 +254,18 @@
1838 err = ap_proxy_host2addr(proxyhost, &server_hp);
1840 return DECLINED; /* try another */
1842 + peer = ap_psprintf(p, "%s:%u", proxyhost, proxyport);
1846 server.sin_port = htons(destport);
1847 err = ap_proxy_host2addr(desthost, &server_hp);
1849 return ap_proxyerror(r, HTTP_INTERNAL_SERVER_ERROR, err);
1851 + peer = ap_psprintf(p, "%s:%u", desthost, destport);
1855 sock = ap_psocket(p, PF_INET, SOCK_STREAM, IPPROTO_TCP);
1856 @@ -307,13 +322,41 @@
1857 f = ap_bcreate(p, B_RDWR | B_SOCKET);
1858 ap_bpushfd(f, sock, sock);
1862 + char *errmsg = NULL;
1863 + ap_hook_use("ap::mod_proxy::http::handler::new_connection",
1864 + AP_HOOK_SIG4(ptr,ptr,ptr,ptr),
1865 + AP_HOOK_DECLINE(NULL),
1866 + &errmsg, r, f, peer);
1867 + if (errmsg != NULL)
1868 + return ap_proxyerror(r, HTTP_BAD_GATEWAY, errmsg);
1872 ap_hard_timeout("proxy send", r);
1873 ap_bvputs(f, r->method, " ", proxyhost ? url : urlptr, " HTTP/1.0" CRLF,
1877 + int rc = DECLINED;
1878 + ap_hook_use("ap::mod_proxy::http::handler::write_host_header",
1879 + AP_HOOK_SIG6(int,ptr,ptr,ptr,int,ptr),
1880 + AP_HOOK_DECLINE(DECLINED),
1881 + &rc, r, f, desthost, destport, destportstr);
1882 + if (rc == DECLINED) {
1883 + if (destportstr != NULL && destport != DEFAULT_HTTP_PORT)
1884 + ap_bvputs(f, "Host: ", desthost, ":", destportstr, CRLF, NULL);
1886 + ap_bvputs(f, "Host: ", desthost, CRLF, NULL);
1890 if (destportstr != NULL && destport != DEFAULT_HTTP_PORT)
1891 ap_bvputs(f, "Host: ", desthost, ":", destportstr, CRLF, NULL);
1893 ap_bvputs(f, "Host: ", desthost, CRLF, NULL);
1896 if (conf->viaopt == via_block) {
1897 /* Block all outgoing Via: headers */
1899 +---------------------------------------------------------------------------
1900 | Add EAPI hooks in module structure for APXS generated samples.
1901 +---------------------------------------------------------------------------
1902 Index: src/support/apxs.pl
1903 --- src/support/apxs.pl 2001/01/23 11:35:14 1.1.1.9
1904 +++ src/support/apxs.pl 2001/01/23 11:48:09 1.9
1905 @@ -654,5 +654,11 @@
1906 NULL, /* child_init */
1907 NULL, /* child_exit */
1908 NULL /* [#0] post read-request */
1910 + ,NULL, /* EAPI: add_module */
1911 + NULL, /* EAPI: remove_module */
1912 + NULL, /* EAPI: rewrite_command */
1913 + NULL /* EAPI: new_connection */
1918 +---------------------------------------------------------------------------
1919 | Add the EAPI functions, so the stuff can be built under AIX
1920 | and similar braindead platforms as DSO.
1921 +---------------------------------------------------------------------------
1922 Index: src/support/httpd.exp
1923 --- src/support/httpd.exp 2001/02/28 19:40:56 1.1.1.9
1924 +++ src/support/httpd.exp 2001/02/28 19:44:35 1.11
1925 @@ -422,3 +422,59 @@
1926 XML_SetUnparsedEntityDeclHandler
1928 XML_UseParserAsHandlerArg
1929 +ap_add_config_define
1930 +ap_make_shared_sub_pool
1939 +ap_hook_unregister_I
1974 +ap_mm_core_permission
1979 +ap_mm_core_maxsegsize
1980 +ap_mm_core_align2page
1981 +ap_mm_core_align2word
1982 +ap_mm_lib_error_set
1983 +ap_mm_lib_error_get
1986 +---------------------------------------------------------------------------
1987 | Add the EAPI functions, so the stuff can be built under
1988 | Windows 95 and similar braindead platforms as DDL.
1989 +---------------------------------------------------------------------------
1990 Index: src/ApacheCore.def
1991 --- src/ApacheCore.def 2001/01/23 11:35:01 1.1.1.7
1992 +++ src/ApacheCore.def 2001/03/03 10:46:41 1.11
1993 @@ -389,3 +389,69 @@
1996 ap_os_dso_error @382
1998 + ; EAPI extended symbols
1999 + ; note; no ID's, so these all bind by name rather than ordinal since
2000 + ; their ordinals would change with symbol changes in the distribution
2001 + ap_add_config_define
2002 + ap_global_ctx DATA
2010 + ap_hook_register_I
2011 + ap_hook_unregister_I
2015 + ap_set_callback_and_alarm
2019 + ap_make_shared_sub_pool
2050 + ap_mm_display_info
2052 + ap_mm_core_permission
2057 + ap_mm_core_align2page
2058 + ap_mm_core_align2word
2059 + ap_mm_lib_error_set
2060 + ap_mm_lib_error_get