summaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/.indent.pro54
-rw-r--r--include/ap_compat.h30
-rw-r--r--include/ap_config.h206
-rw-r--r--include/ap_config_auto.h.in319
-rw-r--r--include/ap_config_layout.h.in64
-rw-r--r--include/ap_expr.h353
-rw-r--r--include/ap_hooks.h162
-rw-r--r--include/ap_listen.h163
-rw-r--r--include/ap_mmn.h566
-rw-r--r--include/ap_mpm.h235
-rw-r--r--include/ap_provider.h100
-rw-r--r--include/ap_regex.h275
-rw-r--r--include/ap_regkey.h219
-rw-r--r--include/ap_release.h83
-rw-r--r--include/ap_slotmem.h199
-rw-r--r--include/ap_socache.h230
-rw-r--r--include/apache_noprobes.h344
-rw-r--r--include/heartbeat.h60
-rw-r--r--include/http_config.h1416
-rw-r--r--include/http_connection.h168
-rw-r--r--include/http_core.h1049
-rw-r--r--include/http_log.h836
-rw-r--r--include/http_main.h88
-rw-r--r--include/http_protocol.h1023
-rw-r--r--include/http_request.h630
-rw-r--r--include/http_vhost.h119
-rw-r--r--include/httpd.h2409
-rw-r--r--include/mod_auth.h141
-rw-r--r--include/mod_core.h103
-rw-r--r--include/mod_request.h64
-rw-r--r--include/mpm_common.h470
-rw-r--r--include/scoreboard.h253
-rw-r--r--include/util_cfgtree.h98
-rw-r--r--include/util_charset.h72
-rw-r--r--include/util_cookies.h146
-rw-r--r--include/util_ebcdic.h92
-rw-r--r--include/util_fcgi.h280
-rw-r--r--include/util_filter.h639
-rw-r--r--include/util_ldap.h398
-rw-r--r--include/util_md5.h72
-rw-r--r--include/util_mutex.h223
-rw-r--r--include/util_script.h233
-rw-r--r--include/util_time.h117
-rw-r--r--include/util_varbuf.h197
-rw-r--r--include/util_xml.h51
45 files changed, 15049 insertions, 0 deletions
diff --git a/include/.indent.pro b/include/.indent.pro
new file mode 100644
index 0000000..a9fbe9f
--- /dev/null
+++ b/include/.indent.pro
@@ -0,0 +1,54 @@
+-i4 -npsl -di0 -br -nce -d0 -cli0 -npcs -nfc1
+-TBUFF
+-TFILE
+-TTRANS
+-TUINT4
+-T_trans
+-Tallow_options_t
+-Tapache_sfio
+-Tarray_header
+-Tbool_int
+-Tbuf_area
+-Tbuff_struct
+-Tbuffy
+-Tcmd_how
+-Tcmd_parms
+-Tcommand_rec
+-Tcommand_struct
+-Tconn_rec
+-Tcore_dir_config
+-Tcore_server_config
+-Tdir_maker_func
+-Tevent
+-Tglobals_s
+-Thandler_func
+-Thandler_rec
+-Tjoblist_s
+-Tlisten_rec
+-Tmerger_func
+-Tmode_t
+-Tmodule
+-Tmodule_struct
+-Tmutex
+-Tn_long
+-Tother_child_rec
+-Toverrides_t
+-Tparent_score
+-Tpid_t
+-Tpiped_log
+-Tpool
+-Trequest_rec
+-Trequire_line
+-Trlim_t
+-Tscoreboard
+-Tsemaphore
+-Tserver_addr_rec
+-Tserver_rec
+-Tserver_rec_chain
+-Tshort_score
+-Ttable
+-Ttable_entry
+-Tthread
+-Tu_wide_int
+-Tvtime_t
+-Twide_int
diff --git a/include/ap_compat.h b/include/ap_compat.h
new file mode 100644
index 0000000..af9303f
--- /dev/null
+++ b/include/ap_compat.h
@@ -0,0 +1,30 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file ap_compat.h
+ * @brief Redefine Apache 1.3 symbols
+ */
+
+#ifndef AP_COMPAT_H
+#define AP_COMPAT_H
+
+/* redefine 1.3.x symbols to the new symbol names */
+
+#define MODULE_VAR_EXPORT AP_MODULE_DECLARE_DATA
+#define ap_send_http_header(r) ;
+
+#endif /* AP_COMPAT_H */
diff --git a/include/ap_config.h b/include/ap_config.h
new file mode 100644
index 0000000..944b16a
--- /dev/null
+++ b/include/ap_config.h
@@ -0,0 +1,206 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file ap_config.h
+ * @brief Symbol export macros and hook functions
+ */
+
+#ifndef AP_CONFIG_H
+#define AP_CONFIG_H
+
+#include "ap_hooks.h"
+
+/* Although this file doesn't declare any hooks, declare the exports group here */
+/**
+ * @defgroup exports Apache exports
+ * @ingroup APACHE_CORE
+ */
+
+#ifdef DOXYGEN
+/* define these just so doxygen documents them */
+
+/**
+ * AP_DECLARE_STATIC is defined when including Apache's Core headers,
+ * to provide static linkage when the dynamic library may be unavailable.
+ *
+ * @see AP_DECLARE_EXPORT
+ *
+ * AP_DECLARE_STATIC and AP_DECLARE_EXPORT are left undefined when
+ * including Apache's Core headers, to import and link the symbols from the
+ * dynamic Apache Core library and assure appropriate indirection and calling
+ * conventions at compile time.
+ */
+# define AP_DECLARE_STATIC
+/**
+ * AP_DECLARE_EXPORT is defined when building the Apache Core dynamic
+ * library, so that all public symbols are exported.
+ *
+ * @see AP_DECLARE_STATIC
+ */
+# define AP_DECLARE_EXPORT
+
+#endif /* def DOXYGEN */
+
+#if !defined(WIN32)
+/**
+ * Apache Core dso functions are declared with AP_DECLARE(), so they may
+ * use the most appropriate calling convention. Hook functions and other
+ * Core functions with variable arguments must use AP_DECLARE_NONSTD().
+ * @code
+ * AP_DECLARE(rettype) ap_func(args)
+ * @endcode
+ */
+#define AP_DECLARE(type) type
+
+/**
+ * Apache Core dso variable argument and hook functions are declared with
+ * AP_DECLARE_NONSTD(), as they must use the C language calling convention.
+ * @see AP_DECLARE
+ * @code
+ * AP_DECLARE_NONSTD(rettype) ap_func(args [...])
+ * @endcode
+ */
+#define AP_DECLARE_NONSTD(type) type
+
+/**
+ * Apache Core dso variables are declared with AP_MODULE_DECLARE_DATA.
+ * This assures the appropriate indirection is invoked at compile time.
+ *
+ * @note AP_DECLARE_DATA extern type apr_variable; syntax is required for
+ * declarations within headers to properly import the variable.
+ * @code
+ * AP_DECLARE_DATA type apr_variable
+ * @endcode
+ */
+#define AP_DECLARE_DATA
+
+#elif defined(AP_DECLARE_STATIC)
+#define AP_DECLARE(type) type __stdcall
+#define AP_DECLARE_NONSTD(type) type
+#define AP_DECLARE_DATA
+#elif defined(AP_DECLARE_EXPORT)
+#define AP_DECLARE(type) __declspec(dllexport) type __stdcall
+#define AP_DECLARE_NONSTD(type) __declspec(dllexport) type
+#define AP_DECLARE_DATA __declspec(dllexport)
+#else
+#define AP_DECLARE(type) __declspec(dllimport) type __stdcall
+#define AP_DECLARE_NONSTD(type) __declspec(dllimport) type
+#define AP_DECLARE_DATA __declspec(dllimport)
+#endif
+
+#if !defined(WIN32) || defined(AP_MODULE_DECLARE_STATIC)
+/**
+ * Declare a dso module's exported module structure as AP_MODULE_DECLARE_DATA.
+ *
+ * Unless AP_MODULE_DECLARE_STATIC is defined at compile time, symbols
+ * declared with AP_MODULE_DECLARE_DATA are always exported.
+ * @code
+ * module AP_MODULE_DECLARE_DATA mod_tag
+ * @endcode
+ */
+#if defined(WIN32)
+#define AP_MODULE_DECLARE(type) type __stdcall
+#else
+#define AP_MODULE_DECLARE(type) type
+#endif
+#define AP_MODULE_DECLARE_NONSTD(type) type
+#define AP_MODULE_DECLARE_DATA
+#else
+/**
+ * AP_MODULE_DECLARE_EXPORT is a no-op. Unless contradicted by the
+ * AP_MODULE_DECLARE_STATIC compile-time symbol, it is assumed and defined.
+ *
+ * The old SHARED_MODULE compile-time symbol is now the default behavior,
+ * so it is no longer referenced anywhere with Apache 2.0.
+ */
+#define AP_MODULE_DECLARE_EXPORT
+#define AP_MODULE_DECLARE(type) __declspec(dllexport) type __stdcall
+#define AP_MODULE_DECLARE_NONSTD(type) __declspec(dllexport) type
+#define AP_MODULE_DECLARE_DATA __declspec(dllexport)
+#endif
+
+#include "os.h"
+#if (!defined(WIN32) && !defined(NETWARE)) || defined(__MINGW32__)
+#include "ap_config_auto.h"
+#endif
+#include "ap_config_layout.h"
+
+/* Where the main/parent process's pid is logged */
+#ifndef DEFAULT_PIDLOG
+#define DEFAULT_PIDLOG DEFAULT_REL_RUNTIMEDIR "/httpd.pid"
+#endif
+
+#if defined(NETWARE)
+#define AP_NONBLOCK_WHEN_MULTI_LISTEN 1
+#endif
+
+#if defined(AP_ENABLE_DTRACE) && HAVE_SYS_SDT_H
+#include <sys/sdt.h>
+#else
+#undef _DTRACE_VERSION
+#endif
+
+#ifdef _DTRACE_VERSION
+#include "apache_probes.h"
+#else
+#include "apache_noprobes.h"
+#endif
+
+/* If APR has OTHER_CHILD logic, use reliable piped logs. */
+#if APR_HAS_OTHER_CHILD
+#define AP_HAVE_RELIABLE_PIPED_LOGS TRUE
+#endif
+
+#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+#define AP_HAVE_C99
+#endif
+
+/* Presume that the compiler supports C99-style designated
+ * initializers if using GCC (but not G++), or for any other compiler
+ * which claims C99 support. */
+#if (defined(__GNUC__) && !defined(__cplusplus)) || defined(AP_HAVE_C99)
+#define AP_HAVE_DESIGNATED_INITIALIZER
+#endif
+
+#ifndef __has_attribute /* check for supported attributes on clang */
+#define __has_attribute(x) 0
+#endif
+#if (defined(__GNUC__) && __GNUC__ >= 4) || __has_attribute(sentinel)
+#define AP_FN_ATTR_SENTINEL __attribute__((sentinel))
+#else
+#define AP_FN_ATTR_SENTINEL
+#endif
+
+#if ( defined(__GNUC__) && \
+ (__GNUC__ >= 4 || ( __GNUC__ == 3 && __GNUC_MINOR__ >= 4))) \
+ || __has_attribute(warn_unused_result)
+#define AP_FN_ATTR_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
+#else
+#define AP_FN_ATTR_WARN_UNUSED_RESULT
+#endif
+
+#if ( defined(__GNUC__) && \
+ (__GNUC__ >= 4 && __GNUC_MINOR__ >= 3)) \
+ || __has_attribute(alloc_size)
+#define AP_FN_ATTR_ALLOC_SIZE(x) __attribute__((alloc_size(x)))
+#define AP_FN_ATTR_ALLOC_SIZE2(x,y) __attribute__((alloc_size(x,y)))
+#else
+#define AP_FN_ATTR_ALLOC_SIZE(x)
+#define AP_FN_ATTR_ALLOC_SIZE2(x,y)
+#endif
+
+#endif /* AP_CONFIG_H */
diff --git a/include/ap_config_auto.h.in b/include/ap_config_auto.h.in
new file mode 100644
index 0000000..ff93e54
--- /dev/null
+++ b/include/ap_config_auto.h.in
@@ -0,0 +1,319 @@
+/* include/ap_config_auto.h.in. Generated from configure.in by autoheader. */
+
+/* SuExec root directory */
+#undef AP_DOC_ROOT
+
+/* Enable DTrace probes */
+#undef AP_ENABLE_DTRACE
+
+/* Allow modules to run hook after a fatal exception */
+#undef AP_ENABLE_EXCEPTION_HOOK
+
+/* Allow IPv4 connections on IPv6 listening sockets */
+#undef AP_ENABLE_V4_MAPPED
+
+/* Minimum allowed GID */
+#undef AP_GID_MIN
+
+/* Enable the APR hook probes capability, reading from ap_hook_probes.h */
+#undef AP_HOOK_PROBES_ENABLED
+
+/* User allowed to call SuExec */
+#undef AP_HTTPD_USER
+
+/* SuExec log file */
+#undef AP_LOG_EXEC
+
+/* SuExec log to syslog */
+#undef AP_LOG_SYSLOG
+
+/* Listening sockets are non-blocking when there are more than 1 */
+#undef AP_NONBLOCK_WHEN_MULTI_LISTEN
+
+/* safe shell path for SuExec */
+#undef AP_SAFE_PATH
+
+/* Enable if suexec is installed with Linux capabilities, not setuid */
+#undef AP_SUEXEC_CAPABILITIES
+
+/* umask for suexec'd process */
+#undef AP_SUEXEC_UMASK
+
+/* Location of the MIME types config file, relative to the Apache root
+ directory */
+#undef AP_TYPES_CONFIG_FILE
+
+/* Minimum allowed UID */
+#undef AP_UID_MIN
+
+/* User subdirectory */
+#undef AP_USERDIR_SUFFIX
+
+/* Using autoconf to configure Apache */
+#undef AP_USING_AUTOCONF
+
+/* Define to 1 if you have the `arc4random_buf' function. */
+#undef HAVE_ARC4RANDOM_BUF
+
+/* Define to 1 if you have the `bindprocessor' function. */
+#undef HAVE_BINDPROCESSOR
+
+/* Define to 1 if you have the <bstring.h> header file. */
+#undef HAVE_BSTRING_H
+
+/* Define if curl is available */
+#undef HAVE_CURL
+
+/* Define to 1 if you have the <curl/curl.h> header file. */
+#undef HAVE_CURL_CURL_H
+
+/* Define if distcache support is enabled */
+#undef HAVE_DISTCACHE
+
+/* Define to 1 if you have the <distcache/dc_client.h> header file. */
+#undef HAVE_DISTCACHE_DC_CLIENT_H
+
+/* Define to 1 if you have the `ENGINE_init' function. */
+#undef HAVE_ENGINE_INIT
+
+/* Define to 1 if you have the `ENGINE_load_builtin_engines' function. */
+#undef HAVE_ENGINE_LOAD_BUILTIN_ENGINES
+
+/* Define to 1 if you have the `epoll_create' function. */
+#undef HAVE_EPOLL_CREATE
+
+/* Define to 1 if you have the `fopen64' function. */
+#undef HAVE_FOPEN64
+
+/* Define to 1 if you have the `getgrnam' function. */
+#undef HAVE_GETGRNAM
+
+/* Define to 1 if you have the `getloadavg' function. */
+#undef HAVE_GETLOADAVG
+
+/* Define to 1 if you have the `getpgid' function. */
+#undef HAVE_GETPGID
+
+/* Define to 1 if you have the `getpwnam' function. */
+#undef HAVE_GETPWNAM
+
+/* Define if you have gettid() */
+#undef HAVE_GETTID
+
+/* Define if struct tm has a tm_gmtoff field */
+#undef HAVE_GMTOFF
+
+/* Define to 1 if you have the <grp.h> header file. */
+#undef HAVE_GRP_H
+
+/* Define to 1 if you have the `initgroups' function. */
+#undef HAVE_INITGROUPS
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define if jansson is available */
+#undef HAVE_JANSSON
+
+/* Define to 1 if you have the `killpg' function. */
+#undef HAVE_KILLPG
+
+/* Define to 1 if you have the `kqueue' function. */
+#undef HAVE_KQUEUE
+
+/* Define to 1 if you have the <limits.h> header file. */
+#undef HAVE_LIMITS_H
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define if nghttp2 is available */
+#undef HAVE_NGHTTP2
+
+/* Define to 1 if you have the <nghttp2/nghttp2.h> header file. */
+#undef HAVE_NGHTTP2_NGHTTP2_H
+
+/* Define to 1 if you have the
+ `nghttp2_session_callbacks_set_on_invalid_header_callback' function. */
+#undef HAVE_NGHTTP2_SESSION_CALLBACKS_SET_ON_INVALID_HEADER_CALLBACK
+
+/* Define to 1 if you have the `nghttp2_session_change_stream_priority'
+ function. */
+#undef HAVE_NGHTTP2_SESSION_CHANGE_STREAM_PRIORITY
+
+/* Define to 1 if you have the `nghttp2_session_get_stream_local_window_size'
+ function. */
+#undef HAVE_NGHTTP2_SESSION_GET_STREAM_LOCAL_WINDOW_SIZE
+
+/* Define to 1 if you have the `nghttp2_session_server_new2' function. */
+#undef HAVE_NGHTTP2_SESSION_SERVER_NEW2
+
+/* Define to 1 if you have the `nghttp2_stream_get_weight' function. */
+#undef HAVE_NGHTTP2_STREAM_GET_WEIGHT
+
+/* Define if OpenSSL is available */
+#undef HAVE_OPENSSL
+
+/* Define to 1 if you have the <openssl/engine.h> header file. */
+#undef HAVE_OPENSSL_ENGINE_H
+
+/* Define to 1 if you have the `port_create' function. */
+#undef HAVE_PORT_CREATE
+
+/* Define to 1 if you have the `prctl' function. */
+#undef HAVE_PRCTL
+
+/* Define to 1 if you have the <priv.h> header file. */
+#undef HAVE_PRIV_H
+
+/* Define to 1 if you have the `pthread_kill' function. */
+#undef HAVE_PTHREAD_KILL
+
+/* Define to 1 if you have the <pwd.h> header file. */
+#undef HAVE_PWD_H
+
+/* Define to 1 if you have the `RAND_egd' function. */
+#undef HAVE_RAND_EGD
+
+/* Define to 1 if you have the `setsid' function. */
+#undef HAVE_SETSID
+
+/* Define to 1 if you have the `SSL_CTX_new' function. */
+#undef HAVE_SSL_CTX_NEW
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if you have the `syslog' function. */
+#undef HAVE_SYSLOG
+
+/* Define to 1 if you have the <sys/ipc.h> header file. */
+#undef HAVE_SYS_IPC_H
+
+/* Define to 1 if you have the <sys/loadavg.h> header file. */
+#undef HAVE_SYS_LOADAVG_H
+
+/* Define to 1 if you have the <sys/prctl.h> header file. */
+#undef HAVE_SYS_PRCTL_H
+
+/* Define to 1 if you have the <sys/processor.h> header file. */
+#undef HAVE_SYS_PROCESSOR_H
+
+/* Define to 1 if you have the <sys/resource.h> header file. */
+#undef HAVE_SYS_RESOURCE_H
+
+/* Define to 1 if you have the <sys/sdt.h> header file. */
+#undef HAVE_SYS_SDT_H
+
+/* Define to 1 if you have the <sys/sem.h> header file. */
+#undef HAVE_SYS_SEM_H
+
+/* Define to 1 if you have the <sys/socket.h> header file. */
+#undef HAVE_SYS_SOCKET_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/times.h> header file. */
+#undef HAVE_SYS_TIMES_H
+
+/* Define to 1 if you have the <sys/time.h> header file. */
+#undef HAVE_SYS_TIME_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have <sys/wait.h> that is POSIX.1 compatible. */
+#undef HAVE_SYS_WAIT_H
+
+/* Define to 1 if you have the `timegm' function. */
+#undef HAVE_TIMEGM
+
+/* Define to 1 if you have the `times' function. */
+#undef HAVE_TIMES
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define to 1 if you have the `vsyslog' function. */
+#undef HAVE_VSYSLOG
+
+/* Root directory of the Apache install area */
+#undef HTTPD_ROOT
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the home page for this package. */
+#undef PACKAGE_URL
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* Location of the config file, relative to the Apache root directory */
+#undef SERVER_CONFIG_FILE
+
+/* This platform doesn't suffer from the thundering herd problem */
+#undef SINGLE_LISTEN_UNSERIALIZED_ACCEPT
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Path to suexec binary */
+#undef SUEXEC_BIN
+
+/* Enable extensions on AIX 3, Interix. */
+#ifndef _ALL_SOURCE
+# undef _ALL_SOURCE
+#endif
+/* Enable GNU extensions on systems that have them. */
+#ifndef _GNU_SOURCE
+# undef _GNU_SOURCE
+#endif
+/* Enable threading extensions on Solaris. */
+#ifndef _POSIX_PTHREAD_SEMANTICS
+# undef _POSIX_PTHREAD_SEMANTICS
+#endif
+/* Enable extensions on HP NonStop. */
+#ifndef _TANDEM_SOURCE
+# undef _TANDEM_SOURCE
+#endif
+/* Enable general extensions on Solaris. */
+#ifndef __EXTENSIONS__
+# undef __EXTENSIONS__
+#endif
+
+
+/* Define to 1 if on MINIX. */
+#undef _MINIX
+
+/* Define to 2 if the system does not provide POSIX.1 features except with
+ this defined. */
+#undef _POSIX_1_SOURCE
+
+/* Define to 1 if you need to in order for `stat' and other things to work. */
+#undef _POSIX_SOURCE
+
+/* Define to empty if `const' does not conform to ANSI C. */
+#undef const
+
+/* Define to 'int' if <sys/resource.h> doesn't define it for us */
+#undef rlim_t
diff --git a/include/ap_config_layout.h.in b/include/ap_config_layout.h.in
new file mode 100644
index 0000000..2b4a70c
--- /dev/null
+++ b/include/ap_config_layout.h.in
@@ -0,0 +1,64 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file ap_config_layout.h
+ * @brief Apache Config Layout
+ */
+
+#ifndef AP_CONFIG_LAYOUT_H
+#define AP_CONFIG_LAYOUT_H
+
+/* Configured Apache directory layout */
+#define DEFAULT_PREFIX "@prefix@"
+#define DEFAULT_EXP_EXEC_PREFIX "@exp_exec_prefix@"
+#define DEFAULT_REL_EXEC_PREFIX "@rel_exec_prefix@"
+#define DEFAULT_EXP_BINDIR "@exp_bindir@"
+#define DEFAULT_REL_BINDIR "@rel_bindir@"
+#define DEFAULT_EXP_SBINDIR "@exp_sbindir@"
+#define DEFAULT_REL_SBINDIR "@rel_sbindir@"
+#define DEFAULT_EXP_LIBEXECDIR "@exp_libexecdir@"
+#define DEFAULT_REL_LIBEXECDIR "@rel_libexecdir@"
+#define DEFAULT_EXP_MANDIR "@exp_mandir@"
+#define DEFAULT_REL_MANDIR "@rel_mandir@"
+#define DEFAULT_EXP_SYSCONFDIR "@exp_sysconfdir@"
+#define DEFAULT_REL_SYSCONFDIR "@rel_sysconfdir@"
+#define DEFAULT_EXP_DATADIR "@exp_datadir@"
+#define DEFAULT_REL_DATADIR "@rel_datadir@"
+#define DEFAULT_EXP_INSTALLBUILDDIR "@exp_installbuilddir@"
+#define DEFAULT_REL_INSTALLBUILDDIR "@rel_installbuilddir@"
+#define DEFAULT_EXP_ERRORDIR "@exp_errordir@"
+#define DEFAULT_REL_ERRORDIR "@rel_errordir@"
+#define DEFAULT_EXP_ICONSDIR "@exp_iconsdir@"
+#define DEFAULT_REL_ICONSDIR "@rel_iconsdir@"
+#define DEFAULT_EXP_HTDOCSDIR "@exp_htdocsdir@"
+#define DEFAULT_REL_HTDOCSDIR "@rel_htdocsdir@"
+#define DEFAULT_EXP_MANUALDIR "@exp_manualdir@"
+#define DEFAULT_REL_MANUALDIR "@rel_manualdir@"
+#define DEFAULT_EXP_CGIDIR "@exp_cgidir@"
+#define DEFAULT_REL_CGIDIR "@rel_cgidir@"
+#define DEFAULT_EXP_INCLUDEDIR "@exp_includedir@"
+#define DEFAULT_REL_INCLUDEDIR "@rel_includedir@"
+#define DEFAULT_EXP_LOCALSTATEDIR "@exp_localstatedir@"
+#define DEFAULT_REL_LOCALSTATEDIR "@rel_localstatedir@"
+#define DEFAULT_EXP_RUNTIMEDIR "@exp_runtimedir@"
+#define DEFAULT_REL_RUNTIMEDIR "@rel_runtimedir@"
+#define DEFAULT_EXP_LOGFILEDIR "@exp_logfiledir@"
+#define DEFAULT_REL_LOGFILEDIR "@rel_logfiledir@"
+#define DEFAULT_EXP_PROXYCACHEDIR "@exp_proxycachedir@"
+#define DEFAULT_REL_PROXYCACHEDIR "@rel_proxycachedir@"
+
+#endif /* AP_CONFIG_LAYOUT_H */
diff --git a/include/ap_expr.h b/include/ap_expr.h
new file mode 100644
index 0000000..55fff36
--- /dev/null
+++ b/include/ap_expr.h
@@ -0,0 +1,353 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file ap_expr.h
+ * @brief Expression parser
+ *
+ * @defgroup AP_EXPR Expression parser
+ * @ingroup APACHE_CORE
+ * @{
+ */
+
+#ifndef AP_EXPR_H
+#define AP_EXPR_H
+
+#include "httpd.h"
+#include "http_config.h"
+#include "ap_regex.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** A node in the expression parse tree */
+typedef struct ap_expr_node ap_expr_t;
+
+/** Struct describing a parsed expression */
+typedef struct {
+ /** The root of the actual expression parse tree */
+ ap_expr_t *root_node;
+ /** The filename where the expression has been defined (for logging).
+ * May be NULL
+ */
+ const char *filename;
+ /** The line number where the expression has been defined (for logging). */
+ unsigned int line_number;
+ /** Flags relevant for the expression, see AP_EXPR_FLAG_* */
+ unsigned int flags;
+ /** The module that is used for loglevel configuration */
+ int module_index;
+} ap_expr_info_t;
+
+/** Use ssl_expr compatibility mode (changes the meaning of the comparison
+ * operators)
+ */
+#define AP_EXPR_FLAG_SSL_EXPR_COMPAT 1
+/** Don't add siginificant request headers to the Vary response header */
+#define AP_EXPR_FLAG_DONT_VARY 2
+/** Don't allow functions/vars that bypass the current request's access
+ * restrictions or would otherwise leak confidential information.
+ * Used by e.g. mod_include.
+ */
+#define AP_EXPR_FLAG_RESTRICTED 4
+/** Expression evaluates to a string, not to a bool */
+#define AP_EXPR_FLAG_STRING_RESULT 8
+
+
+/**
+ * Evaluate a parse tree, simple interface
+ * @param r The current request
+ * @param expr The expression to be evaluated
+ * @param err Where an error message should be stored
+ * @return > 0 if expression evaluates to true, == 0 if false, < 0 on error
+ * @note err will be set to NULL on success, or to an error message on error
+ * @note request headers used during evaluation will be added to the Vary:
+ * response header, unless ::AP_EXPR_FLAG_DONT_VARY is set.
+ */
+AP_DECLARE(int) ap_expr_exec(request_rec *r, const ap_expr_info_t *expr,
+ const char **err);
+
+/**
+ * Evaluate a parse tree, with access to regexp backreference
+ * @param r The current request
+ * @param expr The expression to be evaluated
+ * @param nmatch size of the regex match vector pmatch
+ * @param pmatch information about regex matches
+ * @param source the string that pmatch applies to
+ * @param err Where an error message should be stored
+ * @return > 0 if expression evaluates to true, == 0 if false, < 0 on error
+ * @note err will be set to NULL on success, or to an error message on error
+ * @note nmatch/pmatch/source can be used both to make previous matches
+ * available to ap_expr_exec_re and to use ap_expr_exec_re's matches
+ * later on.
+ * @note request headers used during evaluation will be added to the Vary:
+ * response header, unless ::AP_EXPR_FLAG_DONT_VARY is set.
+ */
+AP_DECLARE(int) ap_expr_exec_re(request_rec *r, const ap_expr_info_t *expr,
+ apr_size_t nmatch, ap_regmatch_t *pmatch,
+ const char **source, const char **err);
+
+/** Context used during evaluation of a parse tree, created by ap_expr_exec */
+typedef struct {
+ /** the current request */
+ request_rec *r;
+ /** the current connection */
+ conn_rec *c;
+ /** the current virtual host */
+ server_rec *s;
+ /** the pool to use */
+ apr_pool_t *p;
+ /** where to store the error string */
+ const char **err;
+ /** ap_expr_info_t for the expression */
+ const ap_expr_info_t *info;
+ /** regex match information for back references */
+ ap_regmatch_t *re_pmatch;
+ /** size of the vector pointed to by re_pmatch */
+ apr_size_t re_nmatch;
+ /** the string corresponding to the re_pmatch */
+ const char **re_source;
+ /** A string where the comma separated names of headers are stored
+ * to be later added to the Vary: header. If NULL, the caller is not
+ * interested in this information.
+ */
+ const char **vary_this;
+ /** where to store the result string */
+ const char **result_string;
+ /** Arbitrary context data provided by the caller for custom functions */
+ void *data;
+ /** The current recursion level */
+ int reclvl;
+} ap_expr_eval_ctx_t;
+
+/**
+ * Evaluate a parse tree, full featured version
+ * @param ctx The evaluation context with all data filled in
+ * @return > 0 if expression evaluates to true, == 0 if false, < 0 on error
+ * @note *ctx->err will be set to NULL on success, or to an error message on
+ * error
+ * @note request headers used during evaluation will be added to the Vary:
+ * response header if ctx->vary_this is set.
+ */
+AP_DECLARE(int) ap_expr_exec_ctx(ap_expr_eval_ctx_t *ctx);
+
+/**
+ * Evaluate a parse tree of a string valued expression
+ * @param r The current request
+ * @param expr The expression to be evaluated
+ * @param err Where an error message should be stored
+ * @return The result string, NULL on error
+ * @note err will be set to NULL on success, or to an error message on error
+ * @note request headers used during evaluation will be added to the Vary:
+ * response header, unless ::AP_EXPR_FLAG_DONT_VARY is set.
+ */
+AP_DECLARE(const char *) ap_expr_str_exec(request_rec *r,
+ const ap_expr_info_t *expr,
+ const char **err);
+
+/**
+ * Evaluate a parse tree of a string valued expression
+ * @param r The current request
+ * @param expr The expression to be evaluated
+ * @param nmatch size of the regex match vector pmatch
+ * @param pmatch information about regex matches
+ * @param source the string that pmatch applies to
+ * @param err Where an error message should be stored
+ * @return The result string, NULL on error
+ * @note err will be set to NULL on success, or to an error message on error
+ * @note nmatch/pmatch/source can be used both to make previous matches
+ * available to ap_expr_exec_re and to use ap_expr_exec_re's matches
+ * later on.
+ * @note request headers used during evaluation will be added to the Vary:
+ * response header, unless ::AP_EXPR_FLAG_DONT_VARY is set.
+ */
+AP_DECLARE(const char *) ap_expr_str_exec_re(request_rec *r,
+ const ap_expr_info_t *expr,
+ apr_size_t nmatch,
+ ap_regmatch_t *pmatch,
+ const char **source,
+ const char **err);
+
+
+/**
+ * The parser can be extended with variable lookup, functions, and
+ * and operators.
+ *
+ * During parsing, the parser calls the lookup function to resolve a
+ * name into a function pointer and an opaque context for the function.
+ * If the argument to a function or operator is constant, the lookup function
+ * may also parse that argument and store the parsed data in the context.
+ *
+ * The default lookup function is the hook ::ap_expr_lookup_default which just
+ * calls ap_run_expr_lookup. Modules can use it to make functions and
+ * variables generally available.
+ *
+ * An ap_expr consumer can also provide its own custom lookup function to
+ * modify the set of variables and functions that are available. The custom
+ * lookup function can in turn call 'ap_run_expr_lookup'.
+ */
+
+/** Unary operator, takes one string argument and returns a bool value.
+ * The name must have the form '-z' (one letter only).
+ * @param ctx The evaluation context
+ * @param data An opaque context provided by the lookup hook function
+ * @param arg The (right) operand
+ * @return 0 or 1
+ */
+typedef int ap_expr_op_unary_t(ap_expr_eval_ctx_t *ctx, const void *data,
+ const char *arg);
+
+/** Binary operator, takes two string arguments and returns a bool value.
+ * The name must have the form '-cmp' (at least two letters).
+ * @param ctx The evaluation context
+ * @param data An opaque context provided by the lookup hook function
+ * @param arg1 The left operand
+ * @param arg2 The right operand
+ * @return 0 or 1
+ */
+typedef int ap_expr_op_binary_t(ap_expr_eval_ctx_t *ctx, const void *data,
+ const char *arg1, const char *arg2);
+
+/** String valued function, takes a string argument and returns a string
+ * @param ctx The evaluation context
+ * @param data An opaque context provided by the lookup hook function
+ * @param arg The argument
+ * @return The functions result string, may be NULL for 'empty string'
+ */
+typedef const char *(ap_expr_string_func_t)(ap_expr_eval_ctx_t *ctx,
+ const void *data,
+ const char *arg);
+
+/** List valued function, takes a string argument and returns a list of strings
+ * Can currently only be called following the builtin '-in' operator.
+ * @param ctx The evaluation context
+ * @param data An opaque context provided by the lookup hook function
+ * @param arg The argument
+ * @return The functions result list of strings, may be NULL for 'empty array'
+ */
+typedef apr_array_header_t *(ap_expr_list_func_t)(ap_expr_eval_ctx_t *ctx,
+ const void *data,
+ const char *arg);
+
+/** Variable lookup function, takes no argument and returns a string
+ * @param ctx The evaluation context
+ * @param data An opaque context provided by the lookup hook function
+ * @return The expanded variable
+ */
+typedef const char *(ap_expr_var_func_t)(ap_expr_eval_ctx_t *ctx,
+ const void *data);
+
+/** parameter struct passed to the lookup hook functions */
+typedef struct {
+ /** type of the looked up object */
+ int type;
+#define AP_EXPR_FUNC_VAR 0
+#define AP_EXPR_FUNC_STRING 1
+#define AP_EXPR_FUNC_LIST 2
+#define AP_EXPR_FUNC_OP_UNARY 3
+#define AP_EXPR_FUNC_OP_BINARY 4
+ /** name of the looked up object */
+ const char *name;
+
+ int flags;
+
+ apr_pool_t *pool;
+ apr_pool_t *ptemp;
+
+ /** where to store the function pointer */
+ const void **func;
+ /** where to store the function's context */
+ const void **data;
+ /** where to store the error message (if any) */
+ const char **err;
+
+ /** arg for pre-parsing (only if a simple string).
+ * For binary ops, this is the right argument. */
+ const char *arg;
+} ap_expr_lookup_parms;
+
+/** Function for looking up the provider function for a variable, operator
+ * or function in an expression.
+ * @param parms The parameter struct, also determins where the result is
+ * stored.
+ * @return OK on success,
+ * !OK on failure,
+ * DECLINED if the requested name is not handled by this function
+ */
+typedef int (ap_expr_lookup_fn_t)(ap_expr_lookup_parms *parms);
+
+/** Default lookup function which just calls ap_run_expr_lookup().
+ * ap_run_expr_lookup cannot be used directly because it has the wrong
+ * calling convention under Windows.
+ */
+AP_DECLARE_NONSTD(int) ap_expr_lookup_default(ap_expr_lookup_parms *parms);
+
+AP_DECLARE_HOOK(int, expr_lookup, (ap_expr_lookup_parms *parms))
+
+/**
+ * Parse an expression into a parse tree
+ * @param pool Pool
+ * @param ptemp temp pool
+ * @param info The ap_expr_info_t struct (with values filled in)
+ * @param expr The expression string to parse
+ * @param lookup_fn The lookup function to use, NULL for default
+ * @return NULL on success, error message on error.
+ * A pointer to the resulting parse tree will be stored in
+ * info->root_node.
+ */
+AP_DECLARE(const char *) ap_expr_parse(apr_pool_t *pool, apr_pool_t *ptemp,
+ ap_expr_info_t *info, const char *expr,
+ ap_expr_lookup_fn_t *lookup_fn);
+
+/**
+ * High level interface to ap_expr_parse that also creates ap_expr_info_t and
+ * uses info from cmd_parms to fill in most of it.
+ * @param cmd The cmd_parms struct
+ * @param expr The expression string to parse
+ * @param flags The flags to use, see AP_EXPR_FLAG_*
+ * @param err Set to NULL on success, error message on error
+ * @param lookup_fn The lookup function used to lookup vars, functions, and
+ * operators
+ * @param module_index The module_index to set for the expression
+ * @return The parsed expression
+ * @note Usually ap_expr_parse_cmd() should be used
+ */
+AP_DECLARE(ap_expr_info_t *) ap_expr_parse_cmd_mi(const cmd_parms *cmd,
+ const char *expr,
+ unsigned int flags,
+ const char **err,
+ ap_expr_lookup_fn_t *lookup_fn,
+ int module_index);
+
+/**
+ * Convenience wrapper for ap_expr_parse_cmd_mi() that sets
+ * module_index = APLOG_MODULE_INDEX
+ */
+#define ap_expr_parse_cmd(cmd, expr, flags, err, lookup_fn) \
+ ap_expr_parse_cmd_mi(cmd, expr, flags, err, lookup_fn, APLOG_MODULE_INDEX)
+
+ /**
+ * Internal initialisation of ap_expr (for httpd internal use)
+ */
+void ap_expr_init(apr_pool_t *pool);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* AP_EXPR_H */
+/** @} */
diff --git a/include/ap_hooks.h b/include/ap_hooks.h
new file mode 100644
index 0000000..43d38e7
--- /dev/null
+++ b/include/ap_hooks.h
@@ -0,0 +1,162 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file ap_hooks.h
+ * @brief ap hook functions and macros
+ */
+
+#ifndef AP_HOOKS_H
+#define AP_HOOKS_H
+
+/* Although this file doesn't declare any hooks, declare the hook group here */
+/**
+ * @defgroup hooks Apache Hooks
+ * @ingroup APACHE_CORE
+ */
+
+#if defined(AP_HOOK_PROBES_ENABLED) && !defined(APR_HOOK_PROBES_ENABLED)
+#define APR_HOOK_PROBES_ENABLED 1
+#endif
+
+#ifdef APR_HOOK_PROBES_ENABLED
+#include "ap_hook_probes.h"
+#endif
+
+#include "apr.h"
+#include "apr_hooks.h"
+#include "apr_optional_hooks.h"
+
+#ifdef DOXYGEN
+/* define these just so doxygen documents them */
+
+/**
+ * AP_DECLARE_STATIC is defined when including Apache's Core headers,
+ * to provide static linkage when the dynamic library may be unavailable.
+ *
+ * @see AP_DECLARE_EXPORT
+ *
+ * AP_DECLARE_STATIC and AP_DECLARE_EXPORT are left undefined when
+ * including Apache's Core headers, to import and link the symbols from the
+ * dynamic Apache Core library and assure appropriate indirection and calling
+ * conventions at compile time.
+ */
+# define AP_DECLARE_STATIC
+/**
+ * AP_DECLARE_EXPORT is defined when building the Apache Core dynamic
+ * library, so that all public symbols are exported.
+ *
+ * @see AP_DECLARE_STATIC
+ */
+# define AP_DECLARE_EXPORT
+
+#endif /* def DOXYGEN */
+
+/**
+ * Declare a hook function
+ * @param ret The return type of the hook
+ * @param name The hook's name (as a literal)
+ * @param args The arguments the hook function takes, in brackets.
+ */
+#define AP_DECLARE_HOOK(ret,name,args) \
+ APR_DECLARE_EXTERNAL_HOOK(ap,AP,ret,name,args)
+
+/** @internal */
+#define AP_IMPLEMENT_HOOK_BASE(name) \
+ APR_IMPLEMENT_EXTERNAL_HOOK_BASE(ap,AP,name)
+
+/**
+ * Implement an Apache core hook that has no return code, and
+ * therefore runs all of the registered functions. The implementation
+ * is called ap_run_<i>name</i>.
+ *
+ * @param name The name of the hook
+ * @param args_decl The declaration of the arguments for the hook, for example
+ * "(int x,void *y)"
+ * @param args_use The arguments for the hook as used in a call, for example
+ * "(x,y)"
+ * @note If IMPLEMENTing a hook that is not linked into the Apache core,
+ * (e.g. within a dso) see APR_IMPLEMENT_EXTERNAL_HOOK_VOID.
+ */
+#define AP_IMPLEMENT_HOOK_VOID(name,args_decl,args_use) \
+ APR_IMPLEMENT_EXTERNAL_HOOK_VOID(ap,AP,name,args_decl,args_use)
+
+/**
+ * Implement an Apache core hook that runs until one of the functions
+ * returns something other than ok or decline. That return value is
+ * then returned from the hook runner. If the hooks run to completion,
+ * then ok is returned. Note that if no hook runs it would probably be
+ * more correct to return decline, but this currently does not do
+ * so. The implementation is called ap_run_<i>name</i>.
+ *
+ * @param ret The return type of the hook (and the hook runner)
+ * @param name The name of the hook
+ * @param args_decl The declaration of the arguments for the hook, for example
+ * "(int x,void *y)"
+ * @param args_use The arguments for the hook as used in a call, for example
+ * "(x,y)"
+ * @param ok The "ok" return value
+ * @param decline The "decline" return value
+ * @return ok, decline or an error.
+ * @note If IMPLEMENTing a hook that is not linked into the Apache core,
+ * (e.g. within a dso) see APR_IMPLEMENT_EXTERNAL_HOOK_RUN_ALL.
+ */
+#define AP_IMPLEMENT_HOOK_RUN_ALL(ret,name,args_decl,args_use,ok,decline) \
+ APR_IMPLEMENT_EXTERNAL_HOOK_RUN_ALL(ap,AP,ret,name,args_decl, \
+ args_use,ok,decline)
+
+/**
+ * Implement a hook that runs until a function returns something other than
+ * decline. If all functions return decline, the hook runner returns decline.
+ * The implementation is called ap_run_<i>name</i>.
+ *
+ * @param ret The return type of the hook (and the hook runner)
+ * @param name The name of the hook
+ * @param args_decl The declaration of the arguments for the hook, for example
+ * "(int x,void *y)"
+ * @param args_use The arguments for the hook as used in a call, for example
+ * "(x,y)"
+ * @param decline The "decline" return value
+ * @return decline or an error.
+ * @note If IMPLEMENTing a hook that is not linked into the Apache core
+ * (e.g. within a dso) see APR_IMPLEMENT_EXTERNAL_HOOK_RUN_FIRST.
+ */
+#define AP_IMPLEMENT_HOOK_RUN_FIRST(ret,name,args_decl,args_use,decline) \
+ APR_IMPLEMENT_EXTERNAL_HOOK_RUN_FIRST(ap,AP,ret,name,args_decl, \
+ args_use,decline)
+
+/* Note that the other optional hook implementations are straightforward but
+ * have not yet been needed
+ */
+
+/**
+ * Implement an optional hook. This is exactly the same as a standard hook
+ * implementation, except the hook is optional.
+ * @see AP_IMPLEMENT_HOOK_RUN_ALL
+ */
+#define AP_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(ret,name,args_decl,args_use,ok, \
+ decline) \
+ APR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(ap,AP,ret,name,args_decl, \
+ args_use,ok,decline)
+
+/**
+ * Hook an optional hook. Unlike static hooks, this uses a macro instead of a
+ * function.
+ */
+#define AP_OPTIONAL_HOOK(name,fn,pre,succ,order) \
+ APR_OPTIONAL_HOOK(ap,name,fn,pre,succ,order)
+
+#endif /* AP_HOOKS_H */
diff --git a/include/ap_listen.h b/include/ap_listen.h
new file mode 100644
index 0000000..58c2574
--- /dev/null
+++ b/include/ap_listen.h
@@ -0,0 +1,163 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file ap_listen.h
+ * @brief Apache Listeners Library
+ *
+ * @defgroup APACHE_CORE_LISTEN Apache Listeners Library
+ * @ingroup APACHE_CORE
+ * @{
+ */
+
+#ifndef AP_LISTEN_H
+#define AP_LISTEN_H
+
+#include "apr_network_io.h"
+#include "httpd.h"
+#include "http_config.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct ap_slave_t ap_slave_t;
+typedef struct ap_listen_rec ap_listen_rec;
+typedef apr_status_t (*accept_function)(void **csd, ap_listen_rec *lr, apr_pool_t *ptrans);
+
+/**
+ * @brief Apache's listeners record.
+ *
+ * These are used in the Multi-Processing Modules
+ * to setup all of the sockets for the MPM to listen to and accept on.
+ */
+struct ap_listen_rec {
+ /**
+ * The next listener in the list
+ */
+ ap_listen_rec *next;
+ /**
+ * The actual socket
+ */
+ apr_socket_t *sd;
+ /**
+ * The sockaddr the socket should bind to
+ */
+ apr_sockaddr_t *bind_addr;
+ /**
+ * The accept function for this socket
+ */
+ accept_function accept_func;
+ /**
+ * Is this socket currently active
+ */
+ int active;
+ /**
+ * The default protocol for this listening socket.
+ */
+ const char* protocol;
+
+ ap_slave_t *slave;
+};
+
+/**
+ * The global list of ap_listen_rec structures
+ */
+AP_DECLARE_DATA extern ap_listen_rec *ap_listeners;
+AP_DECLARE_DATA extern int ap_num_listen_buckets;
+AP_DECLARE_DATA extern int ap_have_so_reuseport;
+
+/**
+ * Setup all of the defaults for the listener list
+ */
+AP_DECLARE(void) ap_listen_pre_config(void);
+
+/**
+ * Loop through the global ap_listen_rec list and create all of the required
+ * sockets. This executes the listen and bind on the sockets.
+ * @param s The global server_rec
+ * @return The number of open sockets.
+ */
+AP_DECLARE(int) ap_setup_listeners(server_rec *s);
+
+/**
+ * This function duplicates ap_listeners into multiple buckets when configured
+ * to (see ListenCoresBucketsRatio) and the platform supports it (eg. number of
+ * online CPU cores and SO_REUSEPORT available).
+ * @param p The config pool
+ * @param s The global server_rec
+ * @param buckets The array of listeners buckets.
+ * @param num_buckets The total number of listeners buckets (array size).
+ * @remark If the given *num_buckets is 0 (input), it will be computed
+ * according to the platform capacities, otherwise (positive) it
+ * will be preserved. The number of listeners duplicated will
+ * always match *num_buckets, be it computed or given.
+ */
+AP_DECLARE(apr_status_t) ap_duplicate_listeners(apr_pool_t *p, server_rec *s,
+ ap_listen_rec ***buckets,
+ int *num_buckets);
+
+/**
+ * Loop through the global ap_listen_rec list and close each of the sockets.
+ */
+AP_DECLARE_NONSTD(void) ap_close_listeners(void);
+
+/**
+ * Loop through the given ap_listen_rec list and close each of the sockets.
+ * @param listeners The listener to close.
+ */
+AP_DECLARE_NONSTD(void) ap_close_listeners_ex(ap_listen_rec *listeners);
+
+/**
+ * FIXMEDOC
+ */
+AP_DECLARE_NONSTD(int) ap_close_selected_listeners(ap_slave_t *);
+
+/* Although these functions are exported from libmain, they are not really
+ * public functions. These functions are actually called while parsing the
+ * config file, when one of the LISTEN_COMMANDS directives is read. These
+ * should not ever be called by external modules. ALL MPMs should include
+ * LISTEN_COMMANDS in their command_rec table so that these functions are
+ * called.
+ */
+AP_DECLARE_NONSTD(const char *) ap_set_listenbacklog(cmd_parms *cmd, void *dummy, const char *arg);
+AP_DECLARE_NONSTD(const char *) ap_set_listencbratio(cmd_parms *cmd, void *dummy, const char *arg);
+AP_DECLARE_NONSTD(const char *) ap_set_listener(cmd_parms *cmd, void *dummy,
+ int argc, char *const argv[]);
+AP_DECLARE_NONSTD(const char *) ap_set_send_buffer_size(cmd_parms *cmd, void *dummy,
+ const char *arg);
+AP_DECLARE_NONSTD(const char *) ap_set_receive_buffer_size(cmd_parms *cmd,
+ void *dummy,
+ const char *arg);
+
+#define LISTEN_COMMANDS \
+AP_INIT_TAKE1("ListenBacklog", ap_set_listenbacklog, NULL, RSRC_CONF, \
+ "Maximum length of the queue of pending connections, as used by listen(2)"), \
+AP_INIT_TAKE1("ListenCoresBucketsRatio", ap_set_listencbratio, NULL, RSRC_CONF, \
+ "Ratio between the number of CPU cores (online) and the number of listeners buckets"), \
+AP_INIT_TAKE_ARGV("Listen", ap_set_listener, NULL, RSRC_CONF, \
+ "A port number or a numeric IP address and a port number, and an optional protocol"), \
+AP_INIT_TAKE1("SendBufferSize", ap_set_send_buffer_size, NULL, RSRC_CONF, \
+ "Send buffer size in bytes"), \
+AP_INIT_TAKE1("ReceiveBufferSize", ap_set_receive_buffer_size, NULL, \
+ RSRC_CONF, "Receive buffer size in bytes")
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/** @} */
diff --git a/include/ap_mmn.h b/include/ap_mmn.h
new file mode 100644
index 0000000..2167baa
--- /dev/null
+++ b/include/ap_mmn.h
@@ -0,0 +1,566 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file ap_mmn.h
+ * @brief Module Magic Number
+ *
+ * @defgroup APACHE_CORE_MMN Module Magic Number
+ * @ingroup APACHE_CORE
+ * @{
+ */
+
+#ifndef APACHE_AP_MMN_H
+#define APACHE_AP_MMN_H
+
+/*
+ * MODULE_MAGIC_NUMBER_MAJOR
+ * Major API changes that could cause compatibility problems for older modules
+ * such as structure size changes. No binary compatibility is possible across
+ * a change in the major version.
+ *
+ * MODULE_MAGIC_NUMBER_MINOR
+ * Minor API changes that do not cause binary compatibility problems.
+ * Should be reset to 0 when upgrading MODULE_MAGIC_NUMBER_MAJOR.
+ *
+ * See the AP_MODULE_MAGIC_AT_LEAST macro below for an example.
+ */
+
+/*
+ * 20010224 (2.0.13-dev) MODULE_MAGIC_COOKIE reset to "AP20"
+ * 20010523 (2.0.19-dev) bump for scoreboard structure reordering
+ * 20010627 (2.0.19-dev) more API changes than I can count
+ * 20010726 (2.0.22-dev) more big API changes
+ * 20010808 (2.0.23-dev) dir d_is_absolute bit introduced, bucket changes, etc
+ * 20010825 (2.0.25-dev) removed d_is_absolute, introduced map_to_storage hook
+ * 20011002 (2.0.26-dev) removed 1.3-deprecated request_rec.content_language
+ * 20011127 (2.0.29-dev) bump for postconfig hook change, and removal of
+ * socket from connection record
+ * 20011212 (2.0.30-dev) bump for new used_path_info member of request_rec
+ * 20011218 (2.0.30-dev) bump for new sbh member of conn_rec, different
+ * declarations for scoreboard, new parameter to
+ * create_connection hook
+ * 20020102 (2.0.30-dev) bump for changed type of limit_req_body in
+ * core_dir_config
+ * 20020109 (2.0.31-dev) bump for changed shm and scoreboard declarations
+ * 20020111 (2.0.31-dev) bump for ETag fields added at end of cor_dir_config
+ * 20020114 (2.0.31-dev) mod_dav changed how it asks its provider to fulfill
+ * a GET request
+ * 20020118 (2.0.31-dev) Input filtering split of blocking and mode
+ * 20020127 (2.0.31-dev) bump for pre_mpm hook change
+ * 20020128 (2.0.31-dev) bump for pre_config hook change
+ * 20020218 (2.0.33-dev) bump for AddOutputFilterByType directive
+ * 20020220 (2.0.33-dev) bump for scoreboard.h structure change
+ * 20020302 (2.0.33-dev) bump for protocol_filter additions.
+ * 20020306 (2.0.34-dev) bump for filter type renames.
+ * 20020318 (2.0.34-dev) mod_dav's API for REPORT generation changed
+ * 20020319 (2.0.34-dev) M_INVALID changed, plus new M_* methods for RFC 3253
+ * 20020327 (2.0.35-dev) Add parameter to quick_handler hook
+ * 20020329 (2.0.35-dev) bump for addition of freelists to bucket API
+ * 20020329.1 (2.0.36) minor bump for new arg to opt fn ap_cgi_build_command
+ * 20020506 (2.0.37-dev) Removed r->boundary in request_rec.
+ * 20020529 (2.0.37-dev) Standardized the names of some apr_pool_*_set funcs
+ * 20020602 (2.0.37-dev) Bucket API change (metadata buckets)
+ * 20020612 (2.0.38-dev) Changed server_rec->[keep_alive_]timeout to apr time
+ * 20020625 (2.0.40-dev) Changed conn_rec->keepalive to an enumeration
+ * 20020628 (2.0.40-dev) Added filter_init to filter registration functions
+ * 20020903 (2.0.41-dev) APR's error constants changed
+ * 20020903.1 (2.1.0-dev) allow_encoded_slashes added to core_dir_config
+ * 20020903.2 (2.0.46-dev) add ap_escape_logitem
+ * 20030213.1 (2.1.0-dev) changed log_writer optional fn's to return previous
+ * handler
+ * 20030821 (2.1.0-dev) bumped mod_include's entire API
+ * 20030821.1 (2.1.0-dev) added XHTML doctypes
+ * 20030821.2 (2.1.0-dev) added ap_escape_errorlog_item
+ * 20030821.3 (2.1.0-dev) added ap_get_server_revision / ap_version_t
+ * 20040425 (2.1.0-dev) removed ap_add_named_module API
+ * changed ap_add_module, ap_add_loaded_module,
+ * ap_setup_prelinked_modules,
+ * ap_process_resource_config
+ * 20040425.1 (2.1.0-dev) Added ap_module_symbol_t and
+ * ap_prelinked_module_symbols
+ * 20050101.0 (2.1.2-dev) Axed misnamed http_method for http_scheme
+ * (which it was!)
+ * 20050127.0 (2.1.3-dev) renamed regex_t->ap_regex_t,
+ * regmatch_t->ap_regmatch_t, REG_*->AP_REG_*,
+ * removed reg* in place of ap_reg*; added ap_regex.h
+ * 20050217.0 (2.1.3-dev) Axed find_child_by_pid, mpm_*_completion_context
+ * (winnt mpm) symbols from the public sector, and
+ * decorated real_exit_code with ap_ in the win32/os.h.
+ * 20050305.0 (2.1.4-dev) added pid and generation fields to worker_score
+ * 20050305.1 (2.1.5-dev) added ap_vhost_iterate_given_conn.
+ * 20050305.2 (2.1.5-dev) added AP_INIT_TAKE_ARGV.
+ * 20050305.3 (2.1.5-dev) added Protocol Framework.
+ * 20050701.0 (2.1.7-dev) Bump MODULE_MAGIC_COOKIE to "AP21"!
+ * 20050701.1 (2.1.7-dev) trace_enable member added to core server_config
+ * 20050708.0 (2.1.7-dev) Bump MODULE_MAGIC_COOKIE to "AP22"!
+ * 20050708.1 (2.1.7-dev) add proxy request_status hook (minor)
+ * 20050919.0 (2.1.8-dev) mod_ssl ssl_ext_list optional function added
+ * 20051005.0 (2.1.8-dev) NET_TIME filter eliminated
+ * 20051005.0 (2.3.0-dev) Bump MODULE_MAGIC_COOKIE to "AP24"!
+ * 20051115.0 (2.3.0-dev) Added use_canonical_phys_port to core_dir_config
+ * 20060110.0 (2.3.0-dev) Conversion of Authz to be provider based
+ * addition of <SatisfyAll><SatisfyOne>
+ * removal of Satisfy, Allow, Deny, Order
+ * 20060110.1 (2.3.0-dev) minex and minex_set members added to
+ * cache_server_conf (minor)
+ * 20060110.2 (2.3.0-dev) flush_packets and flush_wait members added to
+ * proxy_server (minor)
+ * 20060110.3 (2.3.0-dev) added inreslist member to proxy_conn_rec (minor)
+ * 20060110.4 (2.3.0-dev) Added server_scheme member to server_rec (minor)
+ * 20060905.0 (2.3.0-dev) Replaced ap_get_server_version() with
+ * ap_get_server_banner() and ap_get_server_description()
+ * 20060905.1 (2.3.0-dev) Enable retry=0 for the worker (minor)
+ * 20060905.2 (2.3.0-dev) Added ap_all_available_mutexes_string,
+ * ap_available_mutexes_string and
+ * ap_parse_mutex()
+ * 20060905.3 (2.3.0-dev) Added conn_rec::clogging_input_filters.
+ * 20060905.4 (2.3.0-dev) Added proxy_balancer::sticky_path.
+ * 20060905.5 (2.3.0-dev) Added ap_mpm_safe_kill()
+ * 20070823.0 (2.3.0-dev) Removed ap_all_available_mutexes_string,
+ * ap_available_mutexes_string for macros
+ * 20070823.1 (2.3.0-dev) add ap_send_interim_response()
+ * 20071023.0 (2.3.0-dev) add ap_get_scoreboard(sbh) split from the less
+ * conventional ap_get_scoreboard(proc, thread)
+ * 20071023.1 (2.3.0-dev) Add flags field to struct proxy_alias
+ * 20071023.2 (2.3.0-dev) Add ap_mod_status_reqtail
+ * 20071023.3 (2.3.0-dev) Declare ap_time_process_request() as part of the
+ * public scoreboard API.
+ * 20071108.1 (2.3.0-dev) Add the optional kept_body brigade to request_rec
+ * 20071108.2 (2.3.0-dev) Add st and keep fields to struct util_ldap_connection_t
+ * 20071108.3 (2.3.0-dev) Add API guarantee for adding connection filters
+ * with non-NULL request_rec pointer (ap_add_*_filter*)
+ * 20071108.4 (2.3.0-dev) Add ap_proxy_ssl_connection_cleanup
+ * 20071108.5 (2.3.0-dev) Add *scpool to proxy_conn_rec structure
+ * 20071108.6 (2.3.0-dev) Add *r and need_flush to proxy_conn_rec structure
+ * 20071108.7 (2.3.0-dev) Add *ftp_directory_charset to proxy_dir_conf
+ * 20071108.8 (2.3.0-dev) Add optional function ap_logio_add_bytes_in() to mog_logio
+ * 20071108.9 (2.3.0-dev) Add chroot support to unixd_config
+ * 20071108.10(2.3.0-dev) Introduce new ap_expr API
+ * 20071108.11(2.3.0-dev) Revise/Expand new ap_expr API
+ * 20071108.12(2.3.0-dev) Remove ap_expr_clone from the API (same day it was added)
+ * 20080403.0 (2.3.0-dev) Add condition field to core dir config
+ * 20080403.1 (2.3.0-dev) Add authn/z hook and provider registration wrappers.
+ * 20080403.2 (2.3.0-dev) Add ap_escape_path_segment_buffer() and ap_unescape_all().
+ * 20080407.0 (2.3.0-dev) Remove ap_graceful_stop_signalled.
+ * 20080407.1 Deprecate ap_cache_cacheable_hdrs_out and add two
+ * generalized ap_cache_cacheable_headers_(in|out).
+ * 20080528.0 (2.3.0-dev) Switch order of ftp_directory_charset and
+ * interpolate_env in proxy_dir_conf.
+ * Rationale: see r661069.
+ * 20080528.1 (2.3.0-dev) add has_realm_hash() to authn_provider struct
+ * 20080722.0 (2.3.0-dev) remove has_realm_hash() from authn_provider struct
+ * 20080722.1 (2.3.0-dev) Add conn_timeout and conn_timeout_set to
+ * proxy_worker struct.
+ * 20080722.2 (2.3.0-dev) Add scolonsep to proxy_balancer
+ * 20080829.0 (2.3.0-dev) Add cookie attributes when removing cookies
+ * 20080830.0 (2.3.0-dev) Cookies can be set on headers_out and err_headers_out
+ * 20080920.0 (2.3.0-dev) Add ap_mpm_register_timed_callback.
+ * 20080920.1 (2.3.0-dev) Export mod_rewrite.h in the public API.
+ * 20080920.2 (2.3.0-dev) Added ap_timeout_parameter_parse to util.c / httpd.h
+ * 20081101.0 (2.3.0-dev) Remove unused AUTHZ_GROUP_NOTE define.
+ * 20081102.0 (2.3.0-dev) Remove authz_provider_list, authz_request_state,
+ * and AUTHZ_ACCESS_PASSED_NOTE.
+ * 20081104.0 (2.3.0-dev) Remove r and need_flush fields from proxy_conn_rec
+ * as they are no longer used and add
+ * ap_proxy_buckets_lifetime_transform to mod_proxy.h
+ * 20081129.0 (2.3.0-dev) Move AP_FILTER_ERROR and AP_NOBODY_READ|WROTE
+ * from util_filter.h to httpd.h and change their
+ * numeric values so they do not overlap with other
+ * potential status codes
+ * 20081201.0 (2.3.0-dev) Rename several APIs to include ap_ prefix.
+ * 20081201.1 (2.3.0-dev) Added ap_args_to_table and ap_body_to_table.
+ * 20081212.0 (2.3.0-dev) Remove sb_type from process_score in scoreboard.h.
+ * 20081231.0 (2.3.0-dev) Switch ap_escape_html API: add ap_escape_html2,
+ * and make ap_escape_html a macro for it.
+ * 20090130.0 (2.3.2-dev) Add ap_ prefix to unixd_setup_child().
+ * 20090131.0 (2.3.2-dev) Remove ap_default_type(), disable DefaultType
+ * 20090208.0 (2.3.2-dev) Add conn_rec::current_thread.
+ * 20090208.1 (2.3.3-dev) Add ap_retained_data_create()/ap_retained_data_get()
+ * 20090401.0 (2.3.3-dev) Remove ap_threads_per_child, ap_max_daemons_limit,
+ * ap_my_generation, etc. ap_mpm_query() can't be called
+ * until after the register-hooks phase.
+ * 20090401.1 (2.3.3-dev) Protected log.c internals, http_log.h changes
+ * 20090401.2 (2.3.3-dev) Added tmp_flush_bb to core_output_filter_ctx_t
+ * 20090401.3 (2.3.3-dev) Added DAV options provider to mod_dav.h
+ * 20090925.0 (2.3.3-dev) Added server_rec::context and added *server_rec
+ * param to ap_wait_or_timeout()
+ * 20090925.1 (2.3.3-dev) Add optional function ap_logio_get_last_bytes() to
+ * mod_logio
+ * 20091011.0 (2.3.3-dev) Move preserve_host{,_set} from proxy_server_conf to
+ * proxy_dir_conf
+ * 20091011.1 (2.3.3-dev) add debug_level to util_ldap_state_t
+ * 20091031.0 (2.3.3-dev) remove public LDAP referral-related macros
+ * 20091119.0 (2.3.4-dev) dav_error interface uses apr_status_t parm, not errno
+ * 20091119.1 (2.3.4-dev) ap_mutex_register(), ap_{proc,global}_mutex_create()
+ * 20091229.0 (2.3.5-dev) Move allowed_connect_ports from proxy_server_conf
+ * to mod_proxy_connect
+ * 20091230.0 (2.3.5-dev) Move ftp_directory_charset from proxy_dir_conf
+ * to proxy_ftp_dir_conf(mod_proxy_ftp)
+ * 20091230.1 (2.3.5-dev) add util_ldap_state_t.opTimeout
+ * 20091230.2 (2.3.5-dev) add ap_get_server_name_for_url()
+ * 20091230.3 (2.3.6-dev) add ap_parse_log_level()
+ * 20091230.4 (2.3.6-dev) export ap_process_request_after_handler() for mod_serf
+ * 20100208.0 (2.3.6-dev) ap_socache_provider_t API changes to store and iterate
+ * 20100208.1 (2.3.6-dev) Added forward member to proxy_conn_rec
+ * 20100208.2 (2.3.6-dev) Added ap_log_command_line().
+ * 20100223.0 (2.3.6-dev) LDAP client_certs per-server moved to per-dir
+ * 20100223.1 (2.3.6-dev) Added ap_process_fnmatch_configs().
+ * 20100504.0 (2.3.6-dev) Added name arg to ap_{proc,global}_mutex_create().
+ * 20100604.0 (2.3.6-dev) Remove unused core_dir_config::loglevel
+ * 20100606.0 (2.3.6-dev) Make ap_log_*error macro wrappers around
+ * ap_log_*error_ to save argument preparation and
+ * function call overhead.
+ * Introduce per-module loglevels, including new APIs
+ * APLOG_USE_MODULE() and AP_DECLARE_MODULE().
+ * 20100606.1 (2.3.6-dev) Added extended timestamp formatting via
+ * ap_recent_ctime_ex().
+ * 20100609.0 (2.3.6-dev) Dropped ap_body_to_table due to missing constraints.
+ * 20100609.1 (2.3.7-dev) Introduce ap_log_cserror()
+ * 20100609.2 (2.3.7-dev) Add deferred write pool to core_output_filter_ctx
+ * 20100625.0 (2.3.7-dev) Add 'userctx' to socache iterator callback prototype
+ * 20100630.0 (2.3.7-dev) make module_levels vector of char instead of int
+ * 20100701.0 (2.3.7-dev) re-order struct members to improve alignment
+ * 20100701.1 (2.3.7-dev) add note_auth_failure hook
+ * 20100701.2 (2.3.7-dev) add ap_proxy_*_wid() functions
+ * 20100714.0 (2.3.7-dev) add access_checker_ex hook, add AUTHZ_DENIED_NO_USER
+ * to authz_status, call authz providers twice to allow
+ * authz without authenticated user
+ * 20100719.0 (2.3.7-dev) Add symbol name parameter to ap_add_module and
+ * ap_add_loaded_module. Add ap_find_module_short_name
+ * 20100723.0 (2.3.7-dev) Remove ct_output_filters from core rec
+ * 20100723.1 (2.3.7-dev) Added ap_proxy_hashfunc() and hash elements to
+ * proxy worker structs
+ * 20100723.2 (2.3.7-dev) Add ap_request_has_body()
+ * 20100723.3 (2.3.8-dev) Add ap_check_mpm()
+ * 20100905.0 (2.3.9-dev) Add log_id to conn and req recs. Add error log
+ * format handlers. Support AP_CTIME_OPTION_COMPACT in
+ * ap_recent_ctime_ex().
+ * 20100905.1 (2.3.9-dev) Add ap_cache_check_allowed()
+ * 20100912.0 (2.3.9-dev) Add an additional "out" brigade parameter to the
+ * mod_cache store_body() provider function.
+ * 20100916.0 (2.3.9-dev) Add commit_entity() to the mod_cache provider
+ * interface.
+ * 20100918.0 (2.3.9-dev) Move the request_rec within mod_include to be
+ * exposed within include_ctx_t.
+ * 20100919.0 (2.3.9-dev) Authz providers: Add parsed_require_line parameter
+ * to check_authorization() function. Add
+ * parse_require_line() function.
+ * 20100919.1 (2.3.9-dev) Introduce ap_rxplus util/API
+ * 20100921.0 (2.3.9-dev) Add an apr_bucket_brigade to the create_entity
+ * provider interface for mod_cache.h.
+ * 20100922.0 (2.3.9-dev) Move cache_* functions from mod_cache.h to a
+ * private header file.
+ * 20100923.0 (2.3.9-dev) Remove MOD_CACHE_REQUEST_REC, remove deprecated
+ * ap_cache_cacheable_hdrs_out, trim cache_object_t,
+ * make ap_cache_accept_headers, ap_cache_accept_headers
+ * ap_cache_try_lock, ap_cache_check_freshness,
+ * cache_server_conf, cache_enable, cache_disable,
+ * cache_request_rec and cache_provider_list private.
+ * 20100923.1 (2.3.9-dev) Add cache_status hook.
+ * 20100923.2 (2.3.9-dev) Add generate_log_id hook.
+ * Make root parameter of ap_expr_eval() const.
+ * 20100923.3 (2.3.9-dev) Add "last" member to ap_directive_t
+ * 20101012.0 (2.3.9-dev) Add header to cache_status hook.
+ * 20101016.0 (2.3.9-dev) Remove ap_cache_check_allowed().
+ * 20101017.0 (2.3.9-dev) Make ap_cache_control() public, add cache_control_t
+ * to mod_disk_cache format.
+ * 20101106.0 (2.3.9-dev) Replace the ap_expr parser derived from
+ * mod_include's parser with one derived from
+ * mod_ssl's parser. Clean up ap_expr's public
+ * interface.
+ * 20101106.1 (2.3.9-dev) Add ap_pool_cleanup_set_null() generic cleanup
+ * 20101106.2 (2.3.9-dev) Add suexec_disabled_reason field to ap_unixd_config
+ * 20101113.0 (2.3.9-dev) Add source address to mod_proxy.h
+ * 20101113.1 (2.3.9-dev) Add ap_set_flag_slot_char()
+ * 20101113.2 (2.3.9-dev) Add ap_expr_exec_re()
+ * 20101204.0 (2.3.10-dev) Add _t to ap_expr's typedef names
+ * 20101223.0 (2.3.11-dev) Remove cleaned from proxy_conn_rec.
+ * 20101223.1 (2.3.11-dev) Rework mod_proxy, et.al. Remove proxy_worker_stat
+ * and replace w/ proxy_worker_shared; remove worker
+ * info from scoreboard and use slotmem; Allow
+ * dynamic growth of balancer members; Remove
+ * BalancerNonce in favor of 'nonce' parameter.
+ * 20110117.0 (2.3.11-dev) Merge <If> sections in separate step (ap_if_walk).
+ * Add core_dir_config->sec_if. Add ap_add_if_conf().
+ * Add pool argument to ap_add_file_conf().
+ * 20110117.1 (2.3.11-dev) Add ap_pstr2_alnum() and ap_str2_alnum()
+ * 20110203.0 (2.3.11-dev) Raise DYNAMIC_MODULE_LIMIT to 256
+ * 20110203.1 (2.3.11-dev) Add ap_state_query()
+ * 20110203.2 (2.3.11-dev) Add ap_run_pre_read_request() hook and
+ * ap_parse_form_data() util
+ * 20110312.0 (2.3.12-dev) remove uldap_connection_cleanup and add
+ util_ldap_state_t.connectionPoolTTL,
+ util_ldap_connection_t.freed, and
+ util_ldap_connection_t.rebind_pool.
+ * 20110312.1 (2.3.12-dev) Add core_dir_config.decode_encoded_slashes.
+ * 20110328.0 (2.3.12-dev) change type and name of connectionPoolTTL in util_ldap_state_t
+ connectionPoolTTL (connection_pool_ttl, int->apr_interval_t)
+ * 20110329.0 (2.3.12-dev) Change single-bit signed fields to unsigned in
+ * proxy and cache interfaces.
+ * Change ap_configfile_t/ap_cfg_getline()/
+ * ap_cfg_getc() API, add ap_pcfg_strerror()
+ * Axe mpm_note_child_killed hook, change
+ * ap_reclaim_child_process and ap_recover_child_process
+ * interfaces.
+ * 20110329.1 (2.3.12-dev) Add ap_reserve_module_slots()/ap_reserve_module_slots_directive()
+ * change AP_CORE_DECLARE to AP_DECLARE: ap_create_request_config()
+ * change AP_DECLARE to AP_CORE_DECLARE: ap_register_log_hooks()
+ * 20110329.2 (2.3.12-dev) Add child_status and end_generation hooks.
+ * 20110329.3 (2.3.12-dev) Add format field to ap_errorlog_info.
+ * 20110329.4 (2.3.13-dev) bgrowth and max_balancers to proxy_server_conf.
+ * 20110329.5 (2.3.13-dev) Add ap_regexec_len()
+ * 20110329.6 (2.3.13-dev) Add AP_EXPR_FLAGS_RESTRICTED, ap_expr_eval_ctx_t->data,
+ * ap_expr_exec_ctx()
+ * 20110604.0 (2.3.13-dev) Make ap_rputs() inline
+ * 20110605.0 (2.3.13-dev) add core_dir_config->condition_ifelse, change return
+ * type of ap_add_if_conf().
+ * Add members of core_request_config: document_root,
+ * context_document_root, context_prefix.
+ * Add ap_context_*(), ap_set_context_info(), ap_set_document_root()
+ * 20110605.1 (2.3.13-dev) add ap_(get|set)_core_module_config()
+ * 20110605.2 (2.3.13-dev) add ap_get_conn_socket()
+ * 20110619.0 (2.3.13-dev) add async connection infos to process_score in scoreboard,
+ * add ap_start_lingering_close(),
+ * add conn_state_e:CONN_STATE_LINGER_NORMAL and CONN_STATE_LINGER_SHORT
+ * 20110619.1 (2.3.13-dev) add ap_str_toupper()
+ * 20110702.0 (2.3.14-dev) make ap_expr_parse_cmd() macro wrapper for new
+ * ap_expr_parse_cmd_mi() function, add ap_expr_str_*() functions,
+ * rename AP_EXPR_FLAGS_* -> AP_EXPR_FLAG_*
+ * 20110702.1 (2.3.14-dev) Add ap_scan_script_header_err*_ex functions
+ * 20110723.0 (2.3.14-dev) Revert addition of ap_ldap*
+ * 20110724.0 (2.3.14-dev) Add override_list as parameter to ap_parse_htaccess
+ * Add member override_list to cmd_parms_struct,
+ * core_dir_config and htaccess_result
+ * 20110724.1 (2.3.15-dev) add NOT_IN_HTACCESS
+ * 20110724.2 (2.3.15-dev) retries and retry_delay in util_ldap_state_t
+ * 20110724.3 (2.3.15-dev) add util_varbuf.h / ap_varbuf API
+ * 20110724.4 (2.3.15-dev) add max_ranges to core_dir_config
+ * 20110724.5 (2.3.15-dev) add ap_set_accept_ranges()
+ * 20110724.6 (2.3.15-dev) add max_overlaps and max_reversals to core_dir_config
+ * 20110724.7 (2.3.15-dev) add ap_random_insecure_bytes(), ap_random_pick()
+ * 20110724.8 (2.3.15-dev) add ap_abort_on_oom(), ap_malloc(), ap_calloc(),
+ * ap_realloc()
+ * 20110724.9 (2.3.15-dev) add ap_varbuf_pdup() and ap_varbuf_regsub()
+ * 20110724.10(2.3.15-dev) Export ap_max_mem_free
+ * 20111009.0 (2.3.15-dev) Remove ap_proxy_removestr(),
+ * add ap_unixd_config.group_name
+ * 20111014.0 (2.3.15-dev) Remove cookie_path_str and cookie_domain_str from
+ * proxy_dir_conf
+ * 20111025.0 (2.3.15-dev) Add return value and maxlen to ap_varbuf_regsub(),
+ * add ap_pregsub_ex()
+ * 20111025.1 (2.3.15-dev) Add ap_escape_urlencoded(), ap_escape_urlencoded_buffer()
+ * and ap_unescape_urlencoded().
+ * 20111025.2 (2.3.15-dev) Add ap_lua_ssl_val to mod_lua
+ * 20111025.3 (2.4.0-dev) Add reclvl to ap_expr_eval_ctx_t
+ * 20111122.0 (2.4.0-dev) Remove parts of conn_state_t that are private to the MPM
+ * 20111123.0 (2.4.0-dev) Pass ap_errorlog_info struct to error_log hook,
+ * add pool to ap_errorlog_info.
+ * 20111130.0 (2.4.0-dev) c->remote_ip becomes c->peer_ip and r->client_ip,
+ * c->remote_addr becomes c->peer_addr and r->client_addr
+ * 20111201.0 (2.4.0-dev) Add invalidate_entity() to the cache provider.
+ * 20111202.0 (2.4.0-dev) Use apr_status_t across mod_session API.
+ * 20111202.1 (2.4.0-dev) add APLOGNO()
+ * 20111203.0 (2.4.0-dev) Optional ap_proxy_retry_worker(), remove
+ * ap_proxy_string_read(), ap_cache_liststr(),
+ * ap_proxy_buckets_lifetime_transform(),
+ * ap_proxy_date_canon(), ap_proxy_is_ipaddr(),
+ * ap_proxy_is_domainname(), ap_proxy_is_hostname(),
+ * ap_proxy_is_word(), ap_proxy_hex2sec(),
+ * ap_proxy_sec2hex(), ap_proxy_make_fake_req(),
+ * ap_proxy_strmatch_path, ap_proxy_strmatch_domain,
+ * ap_proxy_table_unmerge(), proxy_lb_workers.
+ * 20120109.0 (2.4.1-dev) Changes sizeof(overrides_t) in core config.
+ * 20120109.1 (2.4.1-dev) remove sb_type in global_score.
+ * 20120109.2 (2.4.1-dev) Make core_output_filter_ctx_t and core_ctx_t
+ * private;
+ * move core_net rec definition to http_core.h;
+ * add insert_network_bucket hook, AP_DECLINED
+ * 20120211.0 (2.4.1-dev) Change re_nsub in ap_regex_t from apr_size_t to int.
+ * 20120211.1 (2.4.2-dev) Add AP_HAVE_C99
+ * 20120211.2 (2.4.2-dev) Add ap_runtime_dir_relative
+ * 20120211.3 (2.4.2-dev) Add forcerecovery to proxy_balancer_shared struct
+ * 20120211.4 (2.4.3-dev) Add ap_list_provider_groups()
+ * 20120211.5 (2.4.3-dev) Add missing HTTP status codes registered with IANA.
+ * 20120211.6 (2.4.3-dev) Add ap_proxy_checkproxyblock2.
+ * 20120211.7 (2.4.3-dev) Add ap_get_loadavg()
+ * 20120211.8 (2.4.3-dev) Add sticky_separator to proxy_balancer_shared struct.
+ * 20120211.9 (2.4.4-dev) Add fgrab() to ap_slotmem_provider_t.
+ * 20120211.10 (2.4.4-dev) Add in bal_persist field to proxy_server_conf
+ * 20120211.11 (2.4.4-dev) Add ap_bin2hex()
+ * 20120211.12 (2.4.5-dev) Add ap_remove_input|output_filter_byhandle()
+ * 20120211.13 (2.4.5-dev) Add ap_get_exec_line
+ * 20120211.14 (2.4.5-dev) Add ppinherit and inherit to proxy_server_conf
+ * 20120211.15 (2.4.5-dev) Add dav_join_error()
+ * 20120211.16 (2.4.5-dev) Add cache_control_t.invalidated
+ * 20120211.17 (2.4.5-dev) Add ap_find_etag_weak(), ap_find_etag_strong()
+ * 20120211.18 (2.4.5-dev) Add ap_condition_e, ap_condition_if_match(),
+ * ap_condition_if_unmodified_since(),
+ * ap_condition_if_none_match(),
+ * ap_condition_if_modified_since(),
+ * ap_condition_if_range()
+ * 20120211.19 (2.4.5-dev) Add post_perdir_config hook.
+ * 20120211.20 (2.4.5-dev) Add dirwalk_stat hook.
+ * 20120211.21 (2.4.5-dev) Add in ap_proxy_create_hdrbrgd() and
+ * ap_proxy_pass_brigade()
+ * 20120211.22 (2.4.5-dev) No longer prevent usage of strtoul()
+ * 20120211.23 (2.4.5-dev) Add ap_proxy_clear_connection()
+ * 20120211.24 (2.4.7-dev) add open_htaccess hook.
+ * 20120211.25 (2.4.7-dev) Add conn_sense_e
+ * 20120211.26 (2.4.7-dev) Add util_fcgi.h, FastCGI protocol support
+ * 20120211.27 (2.4.7-dev) Add ap_podx_restart_t and ap_mpm_podx_*
+ * 20120211.28 (2.4.7-dev) Add ap_regname
+ * 20120211.29 (2.4.7-dev) Add uds_path to proxy_conn_rec and proxy_worker_shared.
+ * The change to proxy_worker_shared is an
+ * unintended API break, especially for balancer
+ * lbmethod modules.
+ * 20120211.30 (2.4.7-dev) REWRITE_REDIRECT_HANDLER_NAME in mod_rewrite.h
+ * 20120211.31 (2.4.7-dev) Add ap_proxy_port_of_scheme()
+ * 20120211.32 (2.4.10-dev) Add SSL reusable SNI to mod_proxy.h's proxy_conn_rec
+ * 20120211.33 (2.4.10-dev) Add suspend_connection and resume_connection hooks
+ * 20120211.34 (2.4.10-dev) AP_DEFAULT_HANDLER_NAME/AP_IS_DEFAULT_HANDLER_NAME
+ * 20120211.35 (2.4.10-dev) Add "r", "must_rebind", and last_backend_conn
+ to util_ldap_connection_t
+ * 20120211.36 (2.4.10-dev) Add ap_copy_scoreboard_worker()
+ * 20120211.37 (2.4.11-dev) Add r->trailers_{in,out}
+ * 20120211.38 (2.4.11-dev) Added ap_shutdown_conn().
+ * 20120211.39 (2.4.11-dev) Add ap_proxy_connect_uds().
+ * 20120211.40 (2.4.11-dev) Add ap_log_data(), ap_log_rdata(), etc.
+ * 20120211.41 (2.4.11-dev) Add ap_proxy_de_socketfy to mod_proxy.h
+ * 20120211.42 (2.4.13-dev) Add response_code_exprs to http_core.h
+ * 20120211.43 (2.4.13-dev) Add keep_alive_timeout_set to server_rec
+ * 20120211.44 (2.4.13-dev) Add cgi_pass_auth and AP_CGI_PASS_AUTH_* to
+ * core_dir_config
+ * 20120211.45 (2.4.13-dev) Add ap_proxy_connection_reusable()
+ * 20120211.46 (2.4.13-dev) Add ap_map_http_request_error()
+ * 20120211.47 (2.4.13-dev) Add ap_some_authn_required, ap_force_authn hook.
+ * Deprecate broken ap_some_auth_required.
+ * 20120211.48 (2.4.17-dev) Added ap_log_mpm_common().
+ * 20120211.49 (2.4.17-dev) Add listener bucket in scoreboard.h's process_score.
+ * 20120211.50 (2.4.17-dev) Add ap_set_listencbratio(), ap_close_listeners_ex(),
+ * ap_duplicate_listeners(), ap_num_listen_buckets and
+ * ap_have_so_reuseport to ap_listen.h.
+ * 20120211.51 (2.4.17-dev) Add protocols and protocols_honor_order to
+ * core_server_config. Add hooks protocol_propose
+ * protocol_switch and protocol_get. Add
+ * ap_select_protocol(), ap_switch_protocol(),
+ * ap_get_protocol(). Add HTTP_MISDIRECTED_REQUEST.
+ * Added ap_parse_token_list_strict() to httpd.h
+ * 20120211.52 (2.4.17-dev) Add master conn_rec* member in conn_rec.
+ * 20120211.53 (2.4.19-dev) Add expr_handler to core_dir_config.
+ * 20120211.54 (2.4.19-dev) Add ap_proxy_buckets_lifetime_transform and
+ * ap_proxy_transfer_between_connections to
+ * mod_proxy.h
+ * 20120211.55 (2.4.19-dev) Add new ap_update_child_status...() methods,
+ * add protocol to worker_score in scoreboard.h,
+ * Add pre_close connection hook and
+ * ap_prep_lingering_close().
+ * 20120211.56 (2.4.19-dev) Split useragent_host from the conn_rec into
+ * the request_rec, with ap_get_useragent_host()
+ * 20120211.57 (2.4.19-dev) Add mod_ssl_openssl.h and OpenSSL-specific hooks
+ * 20120211.58 (2.4.21-dev) Add cgi_var_rules to core_dir_config.
+ * 20120211.59 (2.4.21-dev) Add ap_getword_conf2[_nc](),
+ * ap_proxy_is_socket_connected() and
+ * extended proxy_worker_shared.
+ * 20120211.60 (2.4.21-dev) Add dav_get_provider_name.
+ * 20120211.61 (2.4.21-dev) Add ap_cstr_casecmp[n]() - placeholder of apr_ fns
+ * 20120211.62 (2.4.24-dev) Add childtags to dav_error.
+ * 20120211.63 (2.4.24-dev) Add dav_begin_multistatus, dav_send_one_response,
+ * dav_finish_multistatus, dav_send_multistatus,
+ * dav_handle_err, dav_failed_proppatch,
+ * dav_success_proppatch.
+ * 20120211.64 (2.4.24-dev) Add ap_proxy_check_backend(), and tmp_bb to struct
+ * proxy_conn_rec.
+ * 20120211.65 (2.4.24-dev) Add ap_check_pipeline().
+ * 20120211.66 (2.4.24-dev) Rename ap_proxy_check_backend() to
+ * ap_proxy_check_connection().
+ * 20120211.67 (2.4.24-dev) Add http09_enable, http_conformance, and
+ * http_methods to core_server_config
+ * Add ap_scan_http_field_token(),
+ * ap_scan_http_field_content(),
+ * and ap_scan_vchar_obstext()
+ * Replaced fold boolean with with multiple bit flags
+ * to ap_[r]getline()
+ * 20120211.68 (2.4.26-dev) Add ap_get_basic_auth_components() and deprecate
+ * ap_get_basic_auth_pw()
+ * 20120211.69 (2.4.30-dev) Add ap_update_sb_handle()
+ * 20120211.70 (2.4.30-dev) Add flags field to module_struct and function
+ * ap_get_module_flags()
+ * 20120211.71 (2.4.30-dev) Add optional proxy_{hook,run}_section_post_config(),
+ * ap_proxy_connection_create_ex() and section_config
+ * to struct proxy_{worker,balancer} in mod_proxy.h,
+ * and optional ssl_engine_set() to mod_ssl.h.
+ * 20120211.72 (2.4.30-dev) Add NOT_IN_DIR_CONTEXT replacing NOT_IN_DIR_LOC_FILE
+ * semantics
+ * 20120211.73 (2.4.30-dev) Add failontimeout_set, growth_set and lbmethod_set
+ * to proxy_balancer struct
+ * 20120211.74 (2.4.30-dev) Add AP_REG_DOLLAR_ENDONLY, ap_regcomp_get_default_cflags
+ * ap_regcomp_set_default_cflags and
+ * ap_regcomp_default_cflag_by_name
+ * 20120211.75 (2.4.30-dev) Add hostname_ex to proxy_worker_shared
+ * 20120211.76 (2.4.30-dev) Add CONN_STATE_NUM to enum conn_state_e
+ * 20120211.77 (2.4.34-dev) Add ap_exists_directive()
+ * 20120211.78 (2.4.34-dev) Add response_field_size to proxy_worker_shared
+ * 20120211.79 (2.4.34-dev) Add AP_GETLINE_NOSPC_EOL flag to http_protocol.h
+ * 20120211.80 (2.4.35-dev) Add new ap_update_global_status() method and
+ * times field in the global_score structure in
+ * scoreboard.h.
+ * 20120211.81 (2.4.35-dev) Add new duration field to worker_score struct in
+ * scoreboard.h
+ * 20120211.82 (2.4.35-dev) Add optional function declaration for
+ * ap_proxy_balancer_get_best_worker to mod_proxy.h.
+ * 20120211.83 (2.4.35-dev) Add client64 field to worker_score struct
+ *
+ */
+
+#define MODULE_MAGIC_COOKIE 0x41503234UL /* "AP24" */
+
+#ifndef MODULE_MAGIC_NUMBER_MAJOR
+#define MODULE_MAGIC_NUMBER_MAJOR 20120211
+#endif
+#define MODULE_MAGIC_NUMBER_MINOR 83 /* 0...n */
+
+/**
+ * Determine if the server's current MODULE_MAGIC_NUMBER is at least a
+ * specified value.
+ *
+ * Useful for testing for features.
+ * For example, suppose you wish to use the apr_table_overlap
+ * function. You can do this:
+ *
+ * \code
+ * #if AP_MODULE_MAGIC_AT_LEAST(19980812,2)
+ * ... use apr_table_overlap()
+ * #else
+ * ... alternative code which doesn't use apr_table_overlap()
+ * #endif
+ * \endcode
+ *
+ * @param major The major module magic number
+ * @param minor The minor module magic number
+ * @def AP_MODULE_MAGIC_AT_LEAST(int major, int minor)
+ */
+#define AP_MODULE_MAGIC_AT_LEAST(major,minor) \
+ ((major) < MODULE_MAGIC_NUMBER_MAJOR \
+ || ((major) == MODULE_MAGIC_NUMBER_MAJOR \
+ && (minor) <= MODULE_MAGIC_NUMBER_MINOR))
+
+/** @deprecated present for backwards compatibility */
+#define MODULE_MAGIC_NUMBER MODULE_MAGIC_NUMBER_MAJOR
+#define MODULE_MAGIC_AT_LEAST old_broken_macro_we_hope_you_are_not_using
+
+#endif /* !APACHE_AP_MMN_H */
+/** @} */
diff --git a/include/ap_mpm.h b/include/ap_mpm.h
new file mode 100644
index 0000000..71f8f47
--- /dev/null
+++ b/include/ap_mpm.h
@@ -0,0 +1,235 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file ap_mpm.h
+ * @brief Apache Multi-Processing Module library
+ *
+ * @defgroup APACHE_CORE_MPM Multi-Processing Module library
+ * @ingroup APACHE_CORE
+ * @{
+ */
+
+#ifndef AP_MPM_H
+#define AP_MPM_H
+
+#include "apr_thread_proc.h"
+#include "httpd.h"
+#include "scoreboard.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ The MPM, "multi-processing model" provides an abstraction of the
+ interface with the OS for distributing incoming connections to
+ threads/process for processing. http_main invokes the MPM, and
+ the MPM runs until a shutdown/restart has been indicated.
+ The MPM calls out to the apache core via the ap_process_connection
+ function when a connection arrives.
+
+ The MPM may or may not be multithreaded. In the event that it is
+ multithreaded, at any instant it guarantees a 1:1 mapping of threads
+ ap_process_connection invocations.
+
+ Note: In the future it will be possible for ap_process_connection
+ to return to the MPM prior to finishing the entire connection; and
+ the MPM will proceed with asynchronous handling for the connection;
+ in the future the MPM may call ap_process_connection again -- but
+ does not guarantee it will occur on the same thread as the first call.
+
+ The MPM further guarantees that no asynchronous behaviour such as
+ longjmps and signals will interfere with the user code that is
+ invoked through ap_process_connection. The MPM may reserve some
+ signals for its use (i.e. SIGUSR1), but guarantees that these signals
+ are ignored when executing outside the MPM code itself. (This
+ allows broken user code that does not handle EINTR to function
+ properly.)
+
+ The suggested server restart and stop behaviour will be "graceful".
+ However the MPM may choose to terminate processes when the user
+ requests a non-graceful restart/stop. When this occurs, the MPM kills
+ all threads with extreme prejudice, and destroys the pchild pool.
+ User cleanups registered in the pchild apr_pool_t will be invoked at
+ this point. (This can pose some complications, the user cleanups
+ are asynchronous behaviour not unlike longjmp/signal... but if the
+ admin is asking for a non-graceful shutdown, how much effort should
+ we put into doing it in a nice way?)
+
+ unix/posix notes:
+ - The MPM does not set a SIGALRM handler, user code may use SIGALRM.
+ But the preferred method of handling timeouts is to use the
+ timeouts provided by the BUFF abstraction.
+ - The proper setting for SIGPIPE is SIG_IGN, if user code changes it
+ for any of their own processing, it must be restored to SIG_IGN
+ prior to executing or returning to any apache code.
+ TODO: add SIGPIPE debugging check somewhere to make sure it's SIG_IGN
+*/
+
+/**
+ * Pass control to the MPM for steady-state processing. It is responsible
+ * for controlling the parent and child processes. It will run until a
+ * restart/shutdown is indicated.
+ * @param pconf the configuration pool, reset before the config file is read
+ * @param plog the log pool, reset after the config file is read
+ * @param server_conf the global server config.
+ * @return DONE for shutdown OK otherwise.
+ */
+AP_DECLARE_HOOK(int, mpm, (apr_pool_t *pconf, apr_pool_t *plog, server_rec *server_conf))
+
+/**
+ * Spawn a process with privileges that another module has requested
+ * @param r The request_rec of the current request
+ * @param newproc The resulting process handle.
+ * @param progname The program to run
+ * @param args the arguments to pass to the new program. The first
+ * one should be the program name.
+ * @param env The new environment apr_table_t for the new process. This
+ * should be a list of NULL-terminated strings.
+ * @param attr the procattr we should use to determine how to create the new
+ * process
+ * @param p The pool to use.
+ */
+AP_DECLARE(apr_status_t) ap_os_create_privileged_process(
+ const request_rec *r,
+ apr_proc_t *newproc,
+ const char *progname,
+ const char * const *args,
+ const char * const *env,
+ apr_procattr_t *attr,
+ apr_pool_t *p);
+
+/* Subtypes/Values for AP_MPMQ_IS_THREADED and AP_MPMQ_IS_FORKED */
+#define AP_MPMQ_NOT_SUPPORTED 0 /* This value specifies that an */
+ /* MPM is not capable of */
+ /* threading or forking. */
+#define AP_MPMQ_STATIC 1 /* This value specifies that */
+ /* an MPM is using a static */
+ /* number of threads or daemons */
+#define AP_MPMQ_DYNAMIC 2 /* This value specifies that */
+ /* an MPM is using a dynamic */
+ /* number of threads or daemons */
+
+/* Values returned for AP_MPMQ_MPM_STATE */
+#define AP_MPMQ_STARTING 0
+#define AP_MPMQ_RUNNING 1
+#define AP_MPMQ_STOPPING 2
+
+#define AP_MPMQ_MAX_DAEMON_USED 1 /* Max # of daemons used so far */
+#define AP_MPMQ_IS_THREADED 2 /* MPM can do threading */
+#define AP_MPMQ_IS_FORKED 3 /* MPM can do forking */
+#define AP_MPMQ_HARD_LIMIT_DAEMONS 4 /* The compiled max # daemons */
+#define AP_MPMQ_HARD_LIMIT_THREADS 5 /* The compiled max # threads */
+#define AP_MPMQ_MAX_THREADS 6 /* # of threads/child by config */
+#define AP_MPMQ_MIN_SPARE_DAEMONS 7 /* Min # of spare daemons */
+#define AP_MPMQ_MIN_SPARE_THREADS 8 /* Min # of spare threads */
+#define AP_MPMQ_MAX_SPARE_DAEMONS 9 /* Max # of spare daemons */
+#define AP_MPMQ_MAX_SPARE_THREADS 10 /* Max # of spare threads */
+#define AP_MPMQ_MAX_REQUESTS_DAEMON 11 /* Max # of requests per daemon */
+#define AP_MPMQ_MAX_DAEMONS 12 /* Max # of daemons by config */
+#define AP_MPMQ_MPM_STATE 13 /* starting, running, stopping */
+#define AP_MPMQ_IS_ASYNC 14 /* MPM can process async connections */
+#define AP_MPMQ_GENERATION 15 /* MPM generation */
+#define AP_MPMQ_HAS_SERF 16 /* MPM can drive serf internally */
+
+/**
+ * Query a property of the current MPM.
+ * @param query_code One of APM_MPMQ_*
+ * @param result A location to place the result of the query
+ * @return APR_EGENERAL if an mpm-query hook has not been registered;
+ * APR_SUCCESS or APR_ENOTIMPL otherwise
+ * @remark The MPM doesn't register the implementing hook until the
+ * register_hooks hook is called, so modules cannot use ap_mpm_query()
+ * until after that point.
+ * @fn int ap_mpm_query(int query_code, int *result)
+ */
+AP_DECLARE(apr_status_t) ap_mpm_query(int query_code, int *result);
+
+
+typedef void (ap_mpm_callback_fn_t)(void *baton);
+
+/* only added support in the Event MPM.... check for APR_ENOTIMPL */
+AP_DECLARE(apr_status_t) ap_mpm_register_timed_callback(apr_time_t t,
+ ap_mpm_callback_fn_t *cbfn,
+ void *baton);
+
+typedef enum mpm_child_status {
+ MPM_CHILD_STARTED,
+ MPM_CHILD_EXITED,
+ MPM_CHILD_LOST_SLOT
+} mpm_child_status;
+
+/**
+ * Allow a module to remain aware of MPM child process state changes,
+ * along with the generation and scoreboard slot of the process changing
+ * state.
+ *
+ * With some MPMs (event and worker), an active MPM child process may lose
+ * its scoreboard slot if the child process is exiting and the scoreboard
+ * slot is needed by other processes. When this occurs, the hook will be
+ * called with the MPM_CHILD_LOST_SLOT state.
+ *
+ * @param s The main server_rec.
+ * @param pid The id of the MPM child process.
+ * @param gen The server generation of that child process.
+ * @param slot The scoreboard slot number, or -1. It will be -1 when an
+ * MPM child process exits, and that child had previously lost its
+ * scoreboard slot.
+ * @param state One of the mpm_child_status values. Modules should ignore
+ * unrecognized values.
+ */
+AP_DECLARE_HOOK(void,child_status,(server_rec *s, pid_t pid, ap_generation_t gen,
+ int slot, mpm_child_status state))
+
+/**
+ * Allow a module to be notified when the last child process of a generation
+ * exits.
+ *
+ * @param s The main server_rec.
+ * @param gen The server generation which is now completely finished.
+ */
+AP_DECLARE_HOOK(void,end_generation,(server_rec *s, ap_generation_t gen))
+
+/* Defining GPROF when compiling uses the moncontrol() function to
+ * disable gprof profiling in the parent, and enable it only for
+ * request processing in children (or in one_process mode). It's
+ * absolutely required to get useful gprof results under linux
+ * because the profile itimers and such are disabled across a
+ * fork(). It's probably useful elsewhere as well.
+ */
+#ifdef GPROF
+extern void moncontrol(int);
+#define AP_MONCONTROL(x) moncontrol(x)
+#else
+#define AP_MONCONTROL(x)
+#endif
+
+#ifdef AP_ENABLE_EXCEPTION_HOOK
+typedef struct ap_exception_info_t {
+ int sig;
+ pid_t pid;
+} ap_exception_info_t;
+
+AP_DECLARE_HOOK(int,fatal_exception,(ap_exception_info_t *ei))
+#endif /*AP_ENABLE_EXCEPTION_HOOK*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/** @} */
diff --git a/include/ap_provider.h b/include/ap_provider.h
new file mode 100644
index 0000000..0a6c10c
--- /dev/null
+++ b/include/ap_provider.h
@@ -0,0 +1,100 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file ap_provider.h
+ * @brief Apache Provider API
+ *
+ * @defgroup APACHE_CORE_PROVIDER Provider API
+ * @ingroup APACHE_CORE
+ * @{
+ */
+
+#ifndef AP_PROVIDER_H
+#define AP_PROVIDER_H
+
+#include "ap_config.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+ const char *provider_name;
+} ap_list_provider_names_t;
+
+typedef struct {
+ const char *provider_group;
+ const char *provider_version;
+} ap_list_provider_groups_t;
+
+/**
+ * This function is used to register a provider with the global
+ * provider pool.
+ * @param pool The pool to create any storage from
+ * @param provider_group The group to store the provider in
+ * @param provider_name The name for this provider
+ * @param provider_version The version for this provider
+ * @param provider Opaque structure for this provider
+ * @return APR_SUCCESS if all went well
+ */
+AP_DECLARE(apr_status_t) ap_register_provider(apr_pool_t *pool,
+ const char *provider_group,
+ const char *provider_name,
+ const char *provider_version,
+ const void *provider);
+
+/**
+ * This function is used to retrieve a provider from the global
+ * provider pool.
+ * @param provider_group The group to look for this provider in
+ * @param provider_name The name for the provider
+ * @param provider_version The version for the provider
+ * @return provider pointer to provider if found, NULL otherwise
+ */
+AP_DECLARE(void *) ap_lookup_provider(const char *provider_group,
+ const char *provider_name,
+ const char *provider_version);
+
+/**
+ * This function is used to retrieve a list (array) of provider
+ * names from the specified group with the specified version.
+ * @param pool The pool to create any storage from
+ * @param provider_group The group to look for this provider in
+ * @param provider_version The version for the provider
+ * @return pointer to array of ap_list_provider_names_t of provider names (could be empty)
+ */
+
+AP_DECLARE(apr_array_header_t *) ap_list_provider_names(apr_pool_t *pool,
+ const char *provider_group,
+ const char *provider_version);
+
+/**
+ * This function is used to retrieve a list (array) of provider groups and versions
+ * @param pool The pool to create any storage from
+ * @return pointer to array of ap_list_provider_groups_t of provider groups
+ * and versions (could be empty)
+ */
+
+AP_DECLARE(apr_array_header_t *) ap_list_provider_groups(apr_pool_t *pool);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/** @} */
diff --git a/include/ap_regex.h b/include/ap_regex.h
new file mode 100644
index 0000000..7d8df79
--- /dev/null
+++ b/include/ap_regex.h
@@ -0,0 +1,275 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* This code is based on pcreposix.h from the PCRE Library distribution,
+ * as originally written by Philip Hazel <ph10@cam.ac.uk>, and forked by
+ * the Apache HTTP Server project to provide POSIX-style regex function
+ * wrappers around underlying PCRE library functions for httpd.
+ *
+ * The original source file pcreposix.h is copyright and licensed as follows;
+
+ Copyright (c) 1997-2004 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+/**
+ * @file ap_regex.h
+ * @brief Apache Regex defines
+ */
+
+#ifndef AP_REGEX_H
+#define AP_REGEX_H
+
+#include "apr.h"
+
+/* Allow for C++ users */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Options for ap_regcomp, ap_regexec, and ap_rxplus versions: */
+
+#define AP_REG_ICASE 0x01 /** use a case-insensitive match */
+#define AP_REG_NEWLINE 0x02 /** don't match newlines against '.' etc */
+#define AP_REG_NOTBOL 0x04 /** ^ will not match against start-of-string */
+#define AP_REG_NOTEOL 0x08 /** $ will not match against end-of-string */
+
+#define AP_REG_EXTENDED (0) /** unused */
+#define AP_REG_NOSUB (0) /** unused */
+
+#define AP_REG_MULTI 0x10 /* perl's /g (needs fixing) */
+#define AP_REG_NOMEM 0x20 /* nomem in our code */
+#define AP_REG_DOTALL 0x40 /* perl's /s flag */
+
+#define AP_REG_DOLLAR_ENDONLY 0x200 /* '$' matches at end of subject string only */
+
+#define AP_REG_MATCH "MATCH_" /** suggested prefix for ap_regname */
+
+/* Error values: */
+enum {
+ AP_REG_ASSERT = 1, /** internal error ? */
+ AP_REG_ESPACE, /** failed to get memory */
+ AP_REG_INVARG, /** invalid argument */
+ AP_REG_NOMATCH /** match failed */
+};
+
+/* The structure representing a compiled regular expression. */
+typedef struct {
+ void *re_pcre;
+ int re_nsub;
+ apr_size_t re_erroffset;
+} ap_regex_t;
+
+/* The structure in which a captured offset is returned. */
+typedef struct {
+ int rm_so;
+ int rm_eo;
+} ap_regmatch_t;
+
+/* The functions */
+
+/**
+ * Get default compile flags
+ * @return Bitwise OR of AP_REG_* flags
+ */
+AP_DECLARE(int) ap_regcomp_get_default_cflags(void);
+
+/**
+ * Set default compile flags
+ * @param cflags Bitwise OR of AP_REG_* flags
+ */
+AP_DECLARE(void) ap_regcomp_set_default_cflags(int cflags);
+
+/**
+ * Get the AP_REG_* corresponding to the string.
+ * @param name The name (i.e. AP_REG_<name>)
+ * @return The AP_REG_*, or zero if the string is unknown
+ *
+ */
+AP_DECLARE(int) ap_regcomp_default_cflag_by_name(const char *name);
+
+/**
+ * Compile a regular expression.
+ * @param preg Returned compiled regex
+ * @param regex The regular expression string
+ * @param cflags Bitwise OR of AP_REG_* flags (ICASE and NEWLINE supported,
+ * other flags are ignored)
+ * @return Zero on success or non-zero on error
+ */
+AP_DECLARE(int) ap_regcomp(ap_regex_t *preg, const char *regex, int cflags);
+
+/**
+ * Match a NUL-terminated string against a pre-compiled regex.
+ * @param preg The pre-compiled regex
+ * @param string The string to match
+ * @param nmatch Provide information regarding the location of any matches
+ * @param pmatch Provide information regarding the location of any matches
+ * @param eflags Bitwise OR of AP_REG_* flags (NOTBOL and NOTEOL supported,
+ * other flags are ignored)
+ * @return 0 for successful match, \p AP_REG_NOMATCH otherwise
+ */
+AP_DECLARE(int) ap_regexec(const ap_regex_t *preg, const char *string,
+ apr_size_t nmatch, ap_regmatch_t *pmatch, int eflags);
+
+/**
+ * Match a string with given length against a pre-compiled regex. The string
+ * does not need to be NUL-terminated.
+ * @param preg The pre-compiled regex
+ * @param buff The string to match
+ * @param len Length of the string to match
+ * @param nmatch Provide information regarding the location of any matches
+ * @param pmatch Provide information regarding the location of any matches
+ * @param eflags Bitwise OR of AP_REG_* flags (NOTBOL and NOTEOL supported,
+ * other flags are ignored)
+ * @return 0 for successful match, AP_REG_NOMATCH otherwise
+ */
+AP_DECLARE(int) ap_regexec_len(const ap_regex_t *preg, const char *buff,
+ apr_size_t len, apr_size_t nmatch,
+ ap_regmatch_t *pmatch, int eflags);
+
+/**
+ * Return the error code returned by regcomp or regexec into error messages
+ * @param errcode the error code returned by regexec or regcomp
+ * @param preg The precompiled regex
+ * @param errbuf A buffer to store the error in
+ * @param errbuf_size The size of the buffer
+ */
+AP_DECLARE(apr_size_t) ap_regerror(int errcode, const ap_regex_t *preg,
+ char *errbuf, apr_size_t errbuf_size);
+
+/**
+ * Return an array of named regex backreferences
+ * @param preg The precompiled regex
+ * @param names The array to which the names will be added
+ * @param upper If non zero, uppercase the names
+ */
+AP_DECLARE(int) ap_regname(const ap_regex_t *preg,
+ apr_array_header_t *names, const char *prefix,
+ int upper);
+
+/** Destroy a pre-compiled regex.
+ * @param preg The pre-compiled regex to free.
+ */
+AP_DECLARE(void) ap_regfree(ap_regex_t *preg);
+
+/* ap_rxplus: higher-level regexps */
+
+typedef struct {
+ ap_regex_t rx;
+ apr_uint32_t flags;
+ const char *subs;
+ const char *match;
+ apr_size_t nmatch;
+ ap_regmatch_t *pmatch;
+} ap_rxplus_t;
+
+/**
+ * Compile a pattern into a regexp.
+ * supports perl-like formats
+ * match-string
+ * /match-string/flags
+ * s/match-string/replacement-string/flags
+ * Intended to support more perl-like stuff as and when round tuits happen
+ * match-string is anything supported by ap_regcomp
+ * replacement-string is a substitution string as supported in ap_pregsub
+ * flags should correspond with perl syntax: treat failure to do so as a bug
+ * (documentation TBD)
+ * @param pool Pool to allocate from
+ * @param pattern Pattern to compile
+ * @return Compiled regexp, or NULL in case of compile/syntax error
+ */
+AP_DECLARE(ap_rxplus_t*) ap_rxplus_compile(apr_pool_t *pool, const char *pattern);
+/**
+ * Apply a regexp operation to a string.
+ * @param pool Pool to allocate from
+ * @param rx The regex match to apply
+ * @param pattern The string to apply it to
+ * NOTE: This MUST be kept in scope to use regexp memory
+ * @param newpattern The modified string (ignored if the operation doesn't
+ * modify the string)
+ * @return Number of times a match happens. Normally 0 (no match) or 1
+ * (match found), but may be greater if a transforming pattern
+ * is applied with the 'g' flag.
+ */
+AP_DECLARE(int) ap_rxplus_exec(apr_pool_t *pool, ap_rxplus_t *rx,
+ const char *pattern, char **newpattern);
+#ifdef DOXYGEN
+/**
+ * Number of matches in the regexp operation's memory
+ * This may be 0 if no match is in memory, or up to nmatch from compilation
+ * @param rx The regexp
+ * @return Number of matches in memory
+ */
+AP_DECLARE(int) ap_rxplus_nmatch(ap_rxplus_t *rx);
+#else
+#define ap_rxplus_nmatch(rx) (((rx)->match != NULL) ? (rx)->nmatch : 0)
+#endif
+/**
+ * Get a pointer to a match from regex memory
+ * NOTE: this relies on the match pattern from the last call to
+ * ap_rxplus_exec still being valid (i.e. not freed or out-of-scope)
+ * @param rx The regexp
+ * @param n The match number to retrieve (must be between 0 and nmatch)
+ * @param len Returns the length of the match.
+ * @param match Returns the match pattern
+ */
+AP_DECLARE(void) ap_rxplus_match(ap_rxplus_t *rx, int n, int *len,
+ const char **match);
+/**
+ * Get a match from regex memory in a string copy
+ * NOTE: this relies on the match pattern from the last call to
+ * ap_rxplus_exec still being valid (i.e. not freed or out-of-scope)
+ * @param pool Pool to allocate from
+ * @param rx The regexp
+ * @param n The match number to retrieve (must be between 0 and nmatch)
+ * @return The matched string
+ */
+AP_DECLARE(char*) ap_rxplus_pmatch(apr_pool_t *pool, ap_rxplus_t *rx, int n);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* AP_REGEX_T */
+
diff --git a/include/ap_regkey.h b/include/ap_regkey.h
new file mode 100644
index 0000000..f488c58
--- /dev/null
+++ b/include/ap_regkey.h
@@ -0,0 +1,219 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file ap_regkey.h
+ * @brief APR-style Win32 Registry Manipulation
+ */
+
+#ifndef AP_REGKEY_H
+#define AP_REGKEY_H
+
+#if defined(WIN32) || defined(DOXYGEN)
+
+#include "apr.h"
+#include "apr_pools.h"
+#include "ap_config.h" /* Just for AP_DECLARE */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct ap_regkey_t ap_regkey_t;
+
+/* Used to recover AP_REGKEY_* constants
+ */
+AP_DECLARE(const ap_regkey_t *) ap_regkey_const(int i);
+
+/**
+ * Win32 Only: Constants for ap_regkey_open()
+ */
+#define AP_REGKEY_CLASSES_ROOT ap_regkey_const(0)
+#define AP_REGKEY_CURRENT_CONFIG ap_regkey_const(1)
+#define AP_REGKEY_CURRENT_USER ap_regkey_const(2)
+#define AP_REGKEY_LOCAL_MACHINE ap_regkey_const(3)
+#define AP_REGKEY_USERS ap_regkey_const(4)
+#define AP_REGKEY_PERFORMANCE_DATA ap_regkey_const(5)
+#define AP_REGKEY_DYN_DATA ap_regkey_const(6)
+
+/**
+ * Win32 Only: Flags for ap_regkey_value_set()
+ */
+#define AP_REGKEY_EXPAND 0x0001
+
+/**
+ * Win32 Only: Open the specified registry key.
+ * @param newkey The opened registry key
+ * @param parentkey The open registry key of the parent, or one of
+ * <PRE>
+ * AP_REGKEY_CLASSES_ROOT
+ * AP_REGKEY_CURRENT_CONFIG
+ * AP_REGKEY_CURRENT_USER
+ * AP_REGKEY_LOCAL_MACHINE
+ * AP_REGKEY_USERS
+ * AP_REGKEY_PERFORMANCE_DATA
+ * AP_REGKEY_DYN_DATA
+ * </PRE>
+ * @param keyname The path of the key relative to the parent key
+ * @param flags Or'ed value of:
+ * <PRE>
+ * APR_READ open key for reading
+ * APR_WRITE open key for writing
+ * APR_CREATE create the key if it doesn't exist
+ * APR_EXCL return error if APR_CREATE and key exists
+ * </PRE>
+ * @param pool The pool in which newkey is allocated
+ */
+AP_DECLARE(apr_status_t) ap_regkey_open(ap_regkey_t **newkey,
+ const ap_regkey_t *parentkey,
+ const char *keyname,
+ apr_int32_t flags,
+ apr_pool_t *pool);
+
+/**
+ * Win32 Only: Close the registry key opened or created by ap_regkey_open().
+ * @param key The registry key to close
+ */
+AP_DECLARE(apr_status_t) ap_regkey_close(ap_regkey_t *key);
+
+/**
+ * Win32 Only: Remove the given registry key.
+ * @param parent The open registry key of the parent, or one of
+ * <PRE>
+ * AP_REGKEY_CLASSES_ROOT
+ * AP_REGKEY_CURRENT_CONFIG
+ * AP_REGKEY_CURRENT_USER
+ * AP_REGKEY_LOCAL_MACHINE
+ * AP_REGKEY_USERS
+ * AP_REGKEY_PERFORMANCE_DATA
+ * AP_REGKEY_DYN_DATA
+ * </PRE>
+ * @param keyname The path of the key relative to the parent key
+ * @param pool The pool used for temp allocations
+ * @remark ap_regkey_remove() is not recursive, although it removes
+ * all values within the given keyname, it will not remove a key
+ * containing subkeys.
+ */
+AP_DECLARE(apr_status_t) ap_regkey_remove(const ap_regkey_t *parent,
+ const char *keyname,
+ apr_pool_t *pool);
+
+/**
+ * Win32 Only: Retrieve a registry value string from an open key.
+ * @param result The string value retrieved
+ * @param key The registry key to retrieve the value from
+ * @param valuename The named value to retrieve (pass "" for the default)
+ * @param pool The pool used to store the result
+ * @remark There is no toggle to prevent environment variable expansion
+ * if the registry value is set with AP_REG_EXPAND (REG_EXPAND_SZ), such
+ * expansions are always performed.
+ */
+AP_DECLARE(apr_status_t) ap_regkey_value_get(char **result,
+ ap_regkey_t *key,
+ const char *valuename,
+ apr_pool_t *pool);
+
+/**
+ * Win32 Only: Store a registry value string into an open key.
+ * @param key The registry key to store the value into
+ * @param valuename The named value to store (pass "" for the default)
+ * @param value The string to store for the named value
+ * @param flags The option AP_REGKEY_EXPAND or 0, where AP_REGKEY_EXPAND
+ * values will find all %foo% variables expanded from the environment.
+ * @param pool The pool used for temp allocations
+ */
+AP_DECLARE(apr_status_t) ap_regkey_value_set(ap_regkey_t *key,
+ const char *valuename,
+ const char *value,
+ apr_int32_t flags,
+ apr_pool_t *pool);
+
+/**
+ * Win32 Only: Retrieve a raw byte value from an open key.
+ * @param result The raw bytes value retrieved
+ * @param resultsize Pointer to a variable to store the number raw bytes retrieved
+ * @param resulttype Pointer to a variable to store the registry type of the value retrieved
+ * @param key The registry key to retrieve the value from
+ * @param valuename The named value to retrieve (pass "" for the default)
+ * @param pool The pool used to store the result
+ */
+AP_DECLARE(apr_status_t) ap_regkey_value_raw_get(void **result,
+ apr_size_t *resultsize,
+ apr_int32_t *resulttype,
+ ap_regkey_t *key,
+ const char *valuename,
+ apr_pool_t *pool);
+
+/**
+ * Win32 Only: Store a raw bytes value into an open key.
+ * @param key The registry key to store the value into
+ * @param valuename The named value to store (pass "" for the default)
+ * @param value The bytes to store for the named value
+ * @param valuesize The number of bytes for value
+ * @param valuetype The
+ * values will find all %foo% variables expanded from the environment.
+ * @param pool The pool used for temp allocations
+ */
+AP_DECLARE(apr_status_t) ap_regkey_value_raw_set(ap_regkey_t *key,
+ const char *valuename,
+ const void *value,
+ apr_size_t valuesize,
+ apr_int32_t valuetype,
+ apr_pool_t *pool);
+
+/**
+ * Win32 Only: Retrieve a registry value string from an open key.
+ * @param result The string elements retrieved from a REG_MULTI_SZ string array
+ * @param key The registry key to retrieve the value from
+ * @param valuename The named value to retrieve (pass "" for the default)
+ * @param pool The pool used to store the result
+ */
+AP_DECLARE(apr_status_t) ap_regkey_value_array_get(apr_array_header_t **result,
+ ap_regkey_t *key,
+ const char *valuename,
+ apr_pool_t *pool);
+
+/**
+ * Win32 Only: Store a registry value string array into an open key.
+ * @param key The registry key to store the value into
+ * @param valuename The named value to store (pass "" for the default)
+ * @param nelts The string elements to store in a REG_MULTI_SZ string array
+ * @param elts The number of elements in the elts string array
+ * @param pool The pool used for temp allocations
+ */
+AP_DECLARE(apr_status_t) ap_regkey_value_array_set(ap_regkey_t *key,
+ const char *valuename,
+ int nelts,
+ const char * const * elts,
+ apr_pool_t *pool);
+
+/**
+ * Win32 Only: Remove a registry value from an open key.
+ * @param key The registry key to remove the value from
+ * @param valuename The named value to remove (pass "" for the default)
+ * @param pool The pool used for temp allocations
+ */
+AP_DECLARE(apr_status_t) ap_regkey_value_remove(const ap_regkey_t *key,
+ const char *valuename,
+ apr_pool_t *pool);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* def WIN32 || def DOXYGEN */
+
+#endif /* AP_REGKEY_H */
diff --git a/include/ap_release.h b/include/ap_release.h
new file mode 100644
index 0000000..c1b1300
--- /dev/null
+++ b/include/ap_release.h
@@ -0,0 +1,83 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file ap_release.h
+ * @brief Version Release defines
+ */
+
+#ifndef AP_RELEASE_H
+#define AP_RELEASE_H
+
+#define AP_SERVER_COPYRIGHT \
+ "Copyright 2019 The Apache Software Foundation."
+
+/*
+ * The below defines the base string of the Server: header. Additional
+ * tokens can be added via the ap_add_version_component() API call.
+ *
+ * The tokens are listed in order of their significance for identifying the
+ * application.
+ *
+ * "Product tokens should be short and to the point -- use of them for
+ * advertizing or other non-essential information is explicitly forbidden."
+ *
+ * Example: "Apache/1.1.0 MrWidget/0.1-alpha"
+ */
+#define AP_SERVER_BASEVENDOR "Apache Software Foundation"
+#define AP_SERVER_BASEPROJECT "Apache HTTP Server"
+#define AP_SERVER_BASEPRODUCT "Apache"
+
+#define AP_SERVER_MAJORVERSION_NUMBER 2
+#define AP_SERVER_MINORVERSION_NUMBER 4
+#define AP_SERVER_PATCHLEVEL_NUMBER 38
+#define AP_SERVER_DEVBUILD_BOOLEAN 0
+
+/* Synchronize the above with docs/manual/style/version.ent */
+
+#if !AP_SERVER_DEVBUILD_BOOLEAN
+#define AP_SERVER_ADD_STRING ""
+#else
+#ifndef AP_SERVER_ADD_STRING
+#define AP_SERVER_ADD_STRING "-dev"
+#endif
+#endif
+
+/* APR_STRINGIFY is defined here, and also in apr_general.h, so wrap it */
+#ifndef APR_STRINGIFY
+/** Properly quote a value as a string in the C preprocessor */
+#define APR_STRINGIFY(n) APR_STRINGIFY_HELPER(n)
+/** Helper macro for APR_STRINGIFY */
+#define APR_STRINGIFY_HELPER(n) #n
+#endif
+
+/* keep old macros as well */
+#define AP_SERVER_MAJORVERSION APR_STRINGIFY(AP_SERVER_MAJORVERSION_NUMBER)
+#define AP_SERVER_MINORVERSION APR_STRINGIFY(AP_SERVER_MINORVERSION_NUMBER)
+#define AP_SERVER_PATCHLEVEL APR_STRINGIFY(AP_SERVER_PATCHLEVEL_NUMBER) \
+ AP_SERVER_ADD_STRING
+
+#define AP_SERVER_MINORREVISION AP_SERVER_MAJORVERSION "." AP_SERVER_MINORVERSION
+#define AP_SERVER_BASEREVISION AP_SERVER_MINORREVISION "." AP_SERVER_PATCHLEVEL
+#define AP_SERVER_BASEVERSION AP_SERVER_BASEPRODUCT "/" AP_SERVER_BASEREVISION
+#define AP_SERVER_VERSION AP_SERVER_BASEVERSION
+
+/* macro for Win32 .rc files using numeric csv representation */
+#define AP_SERVER_PATCHLEVEL_CSV AP_SERVER_MAJORVERSION_NUMBER, \
+ AP_SERVER_MINORVERSION_NUMBER, \
+ AP_SERVER_PATCHLEVEL_NUMBER
+
+#endif
diff --git a/include/ap_slotmem.h b/include/ap_slotmem.h
new file mode 100644
index 0000000..e1615e9
--- /dev/null
+++ b/include/ap_slotmem.h
@@ -0,0 +1,199 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SLOTMEM_H
+#define SLOTMEM_H
+
+/* Memory handler for a shared memory divided in slot.
+ */
+/**
+ * @file ap_slotmem.h
+ * @brief Memory Slot Extension Storage Module for Apache
+ *
+ * @defgroup MEM mem
+ * @ingroup APACHE_MODS
+ * @{
+ */
+
+#include "httpd.h"
+#include "http_config.h"
+#include "http_log.h"
+#include "ap_provider.h"
+
+#include "apr.h"
+#include "apr_strings.h"
+#include "apr_pools.h"
+#include "apr_shm.h"
+#include "apr_global_mutex.h"
+#include "apr_file_io.h"
+#include "apr_md5.h"
+
+#if APR_HAVE_UNISTD_H
+#include <unistd.h> /* for getpid() */
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define AP_SLOTMEM_PROVIDER_GROUP "slotmem"
+#define AP_SLOTMEM_PROVIDER_VERSION "0"
+
+typedef unsigned int ap_slotmem_type_t;
+
+/*
+ * Values for ap_slotmem_type_t::
+ *
+ * AP_SLOTMEM_TYPE_PERSIST: For transitory providers, persist
+ * the data on the file-system
+ *
+ * AP_SLOTMEM_TYPE_NOTMPSAFE:
+ *
+ * AP_SLOTMEM_TYPE_PREALLOC: Access to slots require they be grabbed 1st
+ *
+ * AP_SLOTMEM_TYPE_CLEARINUSE: If persisting, clear 'inuse' array before
+ * storing
+ */
+#define AP_SLOTMEM_TYPE_PERSIST (1 << 0)
+#define AP_SLOTMEM_TYPE_NOTMPSAFE (1 << 1)
+#define AP_SLOTMEM_TYPE_PREGRAB (1 << 2)
+#define AP_SLOTMEM_TYPE_CLEARINUSE (1 << 3)
+
+typedef struct ap_slotmem_instance_t ap_slotmem_instance_t;
+
+/**
+ * callback function used for slotmem doall.
+ * @param mem is the memory associated with a worker.
+ * @param data is what is passed to slotmem.
+ * @param pool is pool used
+ * @return APR_SUCCESS if all went well
+ */
+typedef apr_status_t ap_slotmem_callback_fn_t(void* mem, void *data, apr_pool_t *pool);
+
+struct ap_slotmem_provider_t {
+ /*
+ * Name of the provider method
+ */
+ const char *name;
+ /**
+ * call the callback on all worker slots
+ * @param s ap_slotmem_instance_t to use.
+ * @param funct callback function to call for each element.
+ * @param data parameter for the callback function.
+ * @param pool is pool used
+ * @return APR_SUCCESS if all went well
+ */
+ apr_status_t (* doall)(ap_slotmem_instance_t *s, ap_slotmem_callback_fn_t *func, void *data, apr_pool_t *pool);
+ /**
+ * create a new slotmem with each item size is item_size.
+ * This would create shared memory, basically.
+ * @param inst where to store pointer to slotmem
+ * @param name a key used for debugging and in mod_status output or allow another process to share this space.
+ * @param item_size size of each item
+ * @param item_num number of item to create.
+ * @param type type of slotmem.
+ * @param pool is pool used
+ * @return APR_SUCCESS if all went well
+ */
+ apr_status_t (* create)(ap_slotmem_instance_t **inst, const char *name, apr_size_t item_size, unsigned int item_num, ap_slotmem_type_t type, apr_pool_t *pool);
+ /**
+ * attach to an existing slotmem.
+ * This would attach to shared memory, basically.
+ * @param inst where to store pointer to slotmem
+ * @param name a key used for debugging and in mod_status output or allow another process to share this space.
+ * @param item_size size of each item
+ * @param item_num max number of item.
+ * @param pool is pool to memory allocate.
+ * @return APR_SUCCESS if all went well
+ */
+ apr_status_t (* attach)(ap_slotmem_instance_t **inst, const char *name, apr_size_t *item_size, unsigned int *item_num, apr_pool_t *pool);
+ /**
+ * get the memory ptr associated with this worker slot.
+ * @param s ap_slotmem_instance_t to use.
+ * @param item_id item to return for 0 to item_num
+ * @param mem address to store the pointer to the slot
+ * @return APR_SUCCESS if all went well
+ */
+ apr_status_t (* dptr)(ap_slotmem_instance_t *s, unsigned int item_id, void**mem);
+ /**
+ * get/read the data associated with this worker slot.
+ * @param s ap_slotmem_instance_t to use.
+ * @param item_id item to return for 0 to item_num
+ * @param dest address to store the data
+ * @param dest_len length of dataset to retrieve
+ * @return APR_SUCCESS if all went well
+ */
+ apr_status_t (* get)(ap_slotmem_instance_t *s, unsigned int item_id, unsigned char *dest, apr_size_t dest_len);
+ /**
+ * put/write the data associated with this worker slot.
+ * @param s ap_slotmem_instance_t to use.
+ * @param item_id item to return for 0 to item_num
+ * @param src address of the data to store in the slot
+ * @param src_len length of dataset to store in the slot
+ * @return APR_SUCCESS if all went well
+ */
+ apr_status_t (* put)(ap_slotmem_instance_t *slot, unsigned int item_id, unsigned char *src, apr_size_t src_len);
+ /**
+ * return number of slots allocated for this entry.
+ * @param s ap_slotmem_instance_t to use.
+ * @return number of slots
+ */
+ unsigned int (* num_slots)(ap_slotmem_instance_t *s);
+ /**
+ * return number of free (not used) slots allocated for this entry.
+ * Valid for slots which are AP_SLOTMEM_TYPE_PREGRAB as well as
+ * any which use get/release.
+ * @param s ap_slotmem_instance_t to use.
+ * @return number of slots
+ */
+ unsigned int (* num_free_slots)(ap_slotmem_instance_t *s);
+ /**
+ * return slot size allocated for this entry.
+ * @param s ap_slotmem_instance_t to use.
+ * @return size of slot
+ */
+ apr_size_t (* slot_size)(ap_slotmem_instance_t *s);
+ /**
+ * grab (or alloc) a free slot
+ * @param s ap_slotmem_instance_t to use.
+ * @param item_id ptr to the available slot id and marked as in-use
+ * @return APR_SUCCESS if all went well
+ */
+ apr_status_t (* grab)(ap_slotmem_instance_t *s, unsigned int *item_id);
+ /**
+ * release (or free) the slot associated with this item_id
+ * @param s ap_slotmem_instance_t to use.
+ * @param item_id slot id to free and mark as no longer in-use
+ * @return APR_SUCCESS if all went well
+ */
+ apr_status_t (* release)(ap_slotmem_instance_t *s, unsigned int item_id);
+ /**
+ * forced grab (or alloc) a slot associated with this item_id
+ * @param s ap_slotmem_instance_t to use.
+ * @param item_id to the specified slot id and marked as in-use
+ * @return APR_SUCCESS if all went well
+ */
+ apr_status_t (* fgrab)(ap_slotmem_instance_t *s, unsigned int item_id);
+};
+
+typedef struct ap_slotmem_provider_t ap_slotmem_provider_t;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/** @} */
diff --git a/include/ap_socache.h b/include/ap_socache.h
new file mode 100644
index 0000000..e404d2d
--- /dev/null
+++ b/include/ap_socache.h
@@ -0,0 +1,230 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file ap_socache.h
+ * @brief Small object cache provider interface.
+ *
+ * @defgroup AP_SOCACHE ap_socache
+ * @ingroup APACHE_MODS
+ * @{
+ */
+
+#ifndef AP_SOCACHE_H
+#define AP_SOCACHE_H
+
+#include "httpd.h"
+#include "ap_provider.h"
+#include "apr_pools.h"
+#include "apr_time.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** If this flag is set, the store/retrieve/remove/status interfaces
+ * of the provider are NOT safe to be called concurrently from
+ * multiple processes or threads, and an external global mutex must be
+ * used to serialize access to the provider.
+ */
+/* XXX: Even if store/retrieve/remove is atomic, isn't it useful to note
+ * independently that status and iterate may or may not be?
+ */
+#define AP_SOCACHE_FLAG_NOTMPSAFE (0x0001)
+
+/** A cache instance. */
+typedef struct ap_socache_instance_t ap_socache_instance_t;
+
+/** Hints which may be passed to the init function; providers may
+ * ignore some or all of these hints. */
+struct ap_socache_hints {
+ /** Approximate average length of IDs: */
+ apr_size_t avg_id_len;
+ /** Approximate average size of objects: */
+ apr_size_t avg_obj_size;
+ /** Suggested interval between expiry cleanup runs; */
+ apr_interval_time_t expiry_interval;
+};
+
+/**
+ * Iterator callback prototype for the ap_socache_provider_t->iterate() method
+ * @param instance The cache instance
+ * @param s Associated server context (for logging)
+ * @param userctx User defined pointer passed from the iterator call
+ * @param id Unique ID for the object (binary blob)
+ * with a trailing null char for convenience
+ * @param idlen Length of id blob
+ * @param data Output buffer to place retrieved data (binary blob)
+ * with a trailing null char for convenience
+ * @param datalen Length of data buffer
+ * @param pool Pool for temporary allocations
+ * @return APR status value; return APR_SUCCESS or the iteration will halt;
+ * this value is returned to the ap_socache_provider_t->iterate() caller
+ */
+typedef apr_status_t (ap_socache_iterator_t)(ap_socache_instance_t *instance,
+ server_rec *s,
+ void *userctx,
+ const unsigned char *id,
+ unsigned int idlen,
+ const unsigned char *data,
+ unsigned int datalen,
+ apr_pool_t *pool);
+
+/** A socache provider structure. socache providers are registered
+ * with the ap_provider.h interface using the AP_SOCACHE_PROVIDER_*
+ * constants. */
+typedef struct ap_socache_provider_t {
+ /** Canonical provider name. */
+ const char *name;
+
+ /** Bitmask of AP_SOCACHE_FLAG_* flags. */
+ unsigned int flags;
+
+ /**
+ * Create a session cache based on the given configuration string.
+ * The instance pointer returned in the instance parameter will be
+ * passed as the first argument to subsequent invocations.
+ *
+ * @param instance Output parameter to which instance object is written.
+ * @param arg User-specified configuration string. May be NULL to
+ * force use of defaults.
+ * @param tmp Pool to be used for any temporary allocations
+ * @param p Pool to be use for any allocations lasting as long as
+ * the created instance
+ * @return NULL on success, or an error string on failure.
+ */
+ const char *(*create)(ap_socache_instance_t **instance, const char *arg,
+ apr_pool_t *tmp, apr_pool_t *p);
+
+ /**
+ * Initialize the cache. The cname must be of maximum length 16
+ * characters, and uniquely identifies the consumer of the cache
+ * within the server; using the module name is recommended, e.g.
+ * "mod_ssl-sess". This string may be used within a filesystem
+ * path so use of only alphanumeric [a-z0-9_-] characters is
+ * recommended. If hints is non-NULL, it gives a set of hints for
+ * the provider. Returns APR error code.
+ *
+ * @param instance The cache instance
+ * @param cname A unique string identifying the consumer of this API
+ * @param hints Optional hints argument describing expected cache use
+ * @param s Server structure to which the cache is associated
+ * @param pool Pool for long-lived allocations
+ * @return APR status value indicating success.
+ */
+ apr_status_t (*init)(ap_socache_instance_t *instance, const char *cname,
+ const struct ap_socache_hints *hints,
+ server_rec *s, apr_pool_t *pool);
+
+ /**
+ * Destroy a given cache instance object.
+ * @param instance The cache instance to destroy.
+ * @param s Associated server structure (for logging purposes)
+ */
+ void (*destroy)(ap_socache_instance_t *instance, server_rec *s);
+
+ /**
+ * Store an object in a cache instance.
+ * @param instance The cache instance
+ * @param s Associated server structure (for logging purposes)
+ * @param id Unique ID for the object; binary blob
+ * @param idlen Length of id blob
+ * @param expiry Absolute time at which the object expires
+ * @param data Data to store; binary blob
+ * @param datalen Length of data blob
+ * @param pool Pool for temporary allocations.
+ * @return APR status value.
+ */
+ apr_status_t (*store)(ap_socache_instance_t *instance, server_rec *s,
+ const unsigned char *id, unsigned int idlen,
+ apr_time_t expiry,
+ unsigned char *data, unsigned int datalen,
+ apr_pool_t *pool);
+
+ /**
+ * Retrieve a cached object.
+ *
+ * @param instance The cache instance
+ * @param s Associated server structure (for logging purposes)
+ * @param id Unique ID for the object; binary blob
+ * @param idlen Length of id blob
+ * @param data Output buffer to place retrievd data (binary blob)
+ * @param datalen On entry, length of data buffer; on exit, the
+ * number of bytes written to the data buffer.
+ * @param pool Pool for temporary allocations.
+ * @return APR status value; APR_NOTFOUND if the object was not
+ * found
+ */
+ apr_status_t (*retrieve)(ap_socache_instance_t *instance, server_rec *s,
+ const unsigned char *id, unsigned int idlen,
+ unsigned char *data, unsigned int *datalen,
+ apr_pool_t *pool);
+
+ /**
+ * Remove an object from the cache
+ *
+ * @param instance The cache instance
+ * @param s Associated server structure (for logging purposes)
+ * @param id Unique ID for the object; binary blob
+ * @param idlen Length of id blob
+ * @param pool Pool for temporary allocations.
+ */
+ apr_status_t (*remove)(ap_socache_instance_t *instance, server_rec *s,
+ const unsigned char *id, unsigned int idlen,
+ apr_pool_t *pool);
+
+ /**
+ * Dump the status of a cache instance for mod_status. Will use
+ * the ap_r* interfaces to produce appropriate status output.
+ * XXX: ap_r* are deprecated, bad dogfood
+ *
+ * @param instance The cache instance
+ * @param r The request structure
+ * @param flags The AP_STATUS_* constants used (see mod_status.h)
+ */
+ void (*status)(ap_socache_instance_t *instance, request_rec *r, int flags);
+
+ /**
+ * Dump all cached objects through an iterator callback.
+ * @param instance The cache instance
+ * @param s Associated server context (for processing and logging)
+ * @param userctx User defined pointer passed through to the iterator
+ * @param iterator The user provided callback function which will receive
+ * individual calls for each unexpired id/data pair
+ * @param pool Pool for temporary allocations.
+ * @return APR status value; APR_NOTFOUND if the object was not
+ * found
+ */
+ apr_status_t (*iterate)(ap_socache_instance_t *instance, server_rec *s,
+ void *userctx, ap_socache_iterator_t *iterator,
+ apr_pool_t *pool);
+
+} ap_socache_provider_t;
+
+/** The provider group used to register socache providers. */
+#define AP_SOCACHE_PROVIDER_GROUP "socache"
+/** The provider version used to register socache providers. */
+#define AP_SOCACHE_PROVIDER_VERSION "0"
+
+/** Default provider name. */
+#define AP_SOCACHE_DEFAULT_PROVIDER "default"
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* AP_SOCACHE_H */
+/** @} */
diff --git a/include/apache_noprobes.h b/include/apache_noprobes.h
new file mode 100644
index 0000000..cb98b97
--- /dev/null
+++ b/include/apache_noprobes.h
@@ -0,0 +1,344 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _APACHE_NOPROBES_H_
+#define _APACHE_NOPROBES_H_
+
+#define AP_ACCESS_CHECKER_DISPATCH_COMPLETE(arg0, arg1)
+#define AP_ACCESS_CHECKER_DISPATCH_COMPLETE_ENABLED() (0)
+#define AP_ACCESS_CHECKER_DISPATCH_INVOKE(arg0)
+#define AP_ACCESS_CHECKER_DISPATCH_INVOKE_ENABLED() (0)
+#define AP_ACCESS_CHECKER_ENTRY()
+#define AP_ACCESS_CHECKER_ENTRY_ENABLED() (0)
+#define AP_ACCESS_CHECKER_RETURN(arg0)
+#define AP_ACCESS_CHECKER_RETURN_ENABLED() (0)
+#define AP_AUTH_CHECKER_DISPATCH_COMPLETE(arg0, arg1)
+#define AP_AUTH_CHECKER_DISPATCH_COMPLETE_ENABLED() (0)
+#define AP_AUTH_CHECKER_DISPATCH_INVOKE(arg0)
+#define AP_AUTH_CHECKER_DISPATCH_INVOKE_ENABLED() (0)
+#define AP_AUTH_CHECKER_ENTRY()
+#define AP_AUTH_CHECKER_ENTRY_ENABLED() (0)
+#define AP_AUTH_CHECKER_RETURN(arg0)
+#define AP_AUTH_CHECKER_RETURN_ENABLED() (0)
+#define AP_CANON_HANDLER_DISPATCH_COMPLETE(arg0, arg1)
+#define AP_CANON_HANDLER_DISPATCH_COMPLETE_ENABLED() (0)
+#define AP_CANON_HANDLER_DISPATCH_INVOKE(arg0)
+#define AP_CANON_HANDLER_DISPATCH_INVOKE_ENABLED() (0)
+#define AP_CANON_HANDLER_ENTRY()
+#define AP_CANON_HANDLER_ENTRY_ENABLED() (0)
+#define AP_CANON_HANDLER_RETURN(arg0)
+#define AP_CANON_HANDLER_RETURN_ENABLED() (0)
+#define AP_CHECK_USER_ID_DISPATCH_COMPLETE(arg0, arg1)
+#define AP_CHECK_USER_ID_DISPATCH_COMPLETE_ENABLED() (0)
+#define AP_CHECK_USER_ID_DISPATCH_INVOKE(arg0)
+#define AP_CHECK_USER_ID_DISPATCH_INVOKE_ENABLED() (0)
+#define AP_CHECK_USER_ID_ENTRY()
+#define AP_CHECK_USER_ID_ENTRY_ENABLED() (0)
+#define AP_CHECK_USER_ID_RETURN(arg0)
+#define AP_CHECK_USER_ID_RETURN_ENABLED() (0)
+#define AP_CHILD_INIT_DISPATCH_COMPLETE(arg0, arg1)
+#define AP_CHILD_INIT_DISPATCH_COMPLETE_ENABLED() (0)
+#define AP_CHILD_INIT_DISPATCH_INVOKE(arg0)
+#define AP_CHILD_INIT_DISPATCH_INVOKE_ENABLED() (0)
+#define AP_CHILD_INIT_ENTRY()
+#define AP_CHILD_INIT_ENTRY_ENABLED() (0)
+#define AP_CHILD_INIT_RETURN(arg0)
+#define AP_CHILD_INIT_RETURN_ENABLED() (0)
+#define AP_CREATE_CONNECTION_DISPATCH_COMPLETE(arg0, arg1)
+#define AP_CREATE_CONNECTION_DISPATCH_COMPLETE_ENABLED() (0)
+#define AP_CREATE_CONNECTION_DISPATCH_INVOKE(arg0)
+#define AP_CREATE_CONNECTION_DISPATCH_INVOKE_ENABLED() (0)
+#define AP_CREATE_CONNECTION_ENTRY()
+#define AP_CREATE_CONNECTION_ENTRY_ENABLED() (0)
+#define AP_CREATE_CONNECTION_RETURN(arg0)
+#define AP_CREATE_CONNECTION_RETURN_ENABLED() (0)
+#define AP_CREATE_REQUEST_DISPATCH_COMPLETE(arg0, arg1)
+#define AP_CREATE_REQUEST_DISPATCH_COMPLETE_ENABLED() (0)
+#define AP_CREATE_REQUEST_DISPATCH_INVOKE(arg0)
+#define AP_CREATE_REQUEST_DISPATCH_INVOKE_ENABLED() (0)
+#define AP_CREATE_REQUEST_ENTRY()
+#define AP_CREATE_REQUEST_ENTRY_ENABLED() (0)
+#define AP_CREATE_REQUEST_RETURN(arg0)
+#define AP_CREATE_REQUEST_RETURN_ENABLED() (0)
+#define AP_DEFAULT_PORT_DISPATCH_COMPLETE(arg0, arg1)
+#define AP_DEFAULT_PORT_DISPATCH_COMPLETE_ENABLED() (0)
+#define AP_DEFAULT_PORT_DISPATCH_INVOKE(arg0)
+#define AP_DEFAULT_PORT_DISPATCH_INVOKE_ENABLED() (0)
+#define AP_DEFAULT_PORT_ENTRY()
+#define AP_DEFAULT_PORT_ENTRY_ENABLED() (0)
+#define AP_DEFAULT_PORT_RETURN(arg0)
+#define AP_DEFAULT_PORT_RETURN_ENABLED() (0)
+#define AP_ERROR_LOG_DISPATCH_COMPLETE(arg0, arg1)
+#define AP_ERROR_LOG_DISPATCH_COMPLETE_ENABLED() (0)
+#define AP_ERROR_LOG_DISPATCH_INVOKE(arg0)
+#define AP_ERROR_LOG_DISPATCH_INVOKE_ENABLED() (0)
+#define AP_ERROR_LOG_ENTRY()
+#define AP_ERROR_LOG_ENTRY_ENABLED() (0)
+#define AP_ERROR_LOG_RETURN(arg0)
+#define AP_ERROR_LOG_RETURN_ENABLED() (0)
+#define AP_FIND_LIVEPROP_DISPATCH_COMPLETE(arg0, arg1)
+#define AP_FIND_LIVEPROP_DISPATCH_COMPLETE_ENABLED() (0)
+#define AP_FIND_LIVEPROP_DISPATCH_INVOKE(arg0)
+#define AP_FIND_LIVEPROP_DISPATCH_INVOKE_ENABLED() (0)
+#define AP_FIND_LIVEPROP_ENTRY()
+#define AP_FIND_LIVEPROP_ENTRY_ENABLED() (0)
+#define AP_FIND_LIVEPROP_RETURN(arg0)
+#define AP_FIND_LIVEPROP_RETURN_ENABLED() (0)
+#define AP_FIXUPS_DISPATCH_COMPLETE(arg0, arg1)
+#define AP_FIXUPS_DISPATCH_COMPLETE_ENABLED() (0)
+#define AP_FIXUPS_DISPATCH_INVOKE(arg0)
+#define AP_FIXUPS_DISPATCH_INVOKE_ENABLED() (0)
+#define AP_FIXUPS_ENTRY()
+#define AP_FIXUPS_ENTRY_ENABLED() (0)
+#define AP_FIXUPS_RETURN(arg0)
+#define AP_FIXUPS_RETURN_ENABLED() (0)
+#define AP_GATHER_PROPSETS_DISPATCH_COMPLETE(arg0, arg1)
+#define AP_GATHER_PROPSETS_DISPATCH_COMPLETE_ENABLED() (0)
+#define AP_GATHER_PROPSETS_DISPATCH_INVOKE(arg0)
+#define AP_GATHER_PROPSETS_DISPATCH_INVOKE_ENABLED() (0)
+#define AP_GATHER_PROPSETS_ENTRY()
+#define AP_GATHER_PROPSETS_ENTRY_ENABLED() (0)
+#define AP_GATHER_PROPSETS_RETURN(arg0)
+#define AP_GATHER_PROPSETS_RETURN_ENABLED() (0)
+#define AP_GET_MGMT_ITEMS_DISPATCH_COMPLETE(arg0, arg1)
+#define AP_GET_MGMT_ITEMS_DISPATCH_COMPLETE_ENABLED() (0)
+#define AP_GET_MGMT_ITEMS_DISPATCH_INVOKE(arg0)
+#define AP_GET_MGMT_ITEMS_DISPATCH_INVOKE_ENABLED() (0)
+#define AP_GET_MGMT_ITEMS_ENTRY()
+#define AP_GET_MGMT_ITEMS_ENTRY_ENABLED() (0)
+#define AP_GET_MGMT_ITEMS_RETURN(arg0)
+#define AP_GET_MGMT_ITEMS_RETURN_ENABLED() (0)
+#define AP_GET_SUEXEC_IDENTITY_DISPATCH_COMPLETE(arg0, arg1)
+#define AP_GET_SUEXEC_IDENTITY_DISPATCH_COMPLETE_ENABLED() (0)
+#define AP_GET_SUEXEC_IDENTITY_DISPATCH_INVOKE(arg0)
+#define AP_GET_SUEXEC_IDENTITY_DISPATCH_INVOKE_ENABLED() (0)
+#define AP_GET_SUEXEC_IDENTITY_ENTRY()
+#define AP_GET_SUEXEC_IDENTITY_ENTRY_ENABLED() (0)
+#define AP_GET_SUEXEC_IDENTITY_RETURN(arg0)
+#define AP_GET_SUEXEC_IDENTITY_RETURN_ENABLED() (0)
+#define AP_HANDLER_DISPATCH_COMPLETE(arg0, arg1)
+#define AP_HANDLER_DISPATCH_COMPLETE_ENABLED() (0)
+#define AP_HANDLER_DISPATCH_INVOKE(arg0)
+#define AP_HANDLER_DISPATCH_INVOKE_ENABLED() (0)
+#define AP_HANDLER_ENTRY()
+#define AP_HANDLER_ENTRY_ENABLED() (0)
+#define AP_HANDLER_RETURN(arg0)
+#define AP_HANDLER_RETURN_ENABLED() (0)
+#define AP_HEADER_PARSER_DISPATCH_COMPLETE(arg0, arg1)
+#define AP_HEADER_PARSER_DISPATCH_COMPLETE_ENABLED() (0)
+#define AP_HEADER_PARSER_DISPATCH_INVOKE(arg0)
+#define AP_HEADER_PARSER_DISPATCH_INVOKE_ENABLED() (0)
+#define AP_HEADER_PARSER_ENTRY()
+#define AP_HEADER_PARSER_ENTRY_ENABLED() (0)
+#define AP_HEADER_PARSER_RETURN(arg0)
+#define AP_HEADER_PARSER_RETURN_ENABLED() (0)
+#define AP_HTTP_SCHEME_DISPATCH_COMPLETE(arg0, arg1)
+#define AP_HTTP_SCHEME_DISPATCH_COMPLETE_ENABLED() (0)
+#define AP_HTTP_SCHEME_DISPATCH_INVOKE(arg0)
+#define AP_HTTP_SCHEME_DISPATCH_INVOKE_ENABLED() (0)
+#define AP_HTTP_SCHEME_ENTRY()
+#define AP_HTTP_SCHEME_ENTRY_ENABLED() (0)
+#define AP_HTTP_SCHEME_RETURN(arg0)
+#define AP_HTTP_SCHEME_RETURN_ENABLED() (0)
+#define AP_INSERT_ALL_LIVEPROPS_DISPATCH_COMPLETE(arg0, arg1)
+#define AP_INSERT_ALL_LIVEPROPS_DISPATCH_COMPLETE_ENABLED() (0)
+#define AP_INSERT_ALL_LIVEPROPS_DISPATCH_INVOKE(arg0)
+#define AP_INSERT_ALL_LIVEPROPS_DISPATCH_INVOKE_ENABLED() (0)
+#define AP_INSERT_ALL_LIVEPROPS_ENTRY()
+#define AP_INSERT_ALL_LIVEPROPS_ENTRY_ENABLED() (0)
+#define AP_INSERT_ALL_LIVEPROPS_RETURN(arg0)
+#define AP_INSERT_ALL_LIVEPROPS_RETURN_ENABLED() (0)
+#define AP_INSERT_ERROR_FILTER_DISPATCH_COMPLETE(arg0, arg1)
+#define AP_INSERT_ERROR_FILTER_DISPATCH_COMPLETE_ENABLED() (0)
+#define AP_INSERT_ERROR_FILTER_DISPATCH_INVOKE(arg0)
+#define AP_INSERT_ERROR_FILTER_DISPATCH_INVOKE_ENABLED() (0)
+#define AP_INSERT_ERROR_FILTER_ENTRY()
+#define AP_INSERT_ERROR_FILTER_ENTRY_ENABLED() (0)
+#define AP_INSERT_ERROR_FILTER_RETURN(arg0)
+#define AP_INSERT_ERROR_FILTER_RETURN_ENABLED() (0)
+#define AP_INSERT_FILTER_DISPATCH_COMPLETE(arg0, arg1)
+#define AP_INSERT_FILTER_DISPATCH_COMPLETE_ENABLED() (0)
+#define AP_INSERT_FILTER_DISPATCH_INVOKE(arg0)
+#define AP_INSERT_FILTER_DISPATCH_INVOKE_ENABLED() (0)
+#define AP_INSERT_FILTER_ENTRY()
+#define AP_INSERT_FILTER_ENTRY_ENABLED() (0)
+#define AP_INSERT_FILTER_RETURN(arg0)
+#define AP_INSERT_FILTER_RETURN_ENABLED() (0)
+#define AP_INTERNAL_REDIRECT(arg0, arg1)
+#define AP_INTERNAL_REDIRECT_ENABLED() (0)
+#define AP_LOG_TRANSACTION_DISPATCH_COMPLETE(arg0, arg1)
+#define AP_LOG_TRANSACTION_DISPATCH_COMPLETE_ENABLED() (0)
+#define AP_LOG_TRANSACTION_DISPATCH_INVOKE(arg0)
+#define AP_LOG_TRANSACTION_DISPATCH_INVOKE_ENABLED() (0)
+#define AP_LOG_TRANSACTION_ENTRY()
+#define AP_LOG_TRANSACTION_ENTRY_ENABLED() (0)
+#define AP_LOG_TRANSACTION_RETURN(arg0)
+#define AP_LOG_TRANSACTION_RETURN_ENABLED() (0)
+#define AP_MAP_TO_STORAGE_DISPATCH_COMPLETE(arg0, arg1)
+#define AP_MAP_TO_STORAGE_DISPATCH_COMPLETE_ENABLED() (0)
+#define AP_MAP_TO_STORAGE_DISPATCH_INVOKE(arg0)
+#define AP_MAP_TO_STORAGE_DISPATCH_INVOKE_ENABLED() (0)
+#define AP_MAP_TO_STORAGE_ENTRY()
+#define AP_MAP_TO_STORAGE_ENTRY_ENABLED() (0)
+#define AP_MAP_TO_STORAGE_RETURN(arg0)
+#define AP_MAP_TO_STORAGE_RETURN_ENABLED() (0)
+#define AP_MONITOR_DISPATCH_COMPLETE(arg0, arg1)
+#define AP_MONITOR_DISPATCH_COMPLETE_ENABLED() (0)
+#define AP_MONITOR_DISPATCH_INVOKE(arg0)
+#define AP_MONITOR_DISPATCH_INVOKE_ENABLED() (0)
+#define AP_MONITOR_ENTRY()
+#define AP_MONITOR_ENTRY_ENABLED() (0)
+#define AP_MONITOR_RETURN(arg0)
+#define AP_MONITOR_RETURN_ENABLED() (0)
+#define AP_OPEN_LOGS_DISPATCH_COMPLETE(arg0, arg1)
+#define AP_OPEN_LOGS_DISPATCH_COMPLETE_ENABLED() (0)
+#define AP_OPEN_LOGS_DISPATCH_INVOKE(arg0)
+#define AP_OPEN_LOGS_DISPATCH_INVOKE_ENABLED() (0)
+#define AP_OPEN_LOGS_ENTRY()
+#define AP_OPEN_LOGS_ENTRY_ENABLED() (0)
+#define AP_OPEN_LOGS_RETURN(arg0)
+#define AP_OPEN_LOGS_RETURN_ENABLED() (0)
+#define AP_OPTIONAL_FN_RETRIEVE_DISPATCH_COMPLETE(arg0, arg1)
+#define AP_OPTIONAL_FN_RETRIEVE_DISPATCH_COMPLETE_ENABLED() (0)
+#define AP_OPTIONAL_FN_RETRIEVE_DISPATCH_INVOKE(arg0)
+#define AP_OPTIONAL_FN_RETRIEVE_DISPATCH_INVOKE_ENABLED() (0)
+#define AP_OPTIONAL_FN_RETRIEVE_ENTRY()
+#define AP_OPTIONAL_FN_RETRIEVE_ENTRY_ENABLED() (0)
+#define AP_OPTIONAL_FN_RETRIEVE_RETURN(arg0)
+#define AP_OPTIONAL_FN_RETRIEVE_RETURN_ENABLED() (0)
+#define AP_POST_CONFIG_DISPATCH_COMPLETE(arg0, arg1)
+#define AP_POST_CONFIG_DISPATCH_COMPLETE_ENABLED() (0)
+#define AP_POST_CONFIG_DISPATCH_INVOKE(arg0)
+#define AP_POST_CONFIG_DISPATCH_INVOKE_ENABLED() (0)
+#define AP_POST_CONFIG_ENTRY()
+#define AP_POST_CONFIG_ENTRY_ENABLED() (0)
+#define AP_POST_CONFIG_RETURN(arg0)
+#define AP_POST_CONFIG_RETURN_ENABLED() (0)
+#define AP_POST_READ_REQUEST_DISPATCH_COMPLETE(arg0, arg1)
+#define AP_POST_READ_REQUEST_DISPATCH_COMPLETE_ENABLED() (0)
+#define AP_POST_READ_REQUEST_DISPATCH_INVOKE(arg0)
+#define AP_POST_READ_REQUEST_DISPATCH_INVOKE_ENABLED() (0)
+#define AP_POST_READ_REQUEST_ENTRY()
+#define AP_POST_READ_REQUEST_ENTRY_ENABLED() (0)
+#define AP_POST_READ_REQUEST_RETURN(arg0)
+#define AP_POST_READ_REQUEST_RETURN_ENABLED() (0)
+#define AP_POST_REQUEST_DISPATCH_COMPLETE(arg0, arg1)
+#define AP_POST_REQUEST_DISPATCH_COMPLETE_ENABLED() (0)
+#define AP_POST_REQUEST_DISPATCH_INVOKE(arg0)
+#define AP_POST_REQUEST_DISPATCH_INVOKE_ENABLED() (0)
+#define AP_POST_REQUEST_ENTRY()
+#define AP_POST_REQUEST_ENTRY_ENABLED() (0)
+#define AP_POST_REQUEST_RETURN(arg0)
+#define AP_POST_REQUEST_RETURN_ENABLED() (0)
+#define AP_PRE_CONFIG_DISPATCH_COMPLETE(arg0, arg1)
+#define AP_PRE_CONFIG_DISPATCH_COMPLETE_ENABLED() (0)
+#define AP_PRE_CONFIG_DISPATCH_INVOKE(arg0)
+#define AP_PRE_CONFIG_DISPATCH_INVOKE_ENABLED() (0)
+#define AP_PRE_CONFIG_ENTRY()
+#define AP_PRE_CONFIG_ENTRY_ENABLED() (0)
+#define AP_PRE_CONFIG_RETURN(arg0)
+#define AP_PRE_CONFIG_RETURN_ENABLED() (0)
+#define AP_PRE_CONNECTION_DISPATCH_COMPLETE(arg0, arg1)
+#define AP_PRE_CONNECTION_DISPATCH_COMPLETE_ENABLED() (0)
+#define AP_PRE_CONNECTION_DISPATCH_INVOKE(arg0)
+#define AP_PRE_CONNECTION_DISPATCH_INVOKE_ENABLED() (0)
+#define AP_PRE_CONNECTION_ENTRY()
+#define AP_PRE_CONNECTION_ENTRY_ENABLED() (0)
+#define AP_PRE_CONNECTION_RETURN(arg0)
+#define AP_PRE_CONNECTION_RETURN_ENABLED() (0)
+#define AP_PRE_MPM_DISPATCH_COMPLETE(arg0, arg1)
+#define AP_PRE_MPM_DISPATCH_COMPLETE_ENABLED() (0)
+#define AP_PRE_MPM_DISPATCH_INVOKE(arg0)
+#define AP_PRE_MPM_DISPATCH_INVOKE_ENABLED() (0)
+#define AP_PRE_MPM_ENTRY()
+#define AP_PRE_MPM_ENTRY_ENABLED() (0)
+#define AP_PRE_MPM_RETURN(arg0)
+#define AP_PRE_MPM_RETURN_ENABLED() (0)
+#define AP_PRE_REQUEST_DISPATCH_COMPLETE(arg0, arg1)
+#define AP_PRE_REQUEST_DISPATCH_COMPLETE_ENABLED() (0)
+#define AP_PRE_REQUEST_DISPATCH_INVOKE(arg0)
+#define AP_PRE_REQUEST_DISPATCH_INVOKE_ENABLED() (0)
+#define AP_PRE_REQUEST_ENTRY()
+#define AP_PRE_REQUEST_ENTRY_ENABLED() (0)
+#define AP_PRE_REQUEST_RETURN(arg0)
+#define AP_PRE_REQUEST_RETURN_ENABLED() (0)
+#define AP_PROCESS_REQUEST_ENTRY(arg0, arg1)
+#define AP_PROCESS_REQUEST_ENTRY_ENABLED() (0)
+#define AP_PROCESS_REQUEST_RETURN(arg0, arg1, arg2)
+#define AP_PROCESS_REQUEST_RETURN_ENABLED() (0)
+#define AP_PROCESS_CONNECTION_DISPATCH_COMPLETE(arg0, arg1)
+#define AP_PROCESS_CONNECTION_DISPATCH_COMPLETE_ENABLED() (0)
+#define AP_PROCESS_CONNECTION_DISPATCH_INVOKE(arg0)
+#define AP_PROCESS_CONNECTION_DISPATCH_INVOKE_ENABLED() (0)
+#define AP_PROCESS_CONNECTION_ENTRY()
+#define AP_PROCESS_CONNECTION_ENTRY_ENABLED() (0)
+#define AP_PROCESS_CONNECTION_RETURN(arg0)
+#define AP_PROCESS_CONNECTION_RETURN_ENABLED() (0)
+#define AP_PROXY_RUN(arg0, arg1, arg2, arg3, arg4)
+#define AP_PROXY_RUN_ENABLED() (0)
+#define AP_PROXY_RUN_FINISHED(arg0, arg1, arg2)
+#define AP_PROXY_RUN_FINISHED_ENABLED() (0)
+#define AP_QUICK_HANDLER_DISPATCH_COMPLETE(arg0, arg1)
+#define AP_QUICK_HANDLER_DISPATCH_COMPLETE_ENABLED() (0)
+#define AP_QUICK_HANDLER_DISPATCH_INVOKE(arg0)
+#define AP_QUICK_HANDLER_DISPATCH_INVOKE_ENABLED() (0)
+#define AP_QUICK_HANDLER_ENTRY()
+#define AP_QUICK_HANDLER_ENTRY_ENABLED() (0)
+#define AP_QUICK_HANDLER_RETURN(arg0)
+#define AP_QUICK_HANDLER_RETURN_ENABLED() (0)
+#define AP_READ_REQUEST_ENTRY(arg0, arg1)
+#define AP_READ_REQUEST_ENTRY_ENABLED() (0)
+#define AP_READ_REQUEST_FAILURE(arg0)
+#define AP_READ_REQUEST_FAILURE_ENABLED() (0)
+#define AP_READ_REQUEST_SUCCESS(arg0, arg1, arg2, arg3, arg4)
+#define AP_READ_REQUEST_SUCCESS_ENABLED() (0)
+#define AP_REWRITE_LOG(arg0, arg1, arg2, arg3, arg4)
+#define AP_REWRITE_LOG_ENABLED() (0)
+#define AP_SCHEME_HANDLER_DISPATCH_COMPLETE(arg0, arg1)
+#define AP_SCHEME_HANDLER_DISPATCH_COMPLETE_ENABLED() (0)
+#define AP_SCHEME_HANDLER_DISPATCH_INVOKE(arg0)
+#define AP_SCHEME_HANDLER_DISPATCH_INVOKE_ENABLED() (0)
+#define AP_SCHEME_HANDLER_ENTRY()
+#define AP_SCHEME_HANDLER_ENTRY_ENABLED() (0)
+#define AP_SCHEME_HANDLER_RETURN(arg0)
+#define AP_SCHEME_HANDLER_RETURN_ENABLED() (0)
+#define AP_TEST_CONFIG_DISPATCH_COMPLETE(arg0, arg1)
+#define AP_TEST_CONFIG_DISPATCH_COMPLETE_ENABLED() (0)
+#define AP_TEST_CONFIG_DISPATCH_INVOKE(arg0)
+#define AP_TEST_CONFIG_DISPATCH_INVOKE_ENABLED() (0)
+#define AP_TEST_CONFIG_ENTRY()
+#define AP_TEST_CONFIG_ENTRY_ENABLED() (0)
+#define AP_TEST_CONFIG_RETURN(arg0)
+#define AP_TEST_CONFIG_RETURN_ENABLED() (0)
+#define AP_TRANSLATE_NAME_DISPATCH_COMPLETE(arg0, arg1)
+#define AP_TRANSLATE_NAME_DISPATCH_COMPLETE_ENABLED() (0)
+#define AP_TRANSLATE_NAME_DISPATCH_INVOKE(arg0)
+#define AP_TRANSLATE_NAME_DISPATCH_INVOKE_ENABLED() (0)
+#define AP_TRANSLATE_NAME_ENTRY()
+#define AP_TRANSLATE_NAME_ENTRY_ENABLED() (0)
+#define AP_TRANSLATE_NAME_RETURN(arg0)
+#define AP_TRANSLATE_NAME_RETURN_ENABLED() (0)
+#define AP_TYPE_CHECKER_DISPATCH_COMPLETE(arg0, arg1)
+#define AP_TYPE_CHECKER_DISPATCH_COMPLETE_ENABLED() (0)
+#define AP_TYPE_CHECKER_DISPATCH_INVOKE(arg0)
+#define AP_TYPE_CHECKER_DISPATCH_INVOKE_ENABLED() (0)
+#define AP_TYPE_CHECKER_ENTRY()
+#define AP_TYPE_CHECKER_ENTRY_ENABLED() (0)
+#define AP_TYPE_CHECKER_RETURN(arg0)
+#define AP_TYPE_CHECKER_RETURN_ENABLED() (0)
+
+#endif
+
diff --git a/include/heartbeat.h b/include/heartbeat.h
new file mode 100644
index 0000000..40f98c3
--- /dev/null
+++ b/include/heartbeat.h
@@ -0,0 +1,60 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file heartbeat.h
+ * @brief commun structures for mod_heartmonitor.c and mod_lbmethod_heartbeat.c
+ *
+ * @defgroup HEARTBEAT heartbeat
+ * @ingroup APACHE_MODS
+ * @{
+ */
+
+#ifndef HEARTBEAT_H
+#define HEARTBEAT_H
+
+#include "apr.h"
+#include "apr_time.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Worse Case: IPv4-Mapped IPv6 Address
+ * 0000:0000:0000:0000:0000:FFFF:255.255.255.255
+ */
+#define MAXIPSIZE 46
+typedef struct hm_slot_server_t
+{
+ char ip[MAXIPSIZE];
+ int busy;
+ int ready;
+ apr_time_t seen;
+ int id;
+} hm_slot_server_t;
+
+/* default name of heartbeat data file, created in the configured
+ * runtime directory when mod_slotmem_shm is not available
+ */
+#define DEFAULT_HEARTBEAT_STORAGE "hb.dat"
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HEARTBEAT_H */
+/** @} */
diff --git a/include/http_config.h b/include/http_config.h
new file mode 100644
index 0000000..adc5825
--- /dev/null
+++ b/include/http_config.h
@@ -0,0 +1,1416 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file http_config.h
+ * @brief Apache Configuration
+ *
+ * @defgroup APACHE_CORE_CONFIG Configuration
+ * @ingroup APACHE_CORE
+ * @{
+ */
+
+#ifndef APACHE_HTTP_CONFIG_H
+#define APACHE_HTTP_CONFIG_H
+
+#include "util_cfgtree.h"
+#include "ap_config.h"
+#include "apr_tables.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * The central data structures around here...
+ */
+
+/* Command dispatch structures... */
+
+/**
+ * How the directives arguments should be parsed.
+ * @remark Note that for all of these except RAW_ARGS, the config routine is
+ * passed a freshly allocated string which can be modified or stored
+ * or whatever...
+ */
+enum cmd_how {
+ RAW_ARGS, /**< cmd_func parses command line itself */
+ TAKE1, /**< one argument only */
+ TAKE2, /**< two arguments only */
+ ITERATE, /**< one argument, occurring multiple times
+ * (e.g., IndexIgnore)
+ */
+ ITERATE2, /**< two arguments, 2nd occurs multiple times
+ * (e.g., AddIcon)
+ */
+ FLAG, /**< One of 'On' or 'Off' */
+ NO_ARGS, /**< No args at all, e.g. &lt;/Directory&gt; */
+ TAKE12, /**< one or two arguments */
+ TAKE3, /**< three arguments only */
+ TAKE23, /**< two or three arguments */
+ TAKE123, /**< one, two or three arguments */
+ TAKE13, /**< one or three arguments */
+ TAKE_ARGV /**< an argc and argv are passed */
+};
+
+/**
+ * This structure is passed to a command which is being invoked,
+ * to carry a large variety of miscellaneous data which is all of
+ * use to *somebody*...
+ */
+typedef struct cmd_parms_struct cmd_parms;
+
+#if defined(AP_HAVE_DESIGNATED_INITIALIZER) || defined(DOXYGEN)
+
+/**
+ * All the types of functions that can be used in directives
+ * @internal
+ */
+typedef union {
+ /** function to call for a no-args */
+ const char *(*no_args) (cmd_parms *parms, void *mconfig);
+ /** function to call for a raw-args */
+ const char *(*raw_args) (cmd_parms *parms, void *mconfig,
+ const char *args);
+ /** function to call for a argv/argc */
+ const char *(*take_argv) (cmd_parms *parms, void *mconfig,
+ int argc, char *const argv[]);
+ /** function to call for a take1 */
+ const char *(*take1) (cmd_parms *parms, void *mconfig, const char *w);
+ /** function to call for a take2 */
+ const char *(*take2) (cmd_parms *parms, void *mconfig, const char *w,
+ const char *w2);
+ /** function to call for a take3 */
+ const char *(*take3) (cmd_parms *parms, void *mconfig, const char *w,
+ const char *w2, const char *w3);
+ /** function to call for a flag */
+ const char *(*flag) (cmd_parms *parms, void *mconfig, int on);
+} cmd_func;
+
+/** This configuration directive does not take any arguments */
+# define AP_NO_ARGS func.no_args
+/** This configuration directive will handle its own parsing of arguments*/
+# define AP_RAW_ARGS func.raw_args
+/** This configuration directive will handle its own parsing of arguments*/
+# define AP_TAKE_ARGV func.take_argv
+/** This configuration directive takes 1 argument*/
+# define AP_TAKE1 func.take1
+/** This configuration directive takes 2 arguments */
+# define AP_TAKE2 func.take2
+/** This configuration directive takes 3 arguments */
+# define AP_TAKE3 func.take3
+/** This configuration directive takes a flag (on/off) as a argument*/
+# define AP_FLAG func.flag
+
+/** mechanism for declaring a directive with no arguments */
+# define AP_INIT_NO_ARGS(directive, func, mconfig, where, help) \
+ { directive, { .no_args=func }, mconfig, where, RAW_ARGS, help }
+/** mechanism for declaring a directive with raw argument parsing */
+# define AP_INIT_RAW_ARGS(directive, func, mconfig, where, help) \
+ { directive, { .raw_args=func }, mconfig, where, RAW_ARGS, help }
+/** mechanism for declaring a directive with raw argument parsing */
+# define AP_INIT_TAKE_ARGV(directive, func, mconfig, where, help) \
+ { directive, { .take_argv=func }, mconfig, where, TAKE_ARGV, help }
+/** mechanism for declaring a directive which takes 1 argument */
+# define AP_INIT_TAKE1(directive, func, mconfig, where, help) \
+ { directive, { .take1=func }, mconfig, where, TAKE1, help }
+/** mechanism for declaring a directive which takes multiple arguments */
+# define AP_INIT_ITERATE(directive, func, mconfig, where, help) \
+ { directive, { .take1=func }, mconfig, where, ITERATE, help }
+/** mechanism for declaring a directive which takes 2 arguments */
+# define AP_INIT_TAKE2(directive, func, mconfig, where, help) \
+ { directive, { .take2=func }, mconfig, where, TAKE2, help }
+/** mechanism for declaring a directive which takes 1 or 2 arguments */
+# define AP_INIT_TAKE12(directive, func, mconfig, where, help) \
+ { directive, { .take2=func }, mconfig, where, TAKE12, help }
+/** mechanism for declaring a directive which takes multiple 2 arguments */
+# define AP_INIT_ITERATE2(directive, func, mconfig, where, help) \
+ { directive, { .take2=func }, mconfig, where, ITERATE2, help }
+/** mechanism for declaring a directive which takes 1 or 3 arguments */
+# define AP_INIT_TAKE13(directive, func, mconfig, where, help) \
+ { directive, { .take3=func }, mconfig, where, TAKE13, help }
+/** mechanism for declaring a directive which takes 2 or 3 arguments */
+# define AP_INIT_TAKE23(directive, func, mconfig, where, help) \
+ { directive, { .take3=func }, mconfig, where, TAKE23, help }
+/** mechanism for declaring a directive which takes 1 to 3 arguments */
+# define AP_INIT_TAKE123(directive, func, mconfig, where, help) \
+ { directive, { .take3=func }, mconfig, where, TAKE123, help }
+/** mechanism for declaring a directive which takes 3 arguments */
+# define AP_INIT_TAKE3(directive, func, mconfig, where, help) \
+ { directive, { .take3=func }, mconfig, where, TAKE3, help }
+/** mechanism for declaring a directive which takes a flag (on/off) argument */
+# define AP_INIT_FLAG(directive, func, mconfig, where, help) \
+ { directive, { .flag=func }, mconfig, where, FLAG, help }
+
+#else /* AP_HAVE_DESIGNATED_INITIALIZER */
+
+typedef const char *(*cmd_func) ();
+
+# define AP_NO_ARGS func
+# define AP_RAW_ARGS func
+# define AP_TAKE_ARGV func
+# define AP_TAKE1 func
+# define AP_TAKE2 func
+# define AP_TAKE3 func
+# define AP_FLAG func
+
+# define AP_INIT_NO_ARGS(directive, func, mconfig, where, help) \
+ { directive, func, mconfig, where, RAW_ARGS, help }
+# define AP_INIT_RAW_ARGS(directive, func, mconfig, where, help) \
+ { directive, func, mconfig, where, RAW_ARGS, help }
+# define AP_INIT_TAKE_ARGV(directive, func, mconfig, where, help) \
+ { directive, func, mconfig, where, TAKE_ARGV, help }
+# define AP_INIT_TAKE1(directive, func, mconfig, where, help) \
+ { directive, func, mconfig, where, TAKE1, help }
+# define AP_INIT_ITERATE(directive, func, mconfig, where, help) \
+ { directive, func, mconfig, where, ITERATE, help }
+# define AP_INIT_TAKE2(directive, func, mconfig, where, help) \
+ { directive, func, mconfig, where, TAKE2, help }
+# define AP_INIT_TAKE12(directive, func, mconfig, where, help) \
+ { directive, func, mconfig, where, TAKE12, help }
+# define AP_INIT_ITERATE2(directive, func, mconfig, where, help) \
+ { directive, func, mconfig, where, ITERATE2, help }
+# define AP_INIT_TAKE13(directive, func, mconfig, where, help) \
+ { directive, func, mconfig, where, TAKE13, help }
+# define AP_INIT_TAKE23(directive, func, mconfig, where, help) \
+ { directive, func, mconfig, where, TAKE23, help }
+# define AP_INIT_TAKE123(directive, func, mconfig, where, help) \
+ { directive, func, mconfig, where, TAKE123, help }
+# define AP_INIT_TAKE3(directive, func, mconfig, where, help) \
+ { directive, func, mconfig, where, TAKE3, help }
+# define AP_INIT_FLAG(directive, func, mconfig, where, help) \
+ { directive, func, mconfig, where, FLAG, help }
+
+#endif /* AP_HAVE_DESIGNATED_INITIALIZER */
+
+/**
+ * The command record structure. Modules can define a table of these
+ * to define the directives it will implement.
+ */
+typedef struct command_struct command_rec;
+struct command_struct {
+ /** Name of this command */
+ const char *name;
+ /** The function to be called when this directive is parsed */
+ cmd_func func;
+ /** Extra data, for functions which implement multiple commands... */
+ void *cmd_data;
+ /** What overrides need to be allowed to enable this command. */
+ int req_override;
+ /** What the command expects as arguments */
+ enum cmd_how args_how;
+
+ /** 'usage' message, in case of syntax errors */
+ const char *errmsg;
+};
+
+/**
+ * @defgroup ConfigDirectives Allowed locations for configuration directives.
+ *
+ * The allowed locations for a configuration directive are the union of
+ * those indicated by each set bit in the req_override mask.
+ *
+ * @{
+ */
+#define OR_NONE 0 /**< *.conf is not available anywhere in this override */
+#define OR_LIMIT 1 /**< *.conf inside &lt;Directory&gt; or &lt;Location&gt;
+ and .htaccess when AllowOverride Limit */
+#define OR_OPTIONS 2 /**< *.conf anywhere
+ and .htaccess when AllowOverride Options */
+#define OR_FILEINFO 4 /**< *.conf anywhere
+ and .htaccess when AllowOverride FileInfo */
+#define OR_AUTHCFG 8 /**< *.conf inside &lt;Directory&gt; or &lt;Location&gt;
+ and .htaccess when AllowOverride AuthConfig */
+#define OR_INDEXES 16 /**< *.conf anywhere
+ and .htaccess when AllowOverride Indexes */
+#define OR_UNSET 32 /**< bit to indicate that AllowOverride has not been set */
+#define ACCESS_CONF 64 /**< *.conf inside &lt;Directory&gt; or &lt;Location&gt; */
+#define RSRC_CONF 128 /**< *.conf outside &lt;Directory&gt; or &lt;Location&gt; */
+#define EXEC_ON_READ 256 /**< force directive to execute a command
+ which would modify the configuration (like including another
+ file, or IFModule */
+/* Flags to determine whether syntax errors in .htaccess should be
+ * treated as nonfatal (log and ignore errors)
+ */
+#define NONFATAL_OVERRIDE 512 /* Violation of AllowOverride rule */
+#define NONFATAL_UNKNOWN 1024 /* Unrecognised directive */
+#define NONFATAL_ALL (NONFATAL_OVERRIDE|NONFATAL_UNKNOWN)
+
+#define PROXY_CONF 2048 /**< *.conf inside &lt;Proxy&gt; only */
+
+/** this directive can be placed anywhere */
+#define OR_ALL (OR_LIMIT|OR_OPTIONS|OR_FILEINFO|OR_AUTHCFG|OR_INDEXES)
+
+/** @} */
+
+/**
+ * This can be returned by a function if they don't wish to handle
+ * a command. Make it something not likely someone will actually use
+ * as an error code.
+ */
+#define DECLINE_CMD "\a\b"
+
+/** Common structure for reading of config files / passwd files etc. */
+typedef struct ap_configfile_t ap_configfile_t;
+struct ap_configfile_t {
+ /**< an apr_file_getc()-like function */
+ apr_status_t (*getch) (char *ch, void *param);
+ /**< an apr_file_gets()-like function */
+ apr_status_t (*getstr) (void *buf, apr_size_t bufsiz, void *param);
+ /**< a close handler function */
+ apr_status_t (*close) (void *param);
+ /**< the argument passed to getch/getstr/close */
+ void *param;
+ /**< the filename / description */
+ const char *name;
+ /**< current line number, starting at 1 */
+ unsigned line_number;
+};
+
+/**
+ * This structure is passed to a command which is being invoked,
+ * to carry a large variety of miscellaneous data which is all of
+ * use to *somebody*...
+ */
+struct cmd_parms_struct {
+ /** Argument to command from cmd_table */
+ void *info;
+ /** Which allow-override bits are set */
+ int override;
+ /** Which allow-override-opts bits are set */
+ int override_opts;
+ /** Table of directives allowed per AllowOverrideList */
+ apr_table_t *override_list;
+ /** Which methods are &lt;Limit&gt;ed */
+ apr_int64_t limited;
+ /** methods which are limited */
+ apr_array_header_t *limited_xmethods;
+ /** methods which are xlimited */
+ ap_method_list_t *xlimited;
+
+ /** Config file structure. */
+ ap_configfile_t *config_file;
+ /** the directive specifying this command */
+ ap_directive_t *directive;
+
+ /** Pool to allocate new storage in */
+ apr_pool_t *pool;
+ /** Pool for scratch memory; persists during configuration, but
+ * wiped before the first request is served... */
+ apr_pool_t *temp_pool;
+ /** Server_rec being configured for */
+ server_rec *server;
+ /** If configuring for a directory, pathname of that directory.
+ * NOPE! That's what it meant previous to the existence of &lt;Files&gt;,
+ * &lt;Location&gt; and regex matching. Now the only usefulness that can be
+ * derived from this field is whether a command is being called in a
+ * server context (path == NULL) or being called in a dir context
+ * (path != NULL). */
+ char *path;
+ /** configuration command */
+ const command_rec *cmd;
+
+ /** per_dir_config vector passed to handle_command */
+ struct ap_conf_vector_t *context;
+ /** directive with syntax error */
+ const ap_directive_t *err_directive;
+
+};
+
+/**
+ * Flags associated with a module.
+ */
+#define AP_MODULE_FLAG_NONE (0)
+#define AP_MODULE_FLAG_ALWAYS_MERGE (1 << 0)
+
+/**
+ * Module structures. Just about everything is dispatched through
+ * these, directly or indirectly (through the command and handler
+ * tables).
+ */
+typedef struct module_struct module;
+struct module_struct {
+ /** API version, *not* module version; check that module is
+ * compatible with this version of the server.
+ */
+ int version;
+ /** API minor version. Provides API feature milestones. Not checked
+ * during module init */
+ int minor_version;
+ /** Index to this modules structures in config vectors. */
+ int module_index;
+
+ /** The name of the module's C file */
+ const char *name;
+ /** The handle for the DSO. Internal use only */
+ void *dynamic_load_handle;
+
+ /** A pointer to the next module in the list
+ * @var module_struct *next
+ */
+ struct module_struct *next;
+
+ /** Magic Cookie to identify a module structure; It's mainly
+ * important for the DSO facility (see also mod_so). */
+ unsigned long magic;
+
+ /** Function to allow MPMs to re-write command line arguments. This
+ * hook is only available to MPMs.
+ * @param The process that the server is running in.
+ */
+ void (*rewrite_args) (process_rec *process);
+ /** Function to allow all modules to create per directory configuration
+ * structures.
+ * @param p The pool to use for all allocations.
+ * @param dir The directory currently being processed.
+ * @return The per-directory structure created
+ */
+ void *(*create_dir_config) (apr_pool_t *p, char *dir);
+ /** Function to allow all modules to merge the per directory configuration
+ * structures for two directories.
+ * @param p The pool to use for all allocations.
+ * @param base_conf The directory structure created for the parent directory.
+ * @param new_conf The directory structure currently being processed.
+ * @return The new per-directory structure created
+ */
+ void *(*merge_dir_config) (apr_pool_t *p, void *base_conf, void *new_conf);
+ /** Function to allow all modules to create per server configuration
+ * structures.
+ * @param p The pool to use for all allocations.
+ * @param s The server currently being processed.
+ * @return The per-server structure created
+ */
+ void *(*create_server_config) (apr_pool_t *p, server_rec *s);
+ /** Function to allow all modules to merge the per server configuration
+ * structures for two servers.
+ * @param p The pool to use for all allocations.
+ * @param base_conf The directory structure created for the parent directory.
+ * @param new_conf The directory structure currently being processed.
+ * @return The new per-directory structure created
+ */
+ void *(*merge_server_config) (apr_pool_t *p, void *base_conf,
+ void *new_conf);
+
+ /** A command_rec table that describes all of the directives this module
+ * defines. */
+ const command_rec *cmds;
+
+ /** A hook to allow modules to hook other points in the request processing.
+ * In this function, modules should call the ap_hook_*() functions to
+ * register an interest in a specific step in processing the current
+ * request.
+ * @param p the pool to use for all allocations
+ */
+ void (*register_hooks) (apr_pool_t *p);
+
+ /** A bitmask of AP_MODULE_FLAG_* */
+ int flags;
+};
+
+/**
+ * The AP_MAYBE_UNUSED macro is used for variable declarations that
+ * might potentially exhibit "unused var" warnings on some compilers if
+ * left untreated.
+ * Since static intializers are not part of the C language (C89), making
+ * (void) usage is not possible. However many compiler have proprietary
+ * mechanism to suppress those warnings.
+ */
+#ifdef AP_MAYBE_UNUSED
+#elif defined(__GNUC__)
+# define AP_MAYBE_UNUSED(x) x __attribute__((unused))
+#elif defined(__LCLINT__)
+# define AP_MAYBE_UNUSED(x) /*@unused@*/ x
+#else
+# define AP_MAYBE_UNUSED(x) x
+#endif
+
+/**
+ * The APLOG_USE_MODULE macro is used choose which module a file belongs to.
+ * This is necessary to allow per-module loglevel configuration.
+ *
+ * APLOG_USE_MODULE indirectly sets APLOG_MODULE_INDEX and APLOG_MARK.
+ *
+ * If a module should be backward compatible with versions before 2.3.6,
+ * APLOG_USE_MODULE needs to be enclosed in a ifdef APLOG_USE_MODULE block.
+ *
+ * @param foo name of the module symbol of the current module, without the
+ * trailing "_module" part
+ * @see APLOG_MARK
+ */
+#define APLOG_USE_MODULE(foo) \
+ extern module AP_MODULE_DECLARE_DATA foo##_module; \
+ AP_MAYBE_UNUSED(static int * const aplog_module_index) = &(foo##_module.module_index)
+
+/**
+ * AP_DECLARE_MODULE is a convenience macro that combines a call of
+ * APLOG_USE_MODULE with the definition of the module symbol.
+ *
+ * If a module should be backward compatible with versions before 2.3.6,
+ * APLOG_USE_MODULE should be used explicitly instead of AP_DECLARE_MODULE.
+ */
+#define AP_DECLARE_MODULE(foo) \
+ APLOG_USE_MODULE(foo); \
+ module AP_MODULE_DECLARE_DATA foo##_module
+
+/**
+ * @defgroup ModuleInit Module structure initializers
+ *
+ * Initializer for the first few module slots, which are only
+ * really set up once we start running. Note that the first two slots
+ * provide a version check; this should allow us to deal with changes to
+ * the API. The major number should reflect changes to the API handler table
+ * itself or removal of functionality. The minor number should reflect
+ * additions of functionality to the existing API. (the server can detect
+ * an old-format module, and either handle it back-compatibly, or at least
+ * signal an error). See src/include/ap_mmn.h for MMN version history.
+ * @{
+ */
+
+/** The one used in Apache 1.3, which will deliberately cause an error */
+#define STANDARD_MODULE_STUFF this_module_needs_to_be_ported_to_apache_2_0
+
+/** Use this in all standard modules */
+#define STANDARD20_MODULE_STUFF MODULE_MAGIC_NUMBER_MAJOR, \
+ MODULE_MAGIC_NUMBER_MINOR, \
+ -1, \
+ __FILE__, \
+ NULL, \
+ NULL, \
+ MODULE_MAGIC_COOKIE, \
+ NULL /* rewrite args spot */
+
+/** Use this only in MPMs */
+#define MPM20_MODULE_STUFF MODULE_MAGIC_NUMBER_MAJOR, \
+ MODULE_MAGIC_NUMBER_MINOR, \
+ -1, \
+ __FILE__, \
+ NULL, \
+ NULL, \
+ MODULE_MAGIC_COOKIE
+
+/** @} */
+
+/* CONFIGURATION VECTOR FUNCTIONS */
+
+/** configuration vector structure */
+typedef struct ap_conf_vector_t ap_conf_vector_t;
+
+/**
+ * Generic accessors for other modules to get at their own module-specific
+ * data
+ * @param cv The vector in which the modules configuration is stored.
+ * usually r->per_dir_config or s->module_config
+ * @param m The module to get the data for.
+ * @return The module-specific data
+ */
+AP_DECLARE(void *) ap_get_module_config(const ap_conf_vector_t *cv,
+ const module *m);
+
+/**
+ * Generic accessors for other modules to set their own module-specific
+ * data
+ * @param cv The vector in which the modules configuration is stored.
+ * usually r->per_dir_config or s->module_config
+ * @param m The module to set the data for.
+ * @param val The module-specific data to set
+ */
+AP_DECLARE(void) ap_set_module_config(ap_conf_vector_t *cv, const module *m,
+ void *val);
+
+/**
+ * When module flags have been introduced, and a way to check this.
+ */
+#define AP_MODULE_FLAGS_MMN_MAJOR 20120211
+#define AP_MODULE_FLAGS_MMN_MINOR 70
+#define AP_MODULE_HAS_FLAGS(m) \
+ AP_MODULE_MAGIC_AT_LEAST(AP_MODULE_FLAGS_MMN_MAJOR, \
+ AP_MODULE_FLAGS_MMN_MINOR)
+/**
+ * Generic accessor for the module's flags
+ * @param m The module to get the flags from.
+ * @return The module-specific flags
+ */
+AP_DECLARE(int) ap_get_module_flags(const module *m);
+
+#if !defined(AP_DEBUG)
+
+#define ap_get_module_config(v,m) \
+ (((void **)(v))[(m)->module_index])
+#define ap_set_module_config(v,m,val) \
+ ((((void **)(v))[(m)->module_index]) = (val))
+
+#endif /* AP_DEBUG */
+
+
+/**
+ * Generic accessor for modules to get the module-specific loglevel
+ * @param s The server from which to get the loglevel.
+ * @param index The module_index of the module to get the loglevel for.
+ * @return The module-specific loglevel
+ */
+AP_DECLARE(int) ap_get_server_module_loglevel(const server_rec *s, int index);
+
+/**
+ * Generic accessor for modules the module-specific loglevel
+ * @param c The connection from which to get the loglevel.
+ * @param index The module_index of the module to get the loglevel for.
+ * @return The module-specific loglevel
+ */
+AP_DECLARE(int) ap_get_conn_module_loglevel(const conn_rec *c, int index);
+
+/**
+ * Generic accessor for modules the module-specific loglevel
+ * @param c The connection from which to get the loglevel.
+ * @param s The server from which to get the loglevel if c does not have a
+ * specific loglevel configuration.
+ * @param index The module_index of the module to get the loglevel for.
+ * @return The module-specific loglevel
+ */
+AP_DECLARE(int) ap_get_conn_server_module_loglevel(const conn_rec *c,
+ const server_rec *s,
+ int index);
+
+/**
+ * Generic accessor for modules to get the module-specific loglevel
+ * @param r The request from which to get the loglevel.
+ * @param index The module_index of the module to get the loglevel for.
+ * @return The module-specific loglevel
+ */
+AP_DECLARE(int) ap_get_request_module_loglevel(const request_rec *r, int index);
+
+/**
+ * Accessor to set module-specific loglevel
+ * @param p A pool
+ * @param l The ap_logconf struct to modify.
+ * @param index The module_index of the module to set the loglevel for.
+ * @param level The new log level
+ */
+AP_DECLARE(void) ap_set_module_loglevel(apr_pool_t *p, struct ap_logconf *l,
+ int index, int level);
+
+#if !defined(AP_DEBUG)
+
+#define ap_get_conn_logconf(c) \
+ ((c)->log ? (c)->log : \
+ &(c)->base_server->log)
+
+#define ap_get_conn_server_logconf(c,s) \
+ ( ( (c)->log != &(c)->base_server->log && (c)->log != NULL ) ? \
+ (c)->log : \
+ &(s)->log )
+
+#define ap_get_request_logconf(r) \
+ ((r)->log ? (r)->log : \
+ (r)->connection->log ? (r)->connection->log : \
+ &(r)->server->log)
+
+#define ap_get_module_loglevel(l,i) \
+ (((i) < 0 || (l)->module_levels == NULL || (l)->module_levels[i] < 0) ? \
+ (l)->level : \
+ (l)->module_levels[i])
+
+#define ap_get_server_module_loglevel(s,i) \
+ (ap_get_module_loglevel(&(s)->log,i))
+
+#define ap_get_conn_module_loglevel(c,i) \
+ (ap_get_module_loglevel(ap_get_conn_logconf(c),i))
+
+#define ap_get_conn_server_module_loglevel(c,s,i) \
+ (ap_get_module_loglevel(ap_get_conn_server_logconf(c,s),i))
+
+#define ap_get_request_module_loglevel(r,i) \
+ (ap_get_module_loglevel(ap_get_request_logconf(r),i))
+
+#endif /* AP_DEBUG */
+
+/**
+ * Set all module-specific loglevels to val
+ * @param l The log config for which to set the loglevels.
+ * @param val the value to set all loglevels to
+ */
+AP_DECLARE(void) ap_reset_module_loglevels(struct ap_logconf *l, int val);
+
+/**
+ * Generic command handling function for strings
+ * @param cmd The command parameters for this directive
+ * @param struct_ptr pointer into a given type
+ * @param arg The argument to the directive
+ * @return An error string or NULL on success
+ */
+AP_DECLARE_NONSTD(const char *) ap_set_string_slot(cmd_parms *cmd,
+ void *struct_ptr,
+ const char *arg);
+
+/**
+ * Generic command handling function for integers
+ * @param cmd The command parameters for this directive
+ * @param struct_ptr pointer into a given type
+ * @param arg The argument to the directive
+ * @return An error string or NULL on success
+ */
+AP_DECLARE_NONSTD(const char *) ap_set_int_slot(cmd_parms *cmd,
+ void *struct_ptr,
+ const char *arg);
+
+/**
+ * Parsing function for log level
+ * @param str The string to parse
+ * @param val The parsed log level
+ * @return An error string or NULL on success
+ */
+AP_DECLARE(const char *) ap_parse_log_level(const char *str, int *val);
+
+/**
+ * Return true if the specified method is limited by being listed in
+ * a &lt;Limit&gt; container, or by *not* being listed in a &lt;LimitExcept&gt;
+ * container.
+ *
+ * @param method Pointer to a string specifying the method to check.
+ * @param cmd Pointer to the cmd_parms structure passed to the
+ * directive handler.
+ * @return 0 if the method is not limited in the current scope
+ */
+AP_DECLARE(int) ap_method_is_limited(cmd_parms *cmd, const char *method);
+
+/**
+ * Generic command handling function for strings, always sets the value
+ * to a lowercase string
+ * @param cmd The command parameters for this directive
+ * @param struct_ptr pointer into a given type
+ * @param arg The argument to the directive
+ * @return An error string or NULL on success
+ */
+AP_DECLARE_NONSTD(const char *) ap_set_string_slot_lower(cmd_parms *cmd,
+ void *struct_ptr,
+ const char *arg);
+/**
+ * Generic command handling function for flags stored in an int
+ * @param cmd The command parameters for this directive
+ * @param struct_ptr pointer into a given type
+ * @param arg The argument to the directive (either 1 or 0)
+ * @return An error string or NULL on success
+ */
+AP_DECLARE_NONSTD(const char *) ap_set_flag_slot(cmd_parms *cmd,
+ void *struct_ptr,
+ int arg);
+/**
+ * Generic command handling function for flags stored in a char
+ * @param cmd The command parameters for this directive
+ * @param struct_ptr pointer into a given type
+ * @param arg The argument to the directive (either 1 or 0)
+ * @return An error string or NULL on success
+ */
+AP_DECLARE_NONSTD(const char *) ap_set_flag_slot_char(cmd_parms *cmd,
+ void *struct_ptr,
+ int arg);
+/**
+ * Generic command handling function for files
+ * @param cmd The command parameters for this directive
+ * @param struct_ptr pointer into a given type
+ * @param arg The argument to the directive
+ * @return An error string or NULL on success
+ */
+AP_DECLARE_NONSTD(const char *) ap_set_file_slot(cmd_parms *cmd,
+ void *struct_ptr,
+ const char *arg);
+/**
+ * Generic command handling function to respond with cmd->help as an error
+ * @param cmd The command parameters for this directive
+ * @param struct_ptr pointer into a given type
+ * @param arg The argument to the directive
+ * @return The cmd->help value as the error string
+ * @note This allows simple declarations such as:
+ * @code
+ * AP_INIT_RAW_ARGS("Foo", ap_set_deprecated, NULL, OR_ALL,
+ * "The Foo directive is no longer supported, use Bar"),
+ * @endcode
+ */
+AP_DECLARE_NONSTD(const char *) ap_set_deprecated(cmd_parms *cmd,
+ void *struct_ptr,
+ const char *arg);
+/**
+ * For modules which need to read config files, open logs, etc. this returns
+ * the canonical form of fname made absolute to ap_server_root.
+ * @param p pool to allocate data from
+ * @param fname The file name
+ */
+AP_DECLARE(char *) ap_server_root_relative(apr_pool_t *p, const char *fname);
+
+/**
+ * Compute the name of a run-time file (e.g., shared memory "file") relative
+ * to the appropriate run-time directory. Absolute paths are returned as-is.
+ * The run-time directory is configured via the DefaultRuntimeDir directive or
+ * at build time.
+ */
+AP_DECLARE(char *) ap_runtime_dir_relative(apr_pool_t *p, const char *fname);
+
+/* Finally, the hook for dynamically loading modules in... */
+
+/**
+ * Add a module to the server
+ * @param m The module structure of the module to add
+ * @param p The pool of the same lifetime as the module
+ * @param s The module's symbol name (used for logging)
+ */
+AP_DECLARE(const char *) ap_add_module(module *m, apr_pool_t *p,
+ const char *s);
+
+/**
+ * Remove a module from the server. There are some caveats:
+ * when the module is removed, its slot is lost so all the current
+ * per-dir and per-server configurations are invalid. So we should
+ * only ever call this function when you are invalidating almost
+ * all our current data. I.e. when doing a restart.
+ * @param m the module structure of the module to remove
+ */
+AP_DECLARE(void) ap_remove_module(module *m);
+/**
+ * Add a module to the chained modules list and the list of loaded modules
+ * @param mod The module structure of the module to add
+ * @param p The pool with the same lifetime as the module
+ * @param s The module's symbol name (used for logging)
+ */
+AP_DECLARE(const char *) ap_add_loaded_module(module *mod, apr_pool_t *p,
+ const char *s);
+/**
+ * Remove a module fromthe chained modules list and the list of loaded modules
+ * @param mod the module structure of the module to remove
+ */
+AP_DECLARE(void) ap_remove_loaded_module(module *mod);
+/**
+ * Find the name of the specified module
+ * @param m The module to get the name for
+ * @return the name of the module
+ */
+AP_DECLARE(const char *) ap_find_module_name(module *m);
+/**
+ * Find the short name of the module identified by the specified module index
+ * @param module_index The module index to get the name for
+ * @return the name of the module, NULL if not found
+ */
+AP_DECLARE(const char *) ap_find_module_short_name(int module_index);
+/**
+ * Find a module based on the name of the module
+ * @param name the name of the module
+ * @return the module structure if found, NULL otherwise
+ */
+AP_DECLARE(module *) ap_find_linked_module(const char *name);
+
+/**
+ * Open a ap_configfile_t as apr_file_t
+ * @param ret_cfg open ap_configfile_t struct pointer
+ * @param p The pool to allocate the structure from
+ * @param name the name of the file to open
+ */
+AP_DECLARE(apr_status_t) ap_pcfg_openfile(ap_configfile_t **ret_cfg,
+ apr_pool_t *p, const char *name);
+
+/**
+ * Allocate a ap_configfile_t handle with user defined functions and params
+ * @param p The pool to allocate from
+ * @param descr The name of the file
+ * @param param The argument passed to getch/getstr/close
+ * @param getc_func The getch function
+ * @param gets_func The getstr function
+ * @param close_func The close function
+ */
+AP_DECLARE(ap_configfile_t *) ap_pcfg_open_custom(apr_pool_t *p,
+ const char *descr,
+ void *param,
+ apr_status_t (*getc_func) (char *ch, void *param),
+ apr_status_t (*gets_func) (void *buf, apr_size_t bufsiz, void *param),
+ apr_status_t (*close_func) (void *param));
+
+/**
+ * Read one line from open ap_configfile_t, strip leading and trailing
+ * whitespace, increase line number
+ * @param buf place to store the line read
+ * @param bufsize size of the buffer
+ * @param cfp File to read from
+ * @return error status, APR_ENOSPC if bufsize is too small for the line
+ */
+AP_DECLARE(apr_status_t) ap_cfg_getline(char *buf, apr_size_t bufsize, ap_configfile_t *cfp);
+
+/**
+ * Read one char from open configfile_t, increase line number upon LF
+ * @param ch place to store the char read
+ * @param cfp The file to read from
+ * @return error status
+ */
+AP_DECLARE(apr_status_t) ap_cfg_getc(char *ch, ap_configfile_t *cfp);
+
+/**
+ * Detach from open ap_configfile_t, calling the close handler
+ * @param cfp The file to close
+ * @return 1 on success, 0 on failure
+ */
+AP_DECLARE(int) ap_cfg_closefile(ap_configfile_t *cfp);
+
+/**
+ * Convert a return value from ap_cfg_getline or ap_cfg_getc to a user friendly
+ * string.
+ * @param p The pool to allocate the string from
+ * @param cfp The config file
+ * @param rc The return value to convert
+ * @return The error string, NULL if rc == APR_SUCCESS
+ */
+AP_DECLARE(const char *) ap_pcfg_strerror(apr_pool_t *p, ap_configfile_t *cfp,
+ apr_status_t rc);
+
+/**
+ * Read all data between the current &lt;foo&gt; and the matching &lt;/foo&gt;. All
+ * of this data is forgotten immediately.
+ * @param cmd The cmd_parms to pass to the directives inside the container
+ * @param directive The directive name to read until
+ * @return Error string on failure, NULL on success
+ * @note If cmd->pool == cmd->temp_pool, ap_soak_end_container() will assume
+ * .htaccess context and use a lower maximum line length.
+ */
+AP_DECLARE(const char *) ap_soak_end_container(cmd_parms *cmd, char *directive);
+
+/**
+ * Read all data between the current &lt;foo&gt; and the matching &lt;/foo&gt; and build
+ * a config tree from it
+ * @param p pool to allocate from
+ * @param temp_pool Temporary pool to allocate from
+ * @param parms The cmd_parms to pass to all directives read
+ * @param current The current node in the tree
+ * @param curr_parent The current parent node
+ * @param orig_directive The directive to read until hit.
+ * @return Error string on failure, NULL on success
+ * @note If p == temp_pool, ap_build_cont_config() will assume .htaccess
+ * context and use a lower maximum line length.
+*/
+AP_DECLARE(const char *) ap_build_cont_config(apr_pool_t *p,
+ apr_pool_t *temp_pool,
+ cmd_parms *parms,
+ ap_directive_t **current,
+ ap_directive_t **curr_parent,
+ char *orig_directive);
+
+/**
+ * Build a config tree from a config file
+ * @param parms The cmd_parms to pass to all of the directives in the file
+ * @param conf_pool The pconf pool
+ * @param temp_pool The temporary pool
+ * @param conftree Place to store the root node of the config tree
+ * @return Error string on erro, NULL otherwise
+ * @note If conf_pool == temp_pool, ap_build_config() will assume .htaccess
+ * context and use a lower maximum line length.
+ */
+AP_DECLARE(const char *) ap_build_config(cmd_parms *parms,
+ apr_pool_t *conf_pool,
+ apr_pool_t *temp_pool,
+ ap_directive_t **conftree);
+
+/**
+ * Walk a config tree and setup the server's internal structures
+ * @param conftree The config tree to walk
+ * @param parms The cmd_parms to pass to all functions
+ * @param section_vector The per-section config vector.
+ * @return Error string on error, NULL otherwise
+ */
+AP_DECLARE(const char *) ap_walk_config(ap_directive_t *conftree,
+ cmd_parms *parms,
+ ap_conf_vector_t *section_vector);
+
+/**
+ * @defgroup ap_check_cmd_context Check command context
+ * @{
+ */
+/**
+ * Check the context a command is used in.
+ * @param cmd The command to check
+ * @param forbidden Where the command is forbidden.
+ * @return Error string on error, NULL on success
+ */
+AP_DECLARE(const char *) ap_check_cmd_context(cmd_parms *cmd,
+ unsigned forbidden);
+
+#define NOT_IN_VIRTUALHOST 0x01 /**< Forbidden in &lt;VirtualHost&gt; */
+#define NOT_IN_LIMIT 0x02 /**< Forbidden in &lt;Limit&gt; */
+#define NOT_IN_DIRECTORY 0x04 /**< Forbidden in &lt;Directory&gt; */
+#define NOT_IN_LOCATION 0x08 /**< Forbidden in &lt;Location&gt; */
+#define NOT_IN_FILES 0x10 /**< Forbidden in &lt;Files&gt; or &lt;If&gt;*/
+#define NOT_IN_HTACCESS 0x20 /**< Forbidden in .htaccess files */
+#define NOT_IN_PROXY 0x40 /**< Forbidden in &lt;Proxy&gt; */
+/** Forbidden in &lt;Directory&gt;/&lt;Location&gt;/&lt;Files&gt;&lt;If&gt;*/
+#define NOT_IN_DIR_LOC_FILE (NOT_IN_DIRECTORY|NOT_IN_LOCATION|NOT_IN_FILES)
+/** Forbidden in &lt;Directory&gt;/&lt;Location&gt;/&lt;Files&gt;&lt;If&gt;&lt;Proxy&gt;*/
+#define NOT_IN_DIR_CONTEXT (NOT_IN_LIMIT|NOT_IN_DIR_LOC_FILE|NOT_IN_PROXY)
+/** Forbidden in &lt;VirtualHost&gt;/&lt;Limit&gt;/&lt;Directory&gt;/&lt;Location&gt;/&lt;Files&gt;/&lt;If&gt;&lt;Proxy&gt;*/
+#define GLOBAL_ONLY (NOT_IN_VIRTUALHOST|NOT_IN_DIR_CONTEXT)
+
+/** @} */
+
+/**
+ * @brief This structure is used to assign symbol names to module pointers
+ */
+typedef struct {
+ const char *name;
+ module *modp;
+} ap_module_symbol_t;
+
+/**
+ * The topmost module in the list
+ * @var module *ap_top_module
+ */
+AP_DECLARE_DATA extern module *ap_top_module;
+
+/**
+ * Array of all statically linked modules
+ * @var module *ap_prelinked_modules[]
+ */
+AP_DECLARE_DATA extern module *ap_prelinked_modules[];
+/**
+ * Array of all statically linked modulenames (symbols)
+ * @var ap_module_symbol_t ap_prelinked_module_symbols[]
+ */
+AP_DECLARE_DATA extern ap_module_symbol_t ap_prelinked_module_symbols[];
+/**
+ * Array of all preloaded modules
+ * @var module *ap_preloaded_modules[]
+ */
+AP_DECLARE_DATA extern module *ap_preloaded_modules[];
+/**
+ * Array of all loaded modules
+ * @var module **ap_loaded_modules
+ */
+AP_DECLARE_DATA extern module **ap_loaded_modules;
+
+/* For mod_so.c... */
+/** Run a single module's two create_config hooks
+ * @param p the pool to allocate from
+ * @param s The server to configure for.
+ * @param m The module to configure
+ */
+AP_DECLARE(void) ap_single_module_configure(apr_pool_t *p, server_rec *s,
+ module *m);
+
+/* For http_main.c... */
+/**
+ * Add all of the prelinked modules into the loaded module list
+ * @param process The process that is currently running the server
+ */
+AP_DECLARE(const char *) ap_setup_prelinked_modules(process_rec *process);
+
+/**
+ * Show the preloaded configuration directives, the help string explaining
+ * the directive arguments, in what module they are handled, and in
+ * what parts of the configuration they are allowed. Used for httpd -h.
+ */
+AP_DECLARE(void) ap_show_directives(void);
+
+/**
+ * Returns non-zero if a configuration directive of the given name has
+ * been registered by a module at the time of calling.
+ * @param p Pool for temporary allocations
+ * @param name Directive name
+ */
+AP_DECLARE(int) ap_exists_directive(apr_pool_t *p, const char *name);
+
+/**
+ * Show the preloaded module names. Used for httpd -l.
+ */
+AP_DECLARE(void) ap_show_modules(void);
+
+/**
+ * Show the MPM name. Used in reporting modules such as mod_info to
+ * provide extra information to the user
+ */
+AP_DECLARE(const char *) ap_show_mpm(void);
+
+/**
+ * Read all config files and setup the server
+ * @param process The process running the server
+ * @param temp_pool A pool to allocate temporary data from.
+ * @param config_name The name of the config file
+ * @param conftree Place to store the root of the config tree
+ * @return The setup server_rec list.
+ */
+AP_DECLARE(server_rec *) ap_read_config(process_rec *process,
+ apr_pool_t *temp_pool,
+ const char *config_name,
+ ap_directive_t **conftree);
+
+/**
+ * Run all rewrite args hooks for loaded modules
+ * @param process The process currently running the server
+ */
+AP_DECLARE(void) ap_run_rewrite_args(process_rec *process);
+
+/**
+ * Run the register hooks function for a specified module
+ * @param m The module to run the register hooks function fo
+ * @param p The pool valid for the lifetime of the module
+ */
+AP_DECLARE(void) ap_register_hooks(module *m, apr_pool_t *p);
+
+/**
+ * Setup all virtual hosts
+ * @param p The pool to allocate from
+ * @param main_server The head of the server_rec list
+ */
+AP_DECLARE(void) ap_fixup_virtual_hosts(apr_pool_t *p,
+ server_rec *main_server);
+
+/**
+ * Reserve some modules slots for modules loaded by other means than
+ * EXEC_ON_READ directives.
+ * Relevant modules should call this in the pre_config stage.
+ * @param count The number of slots to reserve.
+ */
+AP_DECLARE(void) ap_reserve_module_slots(int count);
+
+/**
+ * Reserve some modules slots for modules loaded by a specific
+ * non-EXEC_ON_READ config directive.
+ * This counts how often the given directive is used in the config and calls
+ * ap_reserve_module_slots() accordingly.
+ * @param directive The name of the directive
+ */
+AP_DECLARE(void) ap_reserve_module_slots_directive(const char *directive);
+
+/* For http_request.c... */
+
+/**
+ * Setup the config vector for a request_rec
+ * @param p The pool to allocate the config vector from
+ * @return The config vector
+ */
+AP_DECLARE(ap_conf_vector_t*) ap_create_request_config(apr_pool_t *p);
+
+/**
+ * Setup the config vector for per dir module configs
+ * @param p The pool to allocate the config vector from
+ * @return The config vector
+ */
+AP_CORE_DECLARE(ap_conf_vector_t *) ap_create_per_dir_config(apr_pool_t *p);
+
+/**
+ * Run all of the modules merge per dir config functions
+ * @param p The pool to pass to the merge functions
+ * @param base The base directory config structure
+ * @param new_conf The new directory config structure
+ */
+AP_CORE_DECLARE(ap_conf_vector_t*) ap_merge_per_dir_configs(apr_pool_t *p,
+ ap_conf_vector_t *base,
+ ap_conf_vector_t *new_conf);
+
+/**
+ * Allocate new ap_logconf and make (deep) copy of old ap_logconf
+ * @param p The pool to alloc from
+ * @param old The ap_logconf to copy (may be NULL)
+ * @return The new ap_logconf struct
+ */
+AP_DECLARE(struct ap_logconf *) ap_new_log_config(apr_pool_t *p,
+ const struct ap_logconf *old);
+
+/**
+ * Merge old ap_logconf into new ap_logconf.
+ * old and new must have the same life time.
+ * @param old_conf The ap_logconf to merge from
+ * @param new_conf The ap_logconf to merge into
+ */
+AP_DECLARE(void) ap_merge_log_config(const struct ap_logconf *old_conf,
+ struct ap_logconf *new_conf);
+
+/* For http_connection.c... */
+/**
+ * Setup the config vector for a connection_rec
+ * @param p The pool to allocate the config vector from
+ * @return The config vector
+ */
+AP_CORE_DECLARE(ap_conf_vector_t*) ap_create_conn_config(apr_pool_t *p);
+
+/* For http_core.c... (&lt;Directory&gt; command and virtual hosts) */
+
+/**
+ * parse an htaccess file
+ * @param result htaccess_result
+ * @param r The request currently being served
+ * @param override Which overrides are active
+ * @param override_opts Which allow-override-opts bits are set
+ * @param override_list Table of directives allowed for override
+ * @param path The path to the htaccess file
+ * @param access_name The list of possible names for .htaccess files
+ * int The status of the current request
+ */
+AP_CORE_DECLARE(int) ap_parse_htaccess(ap_conf_vector_t **result,
+ request_rec *r,
+ int override,
+ int override_opts,
+ apr_table_t *override_list,
+ const char *path,
+ const char *access_name);
+
+/**
+ * Setup a virtual host
+ * @param p The pool to allocate all memory from
+ * @param hostname The hostname of the virtual hsot
+ * @param main_server The main server for this Apache configuration
+ * @param ps Place to store the new server_rec
+ * return Error string on error, NULL on success
+ */
+AP_CORE_DECLARE(const char *) ap_init_virtual_host(apr_pool_t *p,
+ const char *hostname,
+ server_rec *main_server,
+ server_rec **ps);
+
+/**
+ * Process a config file for Apache
+ * @param s The server rec to use for the command parms
+ * @param fname The name of the config file
+ * @param conftree The root node of the created config tree
+ * @param p Pool for general allocation
+ * @param ptemp Pool for temporary allocation
+ */
+AP_DECLARE(const char *) ap_process_resource_config(server_rec *s,
+ const char *fname,
+ ap_directive_t **conftree,
+ apr_pool_t *p,
+ apr_pool_t *ptemp);
+
+/**
+ * Process all matching files as Apache configs
+ * @param s The server rec to use for the command parms
+ * @param fname The filename pattern of the config file
+ * @param conftree The root node of the created config tree
+ * @param p Pool for general allocation
+ * @param ptemp Pool for temporary allocation
+ * @param optional Whether a no-match wildcard is allowed
+ * @see apr_fnmatch for pattern handling
+ */
+AP_DECLARE(const char *) ap_process_fnmatch_configs(server_rec *s,
+ const char *fname,
+ ap_directive_t **conftree,
+ apr_pool_t *p,
+ apr_pool_t *ptemp,
+ int optional);
+
+/**
+ * Process all directives in the config tree
+ * @param s The server rec to use in the command parms
+ * @param conftree The config tree to process
+ * @param p The pool for general allocation
+ * @param ptemp The pool for temporary allocations
+ * @return OK if no problems
+ */
+AP_DECLARE(int) ap_process_config_tree(server_rec *s,
+ ap_directive_t *conftree,
+ apr_pool_t *p,
+ apr_pool_t *ptemp);
+
+/**
+ * Store data which will be retained across unload/load of modules
+ * @param key The unique key associated with this module's retained data
+ * @param size in bytes of the retained data (to be allocated)
+ * @return Address of new retained data structure, initially cleared
+ */
+AP_DECLARE(void *) ap_retained_data_create(const char *key, apr_size_t size);
+
+/**
+ * Retrieve data which was stored by ap_retained_data_create()
+ * @param key The unique key associated with this module's retained data
+ * @return Address of previously retained data structure, or NULL if not yet saved
+ */
+AP_DECLARE(void *) ap_retained_data_get(const char *key);
+
+/* Module-method dispatchers, also for http_request.c */
+/**
+ * Run the handler phase of each module until a module accepts the
+ * responsibility of serving the request
+ * @param r The current request
+ * @return The status of the current request
+ */
+AP_CORE_DECLARE(int) ap_invoke_handler(request_rec *r);
+
+/* for mod_perl */
+
+/**
+ * Find a given directive in a command_rec table
+ * @param name The directive to search for
+ * @param cmds The table to search
+ * @return The directive definition of the specified directive
+ */
+AP_CORE_DECLARE(const command_rec *) ap_find_command(const char *name,
+ const command_rec *cmds);
+
+/**
+ * Find a given directive in a list of modules.
+ * @param cmd_name The directive to search for
+ * @param mod Pointer to the first module in the linked list; will be set to
+ * the module providing cmd_name
+ * @return The directive definition of the specified directive.
+ * *mod will be changed to point to the module containing the
+ * directive.
+ */
+AP_CORE_DECLARE(const command_rec *) ap_find_command_in_modules(const char *cmd_name,
+ module **mod);
+
+/**
+ * Ask a module to create per-server and per-section (dir/loc/file) configs
+ * (if it hasn't happened already). The results are stored in the server's
+ * config, and the specified per-section config vector.
+ * @param server The server to operate upon.
+ * @param section_vector The per-section config vector.
+ * @param section Which section to create a config for.
+ * @param mod The module which is defining the config data.
+ * @param pconf A pool for all configuration allocations.
+ * @return The (new) per-section config data.
+ */
+AP_CORE_DECLARE(void *) ap_set_config_vectors(server_rec *server,
+ ap_conf_vector_t *section_vector,
+ const char *section,
+ module *mod, apr_pool_t *pconf);
+
+ /* Hooks */
+
+/**
+ * Run the header parser functions for each module
+ * @param r The current request
+ * @return OK or DECLINED
+ */
+AP_DECLARE_HOOK(int,header_parser,(request_rec *r))
+
+/**
+ * Run the pre_config function for each module
+ * @param pconf The config pool
+ * @param plog The logging streams pool
+ * @param ptemp The temporary pool
+ * @return OK or DECLINED on success anything else is a error
+ */
+AP_DECLARE_HOOK(int,pre_config,(apr_pool_t *pconf,apr_pool_t *plog,
+ apr_pool_t *ptemp))
+
+/**
+ * Run the check_config function for each module
+ * @param pconf The config pool
+ * @param plog The logging streams pool
+ * @param ptemp The temporary pool
+ * @param s the server to operate upon
+ * @return OK or DECLINED on success anything else is a error
+ */
+AP_DECLARE_HOOK(int,check_config,(apr_pool_t *pconf, apr_pool_t *plog,
+ apr_pool_t *ptemp, server_rec *s))
+
+/**
+ * Run the test_config function for each module; this hook is run
+ * only if the server was invoked to test the configuration syntax.
+ * @param pconf The config pool
+ * @param s The list of server_recs
+ * @note To avoid reordering problems due to different buffering, hook
+ * functions should only apr_file_*() to print to stdout/stderr and
+ * not simple printf()/fprintf().
+ *
+ */
+AP_DECLARE_HOOK(void,test_config,(apr_pool_t *pconf, server_rec *s))
+
+/**
+ * Run the post_config function for each module
+ * @param pconf The config pool
+ * @param plog The logging streams pool
+ * @param ptemp The temporary pool
+ * @param s The list of server_recs
+ * @return OK or DECLINED on success anything else is a error
+ */
+AP_DECLARE_HOOK(int,post_config,(apr_pool_t *pconf,apr_pool_t *plog,
+ apr_pool_t *ptemp,server_rec *s))
+
+/**
+ * Run the open_logs functions for each module
+ * @param pconf The config pool
+ * @param plog The logging streams pool
+ * @param ptemp The temporary pool
+ * @param s The list of server_recs
+ * @return OK or DECLINED on success anything else is a error
+ */
+AP_DECLARE_HOOK(int,open_logs,(apr_pool_t *pconf,apr_pool_t *plog,
+ apr_pool_t *ptemp,server_rec *s))
+
+/**
+ * Run the child_init functions for each module
+ * @param pchild The child pool
+ * @param s The list of server_recs in this server
+ */
+AP_DECLARE_HOOK(void,child_init,(apr_pool_t *pchild, server_rec *s))
+
+/**
+ * Run the handler functions for each module
+ * @param r The request_rec
+ * @remark non-wildcard handlers should HOOK_MIDDLE, wildcard HOOK_LAST
+ */
+AP_DECLARE_HOOK(int,handler,(request_rec *r))
+
+/**
+ * Run the quick handler functions for each module. The quick_handler
+ * is run before any other requests hooks are called (location_walk,
+ * directory_walk, access checking, et. al.). This hook was added
+ * to provide a quick way to serve content from a URI keyed cache.
+ *
+ * @param r The request_rec
+ * @param lookup_uri Controls whether the caller actually wants content or not.
+ * lookup is set when the quick_handler is called out of
+ * ap_sub_req_lookup_uri()
+ */
+AP_DECLARE_HOOK(int,quick_handler,(request_rec *r, int lookup_uri))
+
+/**
+ * Retrieve the optional functions for each module.
+ * This is run immediately before the server starts. Optional functions should
+ * be registered during the hook registration phase.
+ */
+AP_DECLARE_HOOK(void,optional_fn_retrieve,(void))
+
+/**
+ * Allow modules to open htaccess files or perform operations before doing so
+ * @param r The current request
+ * @param dir_name The directory for which the htaccess file should be opened
+ * @param access_name The filename for which the htaccess file should be opened
+ * @param conffile Where the pointer to the opened ap_configfile_t must be
+ * stored
+ * @param full_name Where the full file name of the htaccess file must be
+ * stored.
+ * @return APR_SUCCESS on success,
+ * APR_ENOENT or APR_ENOTDIR if no htaccess file exists,
+ * AP_DECLINED to let later modules do the opening,
+ * any other error code on error.
+ */
+AP_DECLARE_HOOK(apr_status_t,open_htaccess,
+ (request_rec *r, const char *dir_name, const char *access_name,
+ ap_configfile_t **conffile, const char **full_name))
+
+/**
+ * Core internal function, use ap_run_open_htaccess() instead.
+ */
+apr_status_t ap_open_htaccess(request_rec *r, const char *dir_name,
+ const char *access_name, ap_configfile_t **conffile,
+ const char **full_name);
+
+/**
+ * A generic pool cleanup that will reset a pointer to NULL. For use with
+ * apr_pool_cleanup_register.
+ * @param data The address of the pointer
+ * @return APR_SUCCESS
+ */
+AP_DECLARE_NONSTD(apr_status_t) ap_pool_cleanup_set_null(void *data);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !APACHE_HTTP_CONFIG_H */
+/** @} */
diff --git a/include/http_connection.h b/include/http_connection.h
new file mode 100644
index 0000000..8bc009d
--- /dev/null
+++ b/include/http_connection.h
@@ -0,0 +1,168 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file http_connection.h
+ * @brief Apache connection library
+ *
+ * @defgroup APACHE_CORE_CONNECTION Connection Library
+ * @ingroup APACHE_CORE
+ * @{
+ */
+
+#ifndef APACHE_HTTP_CONNECTION_H
+#define APACHE_HTTP_CONNECTION_H
+
+#include "apr_network_io.h"
+#include "apr_buckets.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * This is the protocol module driver. This calls all of the
+ * pre-connection and connection hooks for all protocol modules.
+ * @param c The connection on which the request is read
+ * @param csd The mechanism on which this connection is to be read.
+ * Most times this will be a socket, but it is up to the module
+ * that accepts the request to determine the exact type.
+ */
+AP_CORE_DECLARE(void) ap_process_connection(conn_rec *c, void *csd);
+
+/**
+ * Shutdown the connection for writing.
+ * @param c The connection to shutdown
+ * @param flush Whether or not to flush pending data before
+ * @return APR_SUCCESS or the underlying error
+ */
+AP_CORE_DECLARE(apr_status_t) ap_shutdown_conn(conn_rec *c, int flush);
+
+/**
+ * Flushes all remain data in the client send buffer
+ * @param c The connection to flush
+ * @remark calls ap_shutdown_conn(c, 1)
+ */
+AP_CORE_DECLARE(void) ap_flush_conn(conn_rec *c);
+
+/**
+ * This function is responsible for the following cases:
+ * <pre>
+ * we now proceed to read from the client until we get EOF, or until
+ * MAX_SECS_TO_LINGER has passed. The reasons for doing this are
+ * documented in a draft:
+ *
+ * http://tools.ietf.org/html/draft-ietf-http-connection-00.txt
+ *
+ * in a nutshell -- if we don't make this effort we risk causing
+ * TCP RST packets to be sent which can tear down a connection before
+ * all the response data has been sent to the client.
+ * </pre>
+ * @param c The connection we are closing
+ */
+AP_DECLARE(void) ap_lingering_close(conn_rec *c);
+
+AP_DECLARE(int) ap_prep_lingering_close(conn_rec *c);
+
+AP_DECLARE(int) ap_start_lingering_close(conn_rec *c);
+
+/* Hooks */
+/**
+ * create_connection is a RUN_FIRST hook which allows modules to create
+ * connections. In general, you should not install filters with the
+ * create_connection hook. If you require vhost configuration information
+ * to make filter installation decisions, you must use the pre_connection
+ * or install_network_transport hook. This hook should close the connection
+ * if it encounters a fatal error condition.
+ *
+ * @param p The pool from which to allocate the connection record
+ * @param server The server record to create the connection too.
+ * @param csd The socket that has been accepted
+ * @param conn_id A unique identifier for this connection. The ID only
+ * needs to be unique at that time, not forever.
+ * @param sbh A handle to scoreboard information for this connection.
+ * @param alloc The bucket allocator to use for all bucket/brigade creations
+ * @return An allocated connection record or NULL.
+ */
+AP_DECLARE_HOOK(conn_rec *, create_connection,
+ (apr_pool_t *p, server_rec *server, apr_socket_t *csd,
+ long conn_id, void *sbh, apr_bucket_alloc_t *alloc))
+
+/**
+ * This hook gives protocol modules an opportunity to set everything up
+ * before calling the protocol handler. All pre-connection hooks are
+ * run until one returns something other than ok or decline
+ * @param c The connection on which the request has been received.
+ * @param csd The mechanism on which this connection is to be read.
+ * Most times this will be a socket, but it is up to the module
+ * that accepts the request to determine the exact type.
+ * @return OK or DECLINED
+ */
+AP_DECLARE_HOOK(int,pre_connection,(conn_rec *c, void *csd))
+
+/**
+ * This hook implements different protocols. After a connection has been
+ * established, the protocol module must read and serve the request. This
+ * function does that for each protocol module. The first protocol module
+ * to handle the request is the last module run.
+ * @param c The connection on which the request has been received.
+ * @return OK or DECLINED
+ */
+AP_DECLARE_HOOK(int,process_connection,(conn_rec *c))
+
+/**
+ * This hook implements different protocols. Before a connection is closed,
+ * protocols might have to perform some housekeeping actions, such as
+ * sending one last goodbye packet. The connection is, unless some other
+ * error already happened before, still open and operational.
+ * All pre-close-connection hooks are run until one returns something
+ * other than ok or decline
+ * @param c The connection on which the request has been received.
+ * @return OK or DECLINED
+ */
+AP_DECLARE_HOOK(int,pre_close_connection,(conn_rec *c))
+
+/** End Of Connection (EOC) bucket */
+AP_DECLARE_DATA extern const apr_bucket_type_t ap_bucket_type_eoc;
+
+/**
+ * Determine if a bucket is an End Of Connection (EOC) bucket
+ * @param e The bucket to inspect
+ * @return true or false
+ */
+#define AP_BUCKET_IS_EOC(e) (e->type == &ap_bucket_type_eoc)
+
+/**
+ * Make the bucket passed in an End Of Connection (EOC) bucket
+ * @param b The bucket to make into an EOC bucket
+ * @return The new bucket, or NULL if allocation failed
+ */
+AP_DECLARE(apr_bucket *) ap_bucket_eoc_make(apr_bucket *b);
+
+/**
+ * Create a bucket referring to an End Of Connection (EOC). This indicates
+ * that the connection will be closed.
+ * @param list The freelist from which this bucket should be allocated
+ * @return The new bucket, or NULL if allocation failed
+ */
+AP_DECLARE(apr_bucket *) ap_bucket_eoc_create(apr_bucket_alloc_t *list);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !APACHE_HTTP_CONNECTION_H */
+/** @} */
diff --git a/include/http_core.h b/include/http_core.h
new file mode 100644
index 0000000..35df5dc
--- /dev/null
+++ b/include/http_core.h
@@ -0,0 +1,1049 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file http_core.h
+ * @brief CORE HTTP Daemon
+ *
+ * @defgroup APACHE_CORE_HTTPD Core HTTP Daemon
+ * @ingroup APACHE_CORE
+ * @{
+ */
+
+#ifndef APACHE_HTTP_CORE_H
+#define APACHE_HTTP_CORE_H
+
+#include "apr.h"
+#include "apr_hash.h"
+#include "apr_optional.h"
+#include "util_filter.h"
+#include "ap_expr.h"
+#include "apr_tables.h"
+
+#include "http_config.h"
+
+#if APR_HAVE_STRUCT_RLIMIT
+#include <sys/time.h>
+#include <sys/resource.h>
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* ****************************************************************
+ *
+ * The most basic server code is encapsulated in a single module
+ * known as the core, which is just *barely* functional enough to
+ * serve documents, though not terribly well.
+ *
+ * Largely for NCSA back-compatibility reasons, the core needs to
+ * make pieces of its config structures available to other modules.
+ * The accessors are declared here, along with the interpretation
+ * of one of them (allow_options).
+ */
+
+/**
+ * @defgroup APACHE_CORE_HTTPD_ACESSORS Acessors
+ *
+ * @brief File/Directory Accessor directives
+ *
+ * @{
+ */
+
+/** No directives */
+#define OPT_NONE 0
+/** Indexes directive */
+#define OPT_INDEXES 1
+/** SSI is enabled without exec= permission */
+#define OPT_INCLUDES 2
+/** FollowSymLinks directive */
+#define OPT_SYM_LINKS 4
+/** ExecCGI directive */
+#define OPT_EXECCGI 8
+/** directive unset */
+#define OPT_UNSET 16
+/** SSI exec= permission is permitted, iff OPT_INCLUDES is also set */
+#define OPT_INC_WITH_EXEC 32
+/** SymLinksIfOwnerMatch directive */
+#define OPT_SYM_OWNER 64
+/** MultiViews directive */
+#define OPT_MULTI 128
+/** All directives */
+#define OPT_ALL (OPT_INDEXES|OPT_INCLUDES|OPT_INC_WITH_EXEC|OPT_SYM_LINKS|OPT_EXECCGI)
+/** @} */
+
+/**
+ * @defgroup get_remote_host Remote Host Resolution
+ * @ingroup APACHE_CORE_HTTPD
+ * @{
+ */
+/** REMOTE_HOST returns the hostname, or NULL if the hostname
+ * lookup fails. It will force a DNS lookup according to the
+ * HostnameLookups setting.
+ */
+#define REMOTE_HOST (0)
+
+/** REMOTE_NAME returns the hostname, or the dotted quad if the
+ * hostname lookup fails. It will force a DNS lookup according
+ * to the HostnameLookups setting.
+ */
+#define REMOTE_NAME (1)
+
+/** REMOTE_NOLOOKUP is like REMOTE_NAME except that a DNS lookup is
+ * never forced.
+ */
+#define REMOTE_NOLOOKUP (2)
+
+/** REMOTE_DOUBLE_REV will always force a DNS lookup, and also force
+ * a double reverse lookup, regardless of the HostnameLookups
+ * setting. The result is the (double reverse checked) hostname,
+ * or NULL if any of the lookups fail.
+ */
+#define REMOTE_DOUBLE_REV (3)
+
+/** @} // get_remote_host */
+
+/** all of the requirements must be met */
+#define SATISFY_ALL 0
+/** any of the requirements must be met */
+#define SATISFY_ANY 1
+/** There are no applicable satisfy lines */
+#define SATISFY_NOSPEC 2
+
+/** Make sure we don't write less than 8000 bytes at any one time.
+ */
+#define AP_MIN_BYTES_TO_WRITE 8000
+
+/** default maximum of internal redirects */
+# define AP_DEFAULT_MAX_INTERNAL_REDIRECTS 10
+
+/** default maximum subrequest nesting level */
+# define AP_DEFAULT_MAX_SUBREQ_DEPTH 10
+
+/**
+ * Retrieve the value of Options for this request
+ * @param r The current request
+ * @return the Options bitmask
+ */
+AP_DECLARE(int) ap_allow_options(request_rec *r);
+
+/**
+ * Retrieve the value of the AllowOverride for this request
+ * @param r The current request
+ * @return the overrides bitmask
+ */
+AP_DECLARE(int) ap_allow_overrides(request_rec *r);
+
+/**
+ * Retrieve the document root for this server
+ * @param r The current request
+ * @warning Don't use this! If your request went through a Userdir, or
+ * something like that, it'll screw you. But it's back-compatible...
+ * @return The document root
+ */
+AP_DECLARE(const char *) ap_document_root(request_rec *r);
+
+/**
+ * Lookup the remote user agent's DNS name or IP address
+ * @ingroup get_remote_hostname
+ * @param req The current request
+ * @param type The type of lookup to perform. One of:
+ * <pre>
+ * REMOTE_HOST returns the hostname, or NULL if the hostname
+ * lookup fails. It will force a DNS lookup according to the
+ * HostnameLookups setting.
+ * REMOTE_NAME returns the hostname, or the dotted quad if the
+ * hostname lookup fails. It will force a DNS lookup according
+ * to the HostnameLookups setting.
+ * REMOTE_NOLOOKUP is like REMOTE_NAME except that a DNS lookup is
+ * never forced.
+ * REMOTE_DOUBLE_REV will always force a DNS lookup, and also force
+ * a double reverse lookup, regardless of the HostnameLookups
+ * setting. The result is the (double reverse checked)
+ * hostname, or NULL if any of the lookups fail.
+ * </pre>
+ * @param str_is_ip unless NULL is passed, this will be set to non-zero on
+ * output when an IP address string is returned
+ * @return The remote hostname (based on the request useragent_ip)
+ */
+AP_DECLARE(const char *) ap_get_useragent_host(request_rec *req, int type,
+ int *str_is_ip);
+
+/**
+ * Lookup the remote client's DNS name or IP address
+ * @ingroup get_remote_host
+ * @param conn The current connection
+ * @param dir_config The directory config vector from the request
+ * @param type The type of lookup to perform. One of:
+ * <pre>
+ * REMOTE_HOST returns the hostname, or NULL if the hostname
+ * lookup fails. It will force a DNS lookup according to the
+ * HostnameLookups setting.
+ * REMOTE_NAME returns the hostname, or the dotted quad if the
+ * hostname lookup fails. It will force a DNS lookup according
+ * to the HostnameLookups setting.
+ * REMOTE_NOLOOKUP is like REMOTE_NAME except that a DNS lookup is
+ * never forced.
+ * REMOTE_DOUBLE_REV will always force a DNS lookup, and also force
+ * a double reverse lookup, regardless of the HostnameLookups
+ * setting. The result is the (double reverse checked)
+ * hostname, or NULL if any of the lookups fail.
+ * </pre>
+ * @param str_is_ip unless NULL is passed, this will be set to non-zero on output when an IP address
+ * string is returned
+ * @return The remote hostname (based on the connection client_ip)
+ */
+AP_DECLARE(const char *) ap_get_remote_host(conn_rec *conn, void *dir_config, int type, int *str_is_ip);
+
+/**
+ * Retrieve the login name of the remote user. Undef if it could not be
+ * determined
+ * @param r The current request
+ * @return The user logged in to the client machine
+ */
+AP_DECLARE(const char *) ap_get_remote_logname(request_rec *r);
+
+/* Used for constructing self-referencing URLs, and things like SERVER_PORT,
+ * and SERVER_NAME.
+ */
+/**
+ * build a fully qualified URL from the uri and information in the request rec
+ * @param p The pool to allocate the URL from
+ * @param uri The path to the requested file
+ * @param r The current request
+ * @return A fully qualified URL
+ */
+AP_DECLARE(char *) ap_construct_url(apr_pool_t *p, const char *uri, request_rec *r);
+
+/**
+ * Get the current server name from the request
+ * @param r The current request
+ * @return the server name
+ */
+AP_DECLARE(const char *) ap_get_server_name(request_rec *r);
+
+/**
+ * Get the current server name from the request for the purposes
+ * of using in a URL. If the server name is an IPv6 literal
+ * address, it will be returned in URL format (e.g., "[fe80::1]").
+ * @param r The current request
+ * @return the server name
+ */
+AP_DECLARE(const char *) ap_get_server_name_for_url(request_rec *r);
+
+/**
+ * Get the current server port
+ * @param r The current request
+ * @return The server's port
+ */
+AP_DECLARE(apr_port_t) ap_get_server_port(const request_rec *r);
+
+/**
+ * Return the limit on bytes in request msg body
+ * @param r The current request
+ * @return the maximum number of bytes in the request msg body
+ */
+AP_DECLARE(apr_off_t) ap_get_limit_req_body(const request_rec *r);
+
+/**
+ * Return the limit on bytes in XML request msg body
+ * @param r The current request
+ * @return the maximum number of bytes in XML request msg body
+ */
+AP_DECLARE(apr_size_t) ap_get_limit_xml_body(const request_rec *r);
+
+/**
+ * Install a custom response handler for a given status
+ * @param r The current request
+ * @param status The status for which the custom response should be used
+ * @param string The custom response. This can be a static string, a file
+ * or a URL
+ */
+AP_DECLARE(void) ap_custom_response(request_rec *r, int status, const char *string);
+
+/**
+ * Check if the current request is beyond the configured max. number of redirects or subrequests
+ * @param r The current request
+ * @return true (is exceeded) or false
+ */
+AP_DECLARE(int) ap_is_recursion_limit_exceeded(const request_rec *r);
+
+/**
+ * Check for a definition from the server command line
+ * @param name The define to check for
+ * @return 1 if defined, 0 otherwise
+ */
+AP_DECLARE(int) ap_exists_config_define(const char *name);
+/* FIXME! See STATUS about how */
+AP_DECLARE_NONSTD(int) ap_core_translate(request_rec *r);
+
+/* Authentication stuff. This is one of the places where compatibility
+ * with the old config files *really* hurts; they don't discriminate at
+ * all between different authentication schemes, meaning that we need
+ * to maintain common state for all of them in the core, and make it
+ * available to the other modules through interfaces.
+ */
+
+/** @see require_line */
+typedef struct require_line require_line;
+
+/**
+ * @brief A structure to keep track of authorization requirements
+*/
+struct require_line {
+ /** Where the require line is in the config file. */
+ apr_int64_t method_mask;
+ /** The complete string from the command line */
+ char *requirement;
+};
+
+/**
+ * Return the type of authorization required for this request
+ * @param r The current request
+ * @return The authorization required
+ */
+AP_DECLARE(const char *) ap_auth_type(request_rec *r);
+
+/**
+ * Return the current Authorization realm
+ * @param r The current request
+ * @return The current authorization realm
+ */
+AP_DECLARE(const char *) ap_auth_name(request_rec *r);
+
+/**
+ * How the requires lines must be met.
+ * @param r The current request
+ * @return How the requirements must be met. One of:
+ * <pre>
+ * SATISFY_ANY -- any of the requirements must be met.
+ * SATISFY_ALL -- all of the requirements must be met.
+ * SATISFY_NOSPEC -- There are no applicable satisfy lines
+ * </pre>
+ */
+AP_DECLARE(int) ap_satisfies(request_rec *r);
+
+/**
+ * Core is also unlike other modules in being implemented in more than
+ * one file... so, data structures are declared here, even though most of
+ * the code that cares really is in http_core.c. Also, another accessor.
+ */
+AP_DECLARE_DATA extern module core_module;
+
+/**
+ * Accessor for core_module's specific data. Equivalent to
+ * ap_get_module_config(cv, &core_module) but more efficient.
+ * @param cv The vector in which the modules configuration is stored.
+ * usually r->per_dir_config or s->module_config
+ * @return The module-specific data
+ */
+AP_DECLARE(void *) ap_get_core_module_config(const ap_conf_vector_t *cv);
+
+/**
+ * Accessor to set core_module's specific data. Equivalent to
+ * ap_set_module_config(cv, &core_module, val) but more efficient.
+ * @param cv The vector in which the modules configuration is stored.
+ * usually r->per_dir_config or s->module_config
+ * @param val The module-specific data to set
+ */
+AP_DECLARE(void) ap_set_core_module_config(ap_conf_vector_t *cv, void *val);
+
+/** Get the socket from the core network filter. This should be used instead of
+ * accessing the core connection config directly.
+ * @param c The connection record
+ * @return The socket
+ */
+AP_DECLARE(apr_socket_t *) ap_get_conn_socket(conn_rec *c);
+
+#ifndef AP_DEBUG
+#define AP_CORE_MODULE_INDEX 0
+#define ap_get_core_module_config(v) \
+ (((void **)(v))[AP_CORE_MODULE_INDEX])
+#define ap_set_core_module_config(v, val) \
+ ((((void **)(v))[AP_CORE_MODULE_INDEX]) = (val))
+#else
+#define AP_CORE_MODULE_INDEX (AP_DEBUG_ASSERT(core_module.module_index == 0), 0)
+#endif
+
+/**
+ * @brief Per-request configuration
+*/
+typedef struct {
+ /** bucket brigade used by getline for look-ahead and
+ * ap_get_client_block for holding left-over request body */
+ struct apr_bucket_brigade *bb;
+
+ /** an array of per-request working data elements, accessed
+ * by ID using ap_get_request_note()
+ * (Use ap_register_request_note() during initialization
+ * to add elements)
+ */
+ void **notes;
+
+ /** Custom response strings registered via ap_custom_response(),
+ * or NULL; check per-dir config if nothing found here
+ */
+ char **response_code_strings; /* from ap_custom_response(), not from
+ * ErrorDocument
+ */
+
+ /** per-request document root of the server. This allows mass vhosting
+ * modules better compatibility with some scripts. Normally the
+ * context_* info should be used instead */
+ const char *document_root;
+
+ /*
+ * more fine-grained context information which is set by modules like
+ * mod_alias and mod_userdir
+ */
+ /** the context root directory on disk for the current resource,
+ * without trailing slash
+ */
+ const char *context_document_root;
+ /** the URI prefix that corresponds to the context_document_root directory,
+ * without trailing slash
+ */
+ const char *context_prefix;
+
+ /** There is a script processor installed on the output filter chain,
+ * so it needs the default_handler to deliver a (script) file into
+ * the chain so it can process it. Normally, default_handler only
+ * serves files on a GET request (assuming the file is actual content),
+ * since other methods are not content-retrieval. This flag overrides
+ * that behavior, stating that the "content" is actually a script and
+ * won't actually be delivered as the response for the non-GET method.
+ */
+ int deliver_script;
+
+ /** Should addition of charset= be suppressed for this request?
+ */
+ int suppress_charset;
+} core_request_config;
+
+/* Standard entries that are guaranteed to be accessible via
+ * ap_get_request_note() for each request (additional entries
+ * can be added with ap_register_request_note())
+ */
+#define AP_NOTE_DIRECTORY_WALK 0
+#define AP_NOTE_LOCATION_WALK 1
+#define AP_NOTE_FILE_WALK 2
+#define AP_NOTE_IF_WALK 3
+#define AP_NUM_STD_NOTES 4
+
+/**
+ * Reserve an element in the core_request_config->notes array
+ * for some application-specific data
+ * @return An integer key that can be passed to ap_get_request_note()
+ * during request processing to access this element for the
+ * current request.
+ */
+AP_DECLARE(apr_size_t) ap_register_request_note(void);
+
+/**
+ * Retrieve a pointer to an element in the core_request_config->notes array
+ * @param r The request
+ * @param note_num A key for the element: either a value obtained from
+ * ap_register_request_note() or one of the predefined AP_NOTE_*
+ * values.
+ * @return NULL if the note_num is invalid, otherwise a pointer to the
+ * requested note element.
+ * @remark At the start of a request, each note element is NULL. The
+ * handle provided by ap_get_request_note() is a pointer-to-pointer
+ * so that the caller can point the element to some app-specific
+ * data structure. The caller should guarantee that any such
+ * structure will last as long as the request itself.
+ */
+AP_DECLARE(void **) ap_get_request_note(request_rec *r, apr_size_t note_num);
+
+
+typedef unsigned char allow_options_t;
+typedef unsigned int overrides_t;
+
+/*
+ * Bits of info that go into making an ETag for a file
+ * document. Why a long? Because char historically
+ * proved too short for Options, and int can be different
+ * sizes on different platforms.
+ */
+typedef unsigned long etag_components_t;
+
+#define ETAG_UNSET 0
+#define ETAG_NONE (1 << 0)
+#define ETAG_MTIME (1 << 1)
+#define ETAG_INODE (1 << 2)
+#define ETAG_SIZE (1 << 3)
+#define ETAG_ALL (ETAG_MTIME | ETAG_INODE | ETAG_SIZE)
+/* This is the default value used */
+#define ETAG_BACKWARD (ETAG_MTIME | ETAG_SIZE)
+
+/* Generic ON/OFF/UNSET for unsigned int foo :2 */
+#define AP_CORE_CONFIG_OFF (0)
+#define AP_CORE_CONFIG_ON (1)
+#define AP_CORE_CONFIG_UNSET (2)
+
+/* Generic merge of flag */
+#define AP_CORE_MERGE_FLAG(field, to, base, over) to->field = \
+ over->field != AP_CORE_CONFIG_UNSET \
+ ? over->field \
+ : base->field
+
+/**
+ * @brief Server Signature Enumeration
+ */
+typedef enum {
+ srv_sig_unset,
+ srv_sig_off,
+ srv_sig_on,
+ srv_sig_withmail
+} server_signature_e;
+
+/**
+ * @brief Per-directory configuration
+ */
+typedef struct {
+ /** path of the directory/regex/etc. see also d_is_fnmatch/absolute below */
+ char *d;
+ /** the number of slashes in d */
+ unsigned d_components;
+
+ /** If (opts & OPT_UNSET) then no absolute assignment to options has
+ * been made.
+ * invariant: (opts_add & opts_remove) == 0
+ * Which said another way means that the last relative (options + or -)
+ * assignment made to each bit is recorded in exactly one of opts_add
+ * or opts_remove.
+ */
+ allow_options_t opts;
+ allow_options_t opts_add;
+ allow_options_t opts_remove;
+ overrides_t override;
+ allow_options_t override_opts;
+
+ /* Used to be the custom response config. No longer used. */
+ char **response_code_strings; /* from ErrorDocument, not from
+ * ap_custom_response() */
+
+ /* Hostname resolution etc */
+#define HOSTNAME_LOOKUP_OFF 0
+#define HOSTNAME_LOOKUP_ON 1
+#define HOSTNAME_LOOKUP_DOUBLE 2
+#define HOSTNAME_LOOKUP_UNSET 3
+ unsigned int hostname_lookups : 4;
+
+ unsigned int content_md5 : 2; /* calculate Content-MD5? */
+
+#define USE_CANONICAL_NAME_OFF (0)
+#define USE_CANONICAL_NAME_ON (1)
+#define USE_CANONICAL_NAME_DNS (2)
+#define USE_CANONICAL_NAME_UNSET (3)
+ unsigned use_canonical_name : 2;
+
+ /* since is_fnmatch(conf->d) was being called so frequently in
+ * directory_walk() and its relatives, this field was created and
+ * is set to the result of that call.
+ */
+ unsigned d_is_fnmatch : 1;
+
+ /* should we force a charset on any outgoing parameterless content-type?
+ * if so, which charset?
+ */
+#define ADD_DEFAULT_CHARSET_OFF (0)
+#define ADD_DEFAULT_CHARSET_ON (1)
+#define ADD_DEFAULT_CHARSET_UNSET (2)
+ unsigned add_default_charset : 2;
+ const char *add_default_charset_name;
+
+ /* System Resource Control */
+#ifdef RLIMIT_CPU
+ struct rlimit *limit_cpu;
+#endif
+#if defined (RLIMIT_DATA) || defined (RLIMIT_VMEM) || defined(RLIMIT_AS)
+ struct rlimit *limit_mem;
+#endif
+#ifdef RLIMIT_NPROC
+ struct rlimit *limit_nproc;
+#endif
+ apr_off_t limit_req_body; /* limit on bytes in request msg body */
+ long limit_xml_body; /* limit on bytes in XML request msg body */
+
+ /* logging options */
+
+ server_signature_e server_signature;
+
+ /* Access control */
+ apr_array_header_t *sec_file;
+ apr_array_header_t *sec_if;
+ ap_regex_t *r;
+
+ const char *mime_type; /* forced with ForceType */
+ const char *handler; /* forced by something other than SetHandler */
+ const char *output_filters; /* forced with SetOutputFilters */
+ const char *input_filters; /* forced with SetInputFilters */
+ int accept_path_info; /* forced with AcceptPathInfo */
+
+ /*
+ * What attributes/data should be included in ETag generation?
+ */
+ etag_components_t etag_bits;
+ etag_components_t etag_add;
+ etag_components_t etag_remove;
+
+ /*
+ * Run-time performance tuning
+ */
+#define ENABLE_MMAP_OFF (0)
+#define ENABLE_MMAP_ON (1)
+#define ENABLE_MMAP_UNSET (2)
+ unsigned int enable_mmap : 2; /* whether files in this dir can be mmap'ed */
+
+#define ENABLE_SENDFILE_OFF (0)
+#define ENABLE_SENDFILE_ON (1)
+#define ENABLE_SENDFILE_UNSET (2)
+ unsigned int enable_sendfile : 2; /* files in this dir can be sendfile'ed */
+
+#define USE_CANONICAL_PHYS_PORT_OFF (0)
+#define USE_CANONICAL_PHYS_PORT_ON (1)
+#define USE_CANONICAL_PHYS_PORT_UNSET (2)
+ unsigned int use_canonical_phys_port : 2;
+
+ unsigned int allow_encoded_slashes : 1; /* URLs may contain %2f w/o being
+ * pitched indiscriminately */
+ unsigned int decode_encoded_slashes : 1; /* whether to decode encoded slashes in URLs */
+
+#define AP_CONDITION_IF 1
+#define AP_CONDITION_ELSE 2
+#define AP_CONDITION_ELSEIF (AP_CONDITION_ELSE|AP_CONDITION_IF)
+ unsigned int condition_ifelse : 2; /* is this an <If>, <ElseIf>, or <Else> */
+
+ ap_expr_info_t *condition; /* Conditionally merge <If> sections */
+
+ /** per-dir log config */
+ struct ap_logconf *log;
+
+ /** Table of directives allowed per AllowOverrideList */
+ apr_table_t *override_list;
+
+#define AP_MAXRANGES_UNSET -1
+#define AP_MAXRANGES_DEFAULT -2
+#define AP_MAXRANGES_UNLIMITED -3
+#define AP_MAXRANGES_NORANGES 0
+ /** Number of Ranges before returning HTTP_OK. **/
+ int max_ranges;
+ /** Max number of Range overlaps (merges) allowed **/
+ int max_overlaps;
+ /** Max number of Range reversals (eg: 200-300, 100-125) allowed **/
+ int max_reversals;
+
+ /** Named back references */
+ apr_array_header_t *refs;
+
+ /** Custom response config with expression support. The hash table
+ * contains compiled expressions keyed against the custom response
+ * code.
+ */
+ apr_hash_t *response_code_exprs;
+
+#define AP_CGI_PASS_AUTH_OFF (0)
+#define AP_CGI_PASS_AUTH_ON (1)
+#define AP_CGI_PASS_AUTH_UNSET (2)
+ /** CGIPassAuth: Whether HTTP authorization headers will be passed to
+ * scripts as CGI variables; affects all modules calling
+ * ap_add_common_vars(), as well as any others using this field as
+ * advice
+ */
+ unsigned int cgi_pass_auth : 2;
+ unsigned int qualify_redirect_url :2;
+ ap_expr_info_t *expr_handler; /* forced with SetHandler */
+
+ /** Table of rules for building CGI variables, NULL if none configured */
+ apr_hash_t *cgi_var_rules;
+} core_dir_config;
+
+/* macro to implement off by default behaviour */
+#define AP_SENDFILE_ENABLED(x) \
+ ((x) == ENABLE_SENDFILE_ON ? APR_SENDFILE_ENABLED : 0)
+
+/* Per-server core configuration */
+
+typedef struct {
+
+ char *gprof_dir;
+
+ /* Name translations --- we want the core to be able to do *something*
+ * so it's at least a minimally functional web server on its own (and
+ * can be tested that way). But let's keep it to the bare minimum:
+ */
+ const char *ap_document_root;
+
+ /* Access control */
+
+ char *access_name;
+ apr_array_header_t *sec_dir;
+ apr_array_header_t *sec_url;
+
+ /* recursion backstopper */
+ int redirect_limit; /* maximum number of internal redirects */
+ int subreq_limit; /* maximum nesting level of subrequests */
+
+ const char *protocol;
+ apr_table_t *accf_map;
+
+ /* array of ap_errorlog_format_item for error log format string */
+ apr_array_header_t *error_log_format;
+ /*
+ * two arrays of arrays of ap_errorlog_format_item for additional information
+ * logged to the error log once per connection/request
+ */
+ apr_array_header_t *error_log_conn;
+ apr_array_header_t *error_log_req;
+
+ /* TRACE control */
+#define AP_TRACE_UNSET -1
+#define AP_TRACE_DISABLE 0
+#define AP_TRACE_ENABLE 1
+#define AP_TRACE_EXTENDED 2
+ int trace_enable;
+#define AP_MERGE_TRAILERS_UNSET 0
+#define AP_MERGE_TRAILERS_ENABLE 1
+#define AP_MERGE_TRAILERS_DISABLE 2
+ int merge_trailers;
+
+ apr_array_header_t *protocols;
+ int protocols_honor_order;
+
+#define AP_HTTP09_UNSET 0
+#define AP_HTTP09_ENABLE 1
+#define AP_HTTP09_DISABLE 2
+ char http09_enable;
+
+#define AP_HTTP_CONFORMANCE_UNSET 0
+#define AP_HTTP_CONFORMANCE_UNSAFE 1
+#define AP_HTTP_CONFORMANCE_STRICT 2
+ char http_conformance;
+
+#define AP_HTTP_METHODS_UNSET 0
+#define AP_HTTP_METHODS_LENIENT 1
+#define AP_HTTP_METHODS_REGISTERED 2
+ char http_methods;
+
+} core_server_config;
+
+/* for AddOutputFiltersByType in core.c */
+void ap_add_output_filters_by_type(request_rec *r);
+
+/* for http_config.c */
+void ap_core_reorder_directories(apr_pool_t *, server_rec *);
+
+/* for mod_perl */
+AP_CORE_DECLARE(void) ap_add_per_dir_conf(server_rec *s, void *dir_config);
+AP_CORE_DECLARE(void) ap_add_per_url_conf(server_rec *s, void *url_config);
+AP_CORE_DECLARE(void) ap_add_file_conf(apr_pool_t *p, core_dir_config *conf, void *url_config);
+AP_CORE_DECLARE(const char *) ap_add_if_conf(apr_pool_t *p, core_dir_config *conf, void *url_config);
+AP_CORE_DECLARE_NONSTD(const char *) ap_limit_section(cmd_parms *cmd, void *dummy, const char *arg);
+
+/* Core filters; not exported. */
+apr_status_t ap_core_input_filter(ap_filter_t *f, apr_bucket_brigade *b,
+ ap_input_mode_t mode, apr_read_type_e block,
+ apr_off_t readbytes);
+apr_status_t ap_core_output_filter(ap_filter_t *f, apr_bucket_brigade *b);
+
+
+AP_DECLARE(const char*) ap_get_server_protocol(server_rec* s);
+AP_DECLARE(void) ap_set_server_protocol(server_rec* s, const char* proto);
+
+typedef struct core_output_filter_ctx core_output_filter_ctx_t;
+typedef struct core_filter_ctx core_ctx_t;
+
+typedef struct core_net_rec {
+ /** Connection to the client */
+ apr_socket_t *client_socket;
+
+ /** connection record */
+ conn_rec *c;
+
+ core_output_filter_ctx_t *out_ctx;
+ core_ctx_t *in_ctx;
+} core_net_rec;
+
+/**
+ * Insert the network bucket into the core input filter's input brigade.
+ * This hook is intended for MPMs or protocol modules that need to do special
+ * socket setup.
+ * @param c The connection
+ * @param bb The brigade to insert the bucket into
+ * @param socket The socket to put into a bucket
+ * @return AP_DECLINED if the current function does not handle this connection,
+ * APR_SUCCESS or an error otherwise.
+ */
+AP_DECLARE_HOOK(apr_status_t, insert_network_bucket,
+ (conn_rec *c, apr_bucket_brigade *bb, apr_socket_t *socket))
+
+/* ----------------------------------------------------------------------
+ *
+ * Runtime status/management
+ */
+
+typedef enum {
+ ap_mgmt_type_string,
+ ap_mgmt_type_long,
+ ap_mgmt_type_hash
+} ap_mgmt_type_e;
+
+typedef union {
+ const char *s_value;
+ long i_value;
+ apr_hash_t *h_value;
+} ap_mgmt_value;
+
+typedef struct {
+ const char *description;
+ const char *name;
+ ap_mgmt_type_e vtype;
+ ap_mgmt_value v;
+} ap_mgmt_item_t;
+
+/* Handles for core filters */
+AP_DECLARE_DATA extern ap_filter_rec_t *ap_subreq_core_filter_handle;
+AP_DECLARE_DATA extern ap_filter_rec_t *ap_core_output_filter_handle;
+AP_DECLARE_DATA extern ap_filter_rec_t *ap_content_length_filter_handle;
+AP_DECLARE_DATA extern ap_filter_rec_t *ap_core_input_filter_handle;
+
+/**
+ * This hook provdes a way for modules to provide metrics/statistics about
+ * their operational status.
+ *
+ * @param p A pool to use to create entries in the hash table
+ * @param val The name of the parameter(s) that is wanted. This is
+ * tree-structured would be in the form ('*' is all the tree,
+ * 'module.*' all of the module , 'module.foo.*', or
+ * 'module.foo.bar' )
+ * @param ht The hash table to store the results. Keys are item names, and
+ * the values point to ap_mgmt_item_t structures.
+ * @ingroup hooks
+ */
+AP_DECLARE_HOOK(int, get_mgmt_items,
+ (apr_pool_t *p, const char * val, apr_hash_t *ht))
+
+/* ---------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ *
+ * I/O logging with mod_logio
+ */
+
+APR_DECLARE_OPTIONAL_FN(void, ap_logio_add_bytes_out,
+ (conn_rec *c, apr_off_t bytes));
+
+APR_DECLARE_OPTIONAL_FN(void, ap_logio_add_bytes_in,
+ (conn_rec *c, apr_off_t bytes));
+
+APR_DECLARE_OPTIONAL_FN(apr_off_t, ap_logio_get_last_bytes, (conn_rec *c));
+
+/* ----------------------------------------------------------------------
+ *
+ * Error log formats
+ */
+
+/**
+ * The info structure passed to callback functions of errorlog handlers.
+ * Not all information is available in all contexts. In particular, all
+ * pointers may be NULL.
+ */
+typedef struct ap_errorlog_info {
+ /** current server_rec.
+ * Should be preferred over c->base_server and r->server
+ */
+ const server_rec *s;
+
+ /** current conn_rec.
+ * Should be preferred over r->connection
+ */
+ const conn_rec *c;
+
+ /** current request_rec. */
+ const request_rec *r;
+ /** r->main if r is a subrequest, otherwise equal to r */
+ const request_rec *rmain;
+
+ /** pool passed to ap_log_perror, NULL otherwise */
+ apr_pool_t *pool;
+
+ /** name of source file where the log message was produced, NULL if N/A. */
+ const char *file;
+ /** line number in the source file, 0 if N/A */
+ int line;
+
+ /** module index of module that produced the log message, APLOG_NO_MODULE if N/A. */
+ int module_index;
+ /** log level of error message (flags like APLOG_STARTUP have been removed), -1 if N/A */
+ int level;
+
+ /** apr error status related to the log message, 0 if no error */
+ apr_status_t status;
+
+ /** 1 if logging to syslog, 0 otherwise */
+ int using_syslog;
+ /** 1 if APLOG_STARTUP was set for the log message, 0 otherwise */
+ int startup;
+
+ /** message format */
+ const char *format;
+} ap_errorlog_info;
+
+/**
+ * callback function prototype for a external errorlog handler
+ * @note To avoid unbounded memory usage, these functions must not allocate
+ * memory from the server, connection, or request pools. If an errorlog
+ * handler absolutely needs a pool to pass to other functions, it must create
+ * and destroy a sub-pool.
+ */
+typedef int ap_errorlog_handler_fn_t(const ap_errorlog_info *info,
+ const char *arg, char *buf, int buflen);
+
+/**
+ * Register external errorlog handler
+ * @param p config pool to use
+ * @param tag the new format specifier (i.e. the letter after the %)
+ * @param handler the handler function
+ * @param flags flags (reserved, set to 0)
+ */
+AP_DECLARE(void) ap_register_errorlog_handler(apr_pool_t *p, char *tag,
+ ap_errorlog_handler_fn_t *handler,
+ int flags);
+
+typedef struct ap_errorlog_handler {
+ ap_errorlog_handler_fn_t *func;
+ int flags; /* for future extensions */
+} ap_errorlog_handler;
+
+ /** item starts a new field */
+#define AP_ERRORLOG_FLAG_FIELD_SEP 1
+ /** item is the actual error message */
+#define AP_ERRORLOG_FLAG_MESSAGE 2
+ /** skip whole line if item is zero-length */
+#define AP_ERRORLOG_FLAG_REQUIRED 4
+ /** log zero-length item as '-' */
+#define AP_ERRORLOG_FLAG_NULL_AS_HYPHEN 8
+
+typedef struct {
+ /** ap_errorlog_handler function */
+ ap_errorlog_handler_fn_t *func;
+ /** argument passed to item in {} */
+ const char *arg;
+ /** a combination of the AP_ERRORLOG_* flags */
+ unsigned int flags;
+ /** only log item if the message's log level is higher than this */
+ unsigned int min_loglevel;
+} ap_errorlog_format_item;
+
+/**
+ * hook method to log error messages
+ * @ingroup hooks
+ * @param info pointer to ap_errorlog_info struct which contains all
+ * the details
+ * @param errstr the (unformatted) message to log
+ * @warning Allocating from the usual pools (pool, info->c->pool, info->p->pool)
+ * must be avoided because it can cause memory leaks.
+ * Use a subpool if necessary.
+ */
+AP_DECLARE_HOOK(void, error_log, (const ap_errorlog_info *info,
+ const char *errstr))
+
+AP_CORE_DECLARE(void) ap_register_log_hooks(apr_pool_t *p);
+AP_CORE_DECLARE(void) ap_register_config_hooks(apr_pool_t *p);
+
+/* ----------------------------------------------------------------------
+ *
+ * ident lookups with mod_ident
+ */
+
+APR_DECLARE_OPTIONAL_FN(const char *, ap_ident_lookup,
+ (request_rec *r));
+
+/* ----------------------------------------------------------------------
+ *
+ * authorization values with mod_authz_core
+ */
+
+APR_DECLARE_OPTIONAL_FN(int, authz_some_auth_required, (request_rec *r));
+APR_DECLARE_OPTIONAL_FN(const char *, authn_ap_auth_type, (request_rec *r));
+APR_DECLARE_OPTIONAL_FN(const char *, authn_ap_auth_name, (request_rec *r));
+
+/* ----------------------------------------------------------------------
+ *
+ * authorization values with mod_access_compat
+ */
+
+APR_DECLARE_OPTIONAL_FN(int, access_compat_ap_satisfies, (request_rec *r));
+
+/* ---------------------------------------------------------------------- */
+
+/** Query the server for some state information
+ * @param query_code Which information is requested
+ * @return the requested state information
+ */
+AP_DECLARE(int) ap_state_query(int query_code);
+
+/*
+ * possible values for query_code in ap_state_query()
+ */
+
+ /** current status of the server */
+#define AP_SQ_MAIN_STATE 0
+ /** are we going to serve requests or are we just testing/dumping config */
+#define AP_SQ_RUN_MODE 1
+ /** generation of the top-level apache parent */
+#define AP_SQ_CONFIG_GEN 2
+
+/*
+ * return values for ap_state_query()
+ */
+
+ /** return value for unknown query_code */
+#define AP_SQ_NOT_SUPPORTED -1
+
+/* values returned for AP_SQ_MAIN_STATE */
+ /** before the config preflight */
+#define AP_SQ_MS_INITIAL_STARTUP 1
+ /** initial configuration run for setting up log config, etc. */
+#define AP_SQ_MS_CREATE_PRE_CONFIG 2
+ /** tearing down configuration */
+#define AP_SQ_MS_DESTROY_CONFIG 3
+ /** normal configuration run */
+#define AP_SQ_MS_CREATE_CONFIG 4
+ /** running the MPM */
+#define AP_SQ_MS_RUN_MPM 5
+ /** cleaning up for exit */
+#define AP_SQ_MS_EXITING 6
+
+/* values returned for AP_SQ_RUN_MODE */
+ /** command line not yet parsed */
+#define AP_SQ_RM_UNKNOWN 1
+ /** normal operation (server requests or signal server) */
+#define AP_SQ_RM_NORMAL 2
+ /** config test only */
+#define AP_SQ_RM_CONFIG_TEST 3
+ /** only dump some parts of the config */
+#define AP_SQ_RM_CONFIG_DUMP 4
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !APACHE_HTTP_CORE_H */
+/** @} */
diff --git a/include/http_log.h b/include/http_log.h
new file mode 100644
index 0000000..2b61a11
--- /dev/null
+++ b/include/http_log.h
@@ -0,0 +1,836 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file http_log.h
+ * @brief Apache Logging library
+ *
+ * @defgroup APACHE_CORE_LOG Logging library
+ * @ingroup APACHE_CORE
+ * @{
+ */
+
+#ifndef APACHE_HTTP_LOG_H
+#define APACHE_HTTP_LOG_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "apr_thread_proc.h"
+#include "http_config.h"
+
+#ifdef HAVE_SYSLOG
+#include <syslog.h>
+
+#ifndef LOG_PRIMASK
+#define LOG_PRIMASK 7
+#endif
+
+#define APLOG_EMERG LOG_EMERG /* system is unusable */
+#define APLOG_ALERT LOG_ALERT /* action must be taken immediately */
+#define APLOG_CRIT LOG_CRIT /* critical conditions */
+#define APLOG_ERR LOG_ERR /* error conditions */
+#define APLOG_WARNING LOG_WARNING /* warning conditions */
+#define APLOG_NOTICE LOG_NOTICE /* normal but significant condition */
+#define APLOG_INFO LOG_INFO /* informational */
+#define APLOG_DEBUG LOG_DEBUG /* debug-level messages */
+#define APLOG_TRACE1 (LOG_DEBUG + 1) /* trace-level 1 messages */
+#define APLOG_TRACE2 (LOG_DEBUG + 2) /* trace-level 2 messages */
+#define APLOG_TRACE3 (LOG_DEBUG + 3) /* trace-level 3 messages */
+#define APLOG_TRACE4 (LOG_DEBUG + 4) /* trace-level 4 messages */
+#define APLOG_TRACE5 (LOG_DEBUG + 5) /* trace-level 5 messages */
+#define APLOG_TRACE6 (LOG_DEBUG + 6) /* trace-level 6 messages */
+#define APLOG_TRACE7 (LOG_DEBUG + 7) /* trace-level 7 messages */
+#define APLOG_TRACE8 (LOG_DEBUG + 8) /* trace-level 8 messages */
+
+#define APLOG_LEVELMASK 15 /* mask off the level value */
+
+#else
+
+#define APLOG_EMERG 0 /* system is unusable */
+#define APLOG_ALERT 1 /* action must be taken immediately */
+#define APLOG_CRIT 2 /* critical conditions */
+#define APLOG_ERR 3 /* error conditions */
+#define APLOG_WARNING 4 /* warning conditions */
+#define APLOG_NOTICE 5 /* normal but significant condition */
+#define APLOG_INFO 6 /* informational */
+#define APLOG_DEBUG 7 /* debug-level messages */
+#define APLOG_TRACE1 8 /* trace-level 1 messages */
+#define APLOG_TRACE2 9 /* trace-level 2 messages */
+#define APLOG_TRACE3 10 /* trace-level 3 messages */
+#define APLOG_TRACE4 11 /* trace-level 4 messages */
+#define APLOG_TRACE5 12 /* trace-level 5 messages */
+#define APLOG_TRACE6 13 /* trace-level 6 messages */
+#define APLOG_TRACE7 14 /* trace-level 7 messages */
+#define APLOG_TRACE8 15 /* trace-level 8 messages */
+
+#define APLOG_LEVELMASK 15 /* mask off the level value */
+
+#endif
+
+/* APLOG_NOERRNO is ignored and should not be used. It will be
+ * removed in a future release of Apache.
+ */
+#define APLOG_NOERRNO (APLOG_LEVELMASK + 1)
+
+/** Use APLOG_TOCLIENT on ap_log_rerror() to give content
+ * handlers the option of including the error text in the
+ * ErrorDocument sent back to the client. Setting APLOG_TOCLIENT
+ * will cause the error text to be saved in the request_rec->notes
+ * table, keyed to the string "error-notes", if and only if:
+ * - the severity level of the message is APLOG_WARNING or greater
+ * - there are no other "error-notes" set in request_rec->notes
+ * Once error-notes is set, it is up to the content handler to
+ * determine whether this text should be sent back to the client.
+ * Note: Client generated text streams sent back to the client MUST
+ * be escaped to prevent CSS attacks.
+ */
+#define APLOG_TOCLIENT ((APLOG_LEVELMASK + 1) * 2)
+
+/* normal but significant condition on startup, usually printed to stderr */
+#define APLOG_STARTUP ((APLOG_LEVELMASK + 1) * 4)
+
+#ifndef DEFAULT_LOGLEVEL
+#define DEFAULT_LOGLEVEL APLOG_WARNING
+#endif
+
+/**
+ * APLOGNO() should be used at the start of the format string passed
+ * to ap_log_error() and friends. The argument must be a 5 digit decimal
+ * number. It creates a tag of the form "AH02182: "
+ * See docs/log-message-tags/README for details.
+ */
+#define APLOGNO(n) "AH" #n ": "
+
+/**
+ * APLOG_NO_MODULE may be passed as module_index to ap_log_error() and related
+ * functions if the module causing the log message is not known. Normally this
+ * should not be used directly. Use ::APLOG_MARK or ::APLOG_MODULE_INDEX
+ * instead.
+ *
+ * @see APLOG_MARK
+ * @see APLOG_MODULE_INDEX
+ * @see ap_log_error
+ */
+#define APLOG_NO_MODULE -1
+
+#ifdef __cplusplus
+/**
+ * C++ modules must invoke ::APLOG_USE_MODULE or ::AP_DECLARE_MODULE in
+ * every file which uses ap_log_* before the first use of ::APLOG_MARK
+ * or ::APLOG_MODULE_INDEX.
+ * (C modules *should* do that as well, to enable module-specific log
+ * levels. C modules need not obey the ordering, though).
+ */
+#else /* __cplusplus */
+/**
+ * Constant to store module_index for the current file.
+ * Objects with static storage duration are set to NULL if not
+ * initialized explicitly. This means that if aplog_module_index
+ * is not initialized using the ::APLOG_USE_MODULE or the
+ * ::AP_DECLARE_MODULE macro, we can safely fall back to
+ * use ::APLOG_NO_MODULE. This variable will usually be optimized away.
+ */
+static int * const aplog_module_index;
+#endif /* __cplusplus */
+
+/**
+ * APLOG_MODULE_INDEX contains the module_index of the current module if
+ * it has been set via the ::APLOG_USE_MODULE or ::AP_DECLARE_MODULE macro.
+ * Otherwise it contains ::APLOG_NO_MODULE (for example in unmodified httpd
+ * 2.2 modules).
+ *
+ * If ::APLOG_MARK is used in ap_log_error() and related functions,
+ * ::APLOG_MODULE_INDEX will be passed as module_index. In cases where
+ * ::APLOG_MARK cannot be used, ::APLOG_MODULE_INDEX should normally be passed
+ * as module_index.
+ *
+ * @see APLOG_MARK
+ * @see ap_log_error
+ */
+#ifdef __cplusplus
+#define APLOG_MODULE_INDEX (*aplog_module_index)
+#else /* __cplusplus */
+#define APLOG_MODULE_INDEX \
+ (aplog_module_index ? *aplog_module_index : APLOG_NO_MODULE)
+#endif /* __cplusplus */
+
+/**
+ * APLOG_MAX_LOGLEVEL can be defined to remove logging above some
+ * specified level at compile time.
+ *
+ * This requires a C99 compiler.
+ */
+#ifdef DOXYGEN
+#define APLOG_MAX_LOGLEVEL
+#endif
+#ifndef APLOG_MAX_LOGLEVEL
+#define APLOG_MODULE_IS_LEVEL(s,module_index,level) \
+ ( (((level)&APLOG_LEVELMASK) <= APLOG_NOTICE) || \
+ (s == NULL) || \
+ (ap_get_server_module_loglevel(s, module_index) \
+ >= ((level)&APLOG_LEVELMASK) ) )
+#define APLOG_C_MODULE_IS_LEVEL(c,module_index,level) \
+ ( (((level)&APLOG_LEVELMASK) <= APLOG_NOTICE) || \
+ (ap_get_conn_module_loglevel(c, module_index) \
+ >= ((level)&APLOG_LEVELMASK) ) )
+#define APLOG_CS_MODULE_IS_LEVEL(c,s,module_index,level) \
+ ( (((level)&APLOG_LEVELMASK) <= APLOG_NOTICE) || \
+ (ap_get_conn_server_module_loglevel(c, s, module_index) \
+ >= ((level)&APLOG_LEVELMASK) ) )
+#define APLOG_R_MODULE_IS_LEVEL(r,module_index,level) \
+ ( (((level)&APLOG_LEVELMASK) <= APLOG_NOTICE) || \
+ (ap_get_request_module_loglevel(r, module_index) \
+ >= ((level)&APLOG_LEVELMASK) ) )
+#else
+#define APLOG_MODULE_IS_LEVEL(s,module_index,level) \
+ ( (((level)&APLOG_LEVELMASK) <= APLOG_MAX_LOGLEVEL) && \
+ ( (((level)&APLOG_LEVELMASK) <= APLOG_NOTICE) || \
+ (s == NULL) || \
+ (ap_get_server_module_loglevel(s, module_index) \
+ >= ((level)&APLOG_LEVELMASK) ) ) )
+#define APLOG_CS_MODULE_IS_LEVEL(c,s,module_index,level) \
+ ( (((level)&APLOG_LEVELMASK) <= APLOG_MAX_LOGLEVEL) && \
+ ( (((level)&APLOG_LEVELMASK) <= APLOG_NOTICE) || \
+ (ap_get_conn_server_module_loglevel(c, s, module_index) \
+ >= ((level)&APLOG_LEVELMASK) ) ) )
+#define APLOG_C_MODULE_IS_LEVEL(c,module_index,level) \
+ ( (((level)&APLOG_LEVELMASK) <= APLOG_MAX_LOGLEVEL) && \
+ ( (((level)&APLOG_LEVELMASK) <= APLOG_NOTICE) || \
+ (ap_get_conn_module_loglevel(c, module_index) \
+ >= ((level)&APLOG_LEVELMASK) ) ) )
+#define APLOG_R_MODULE_IS_LEVEL(r,module_index,level) \
+ ( (((level)&APLOG_LEVELMASK) <= APLOG_MAX_LOGLEVEL) && \
+ ( (((level)&APLOG_LEVELMASK) <= APLOG_NOTICE) || \
+ (ap_get_request_module_loglevel(r, module_index) \
+ >= ((level)&APLOG_LEVELMASK) ) ) )
+#endif
+
+#define APLOG_IS_LEVEL(s,level) \
+ APLOG_MODULE_IS_LEVEL(s,APLOG_MODULE_INDEX,level)
+#define APLOG_C_IS_LEVEL(c,level) \
+ APLOG_C_MODULE_IS_LEVEL(c,APLOG_MODULE_INDEX,level)
+#define APLOG_CS_IS_LEVEL(c,s,level) \
+ APLOG_CS_MODULE_IS_LEVEL(c,s,APLOG_MODULE_INDEX,level)
+#define APLOG_R_IS_LEVEL(r,level) \
+ APLOG_R_MODULE_IS_LEVEL(r,APLOG_MODULE_INDEX,level)
+
+
+#define APLOGinfo(s) APLOG_IS_LEVEL(s,APLOG_INFO)
+#define APLOGdebug(s) APLOG_IS_LEVEL(s,APLOG_DEBUG)
+#define APLOGtrace1(s) APLOG_IS_LEVEL(s,APLOG_TRACE1)
+#define APLOGtrace2(s) APLOG_IS_LEVEL(s,APLOG_TRACE2)
+#define APLOGtrace3(s) APLOG_IS_LEVEL(s,APLOG_TRACE3)
+#define APLOGtrace4(s) APLOG_IS_LEVEL(s,APLOG_TRACE4)
+#define APLOGtrace5(s) APLOG_IS_LEVEL(s,APLOG_TRACE5)
+#define APLOGtrace6(s) APLOG_IS_LEVEL(s,APLOG_TRACE6)
+#define APLOGtrace7(s) APLOG_IS_LEVEL(s,APLOG_TRACE7)
+#define APLOGtrace8(s) APLOG_IS_LEVEL(s,APLOG_TRACE8)
+
+#define APLOGrinfo(r) APLOG_R_IS_LEVEL(r,APLOG_INFO)
+#define APLOGrdebug(r) APLOG_R_IS_LEVEL(r,APLOG_DEBUG)
+#define APLOGrtrace1(r) APLOG_R_IS_LEVEL(r,APLOG_TRACE1)
+#define APLOGrtrace2(r) APLOG_R_IS_LEVEL(r,APLOG_TRACE2)
+#define APLOGrtrace3(r) APLOG_R_IS_LEVEL(r,APLOG_TRACE3)
+#define APLOGrtrace4(r) APLOG_R_IS_LEVEL(r,APLOG_TRACE4)
+#define APLOGrtrace5(r) APLOG_R_IS_LEVEL(r,APLOG_TRACE5)
+#define APLOGrtrace6(r) APLOG_R_IS_LEVEL(r,APLOG_TRACE6)
+#define APLOGrtrace7(r) APLOG_R_IS_LEVEL(r,APLOG_TRACE7)
+#define APLOGrtrace8(r) APLOG_R_IS_LEVEL(r,APLOG_TRACE8)
+
+#define APLOGcinfo(c) APLOG_C_IS_LEVEL(c,APLOG_INFO)
+#define APLOGcdebug(c) APLOG_C_IS_LEVEL(c,APLOG_DEBUG)
+#define APLOGctrace1(c) APLOG_C_IS_LEVEL(c,APLOG_TRACE1)
+#define APLOGctrace2(c) APLOG_C_IS_LEVEL(c,APLOG_TRACE2)
+#define APLOGctrace3(c) APLOG_C_IS_LEVEL(c,APLOG_TRACE3)
+#define APLOGctrace4(c) APLOG_C_IS_LEVEL(c,APLOG_TRACE4)
+#define APLOGctrace5(c) APLOG_C_IS_LEVEL(c,APLOG_TRACE5)
+#define APLOGctrace6(c) APLOG_C_IS_LEVEL(c,APLOG_TRACE6)
+#define APLOGctrace7(c) APLOG_C_IS_LEVEL(c,APLOG_TRACE7)
+#define APLOGctrace8(c) APLOG_C_IS_LEVEL(c,APLOG_TRACE8)
+
+AP_DECLARE_DATA extern int ap_default_loglevel;
+
+/**
+ * APLOG_MARK is a convenience macro for use as the first three parameters in
+ * ap_log_error() and related functions, i.e. file, line, and module_index.
+ *
+ * The module_index parameter was introduced in version 2.3.6. Before that
+ * version, APLOG_MARK only replaced the file and line parameters.
+ * This means that APLOG_MARK can be used with ap_log_*error in all versions
+ * of Apache httpd.
+ *
+ * @see APLOG_MODULE_INDEX
+ * @see ap_log_error
+ * @see ap_log_cerror
+ * @see ap_log_rerror
+ * @see ap_log_cserror
+ */
+#define APLOG_MARK __FILE__,__LINE__,APLOG_MODULE_INDEX
+
+/**
+ * Set up for logging to stderr.
+ * @param p The pool to allocate out of
+ */
+AP_DECLARE(void) ap_open_stderr_log(apr_pool_t *p);
+
+/**
+ * Replace logging to stderr with logging to the given file.
+ * @param p The pool to allocate out of
+ * @param file Name of the file to log stderr output
+ */
+AP_DECLARE(apr_status_t) ap_replace_stderr_log(apr_pool_t *p,
+ const char *file);
+
+/**
+ * Open the error log and replace stderr with it.
+ * @param pconf Not used
+ * @param plog The pool to allocate the logs from
+ * @param ptemp Pool used for temporary allocations
+ * @param s_main The main server
+ * @note ap_open_logs isn't expected to be used by modules, it is
+ * an internal core function
+ */
+int ap_open_logs(apr_pool_t *pconf, apr_pool_t *plog,
+ apr_pool_t *ptemp, server_rec *s_main);
+
+/**
+ * Perform special processing for piped loggers in MPM child
+ * processes.
+ * @param p Not used
+ * @param s Not used
+ * @note ap_logs_child_init is not for use by modules; it is an
+ * internal core function
+ */
+void ap_logs_child_init(apr_pool_t *p, server_rec *s);
+
+/*
+ * The primary logging functions, ap_log_error, ap_log_rerror, ap_log_cerror,
+ * and ap_log_perror use a printf style format string to build the log message.
+ * It is VERY IMPORTANT that you not include any raw data from the network,
+ * such as the request-URI or request header fields, within the format
+ * string. Doing so makes the server vulnerable to a denial-of-service
+ * attack and other messy behavior. Instead, use a simple format string
+ * like "%s", followed by the string containing the untrusted data.
+ */
+
+/**
+ * ap_log_error() - log messages which are not related to a particular
+ * request or connection. This uses a printf-like format to log messages
+ * to the error_log.
+ * @param file The file in which this function is called
+ * @param line The line number on which this function is called
+ * @param module_index The module_index of the module generating this message
+ * @param level The level of this error message
+ * @param status The status code from the previous command
+ * @param s The server on which we are logging
+ * @param fmt The format string
+ * @param ... The arguments to use to fill out fmt.
+ * @note ap_log_error is implemented as a macro
+ * @note Use APLOG_MARK to fill out file and line
+ * @note If a request_rec is available, use that with ap_log_rerror()
+ * in preference to calling this function. Otherwise, if a conn_rec is
+ * available, use that with ap_log_cerror() in preference to calling
+ * this function.
+ * @warning It is VERY IMPORTANT that you not include any raw data from
+ * the network, such as the request-URI or request header fields, within
+ * the format string. Doing so makes the server vulnerable to a
+ * denial-of-service attack and other messy behavior. Instead, use a
+ * simple format string like "%s", followed by the string containing the
+ * untrusted data.
+ */
+#ifdef DOXYGEN
+AP_DECLARE(void) ap_log_error(const char *file, int line, int module_index,
+ int level, apr_status_t status,
+ const server_rec *s, const char *fmt, ...);
+#else
+#ifdef AP_HAVE_C99
+/* need additional step to expand APLOG_MARK first */
+#define ap_log_error(...) ap_log_error__(__VA_ARGS__)
+/* need server_rec *sr = ... for the case if s is verbatim NULL */
+#define ap_log_error__(file, line, mi, level, status, s, ...) \
+ do { const server_rec *sr__ = s; if (APLOG_MODULE_IS_LEVEL(sr__, mi, level)) \
+ ap_log_error_(file, line, mi, level, status, sr__, __VA_ARGS__); \
+ } while(0)
+#else
+#define ap_log_error ap_log_error_
+#endif
+AP_DECLARE(void) ap_log_error_(const char *file, int line, int module_index,
+ int level, apr_status_t status,
+ const server_rec *s, const char *fmt, ...)
+ __attribute__((format(printf,7,8)));
+#endif
+
+/**
+ * ap_log_perror() - log messages which are not related to a particular
+ * request, connection, or virtual server. This uses a printf-like
+ * format to log messages to the error_log.
+ * @param file The file in which this function is called
+ * @param line The line number on which this function is called
+ * @param module_index ignored dummy value for use by APLOG_MARK
+ * @param level The level of this error message
+ * @param status The status code from the previous command
+ * @param p The pool which we are logging for
+ * @param fmt The format string
+ * @param ... The arguments to use to fill out fmt.
+ * @note ap_log_perror is implemented as a macro
+ * @note Use APLOG_MARK to fill out file, line, and module_index
+ * @warning It is VERY IMPORTANT that you not include any raw data from
+ * the network, such as the request-URI or request header fields, within
+ * the format string. Doing so makes the server vulnerable to a
+ * denial-of-service attack and other messy behavior. Instead, use a
+ * simple format string like "%s", followed by the string containing the
+ * untrusted data.
+ */
+#ifdef DOXYGEN
+AP_DECLARE(void) ap_log_perror(const char *file, int line, int module_index,
+ int level, apr_status_t status, apr_pool_t *p,
+ const char *fmt, ...);
+#else
+#if defined(AP_HAVE_C99) && defined(APLOG_MAX_LOGLEVEL)
+/* need additional step to expand APLOG_MARK first */
+#define ap_log_perror(...) ap_log_perror__(__VA_ARGS__)
+#define ap_log_perror__(file, line, mi, level, status, p, ...) \
+ do { if ((level) <= APLOG_MAX_LOGLEVEL ) \
+ ap_log_perror_(file, line, mi, level, status, p, \
+ __VA_ARGS__); } while(0)
+#else
+#define ap_log_perror ap_log_perror_
+#endif
+AP_DECLARE(void) ap_log_perror_(const char *file, int line, int module_index,
+ int level, apr_status_t status, apr_pool_t *p,
+ const char *fmt, ...)
+ __attribute__((format(printf,7,8)));
+#endif
+
+/**
+ * ap_log_rerror() - log messages which are related to a particular
+ * request. This uses a printf-like format to log messages to the
+ * error_log.
+ * @param file The file in which this function is called
+ * @param line The line number on which this function is called
+ * @param module_index The module_index of the module generating this message
+ * @param level The level of this error message
+ * @param status The status code from the previous command
+ * @param r The request which we are logging for
+ * @param fmt The format string
+ * @param ... The arguments to use to fill out fmt.
+ * @note ap_log_rerror is implemented as a macro
+ * @note Use APLOG_MARK to fill out file, line, and module_index
+ * @warning It is VERY IMPORTANT that you not include any raw data from
+ * the network, such as the request-URI or request header fields, within
+ * the format string. Doing so makes the server vulnerable to a
+ * denial-of-service attack and other messy behavior. Instead, use a
+ * simple format string like "%s", followed by the string containing the
+ * untrusted data.
+ */
+#ifdef DOXYGEN
+AP_DECLARE(void) ap_log_rerror(const char *file, int line, int module_index,
+ int level, apr_status_t status,
+ const request_rec *r, const char *fmt, ...);
+#else
+#ifdef AP_HAVE_C99
+/* need additional step to expand APLOG_MARK first */
+#define ap_log_rerror(...) ap_log_rerror__(__VA_ARGS__)
+#define ap_log_rerror__(file, line, mi, level, status, r, ...) \
+ do { if (APLOG_R_MODULE_IS_LEVEL(r, mi, level)) \
+ ap_log_rerror_(file, line, mi, level, status, r, __VA_ARGS__); \
+ } while(0)
+#else
+#define ap_log_rerror ap_log_rerror_
+#endif
+AP_DECLARE(void) ap_log_rerror_(const char *file, int line, int module_index,
+ int level, apr_status_t status,
+ const request_rec *r, const char *fmt, ...)
+ __attribute__((format(printf,7,8)));
+#endif
+
+/**
+ * ap_log_cerror() - log messages which are related to a particular
+ * connection. This uses a printf-like format to log messages to the
+ * error_log.
+ * @param file The file in which this function is called
+ * @param line The line number on which this function is called
+ * @param level The level of this error message
+ * @param module_index The module_index of the module generating this message
+ * @param status The status code from the previous command
+ * @param c The connection which we are logging for
+ * @param fmt The format string
+ * @param ... The arguments to use to fill out fmt.
+ * @note ap_log_cerror is implemented as a macro
+ * @note Use APLOG_MARK to fill out file, line, and module_index
+ * @note If a request_rec is available, use that with ap_log_rerror()
+ * in preference to calling this function.
+ * @warning It is VERY IMPORTANT that you not include any raw data from
+ * the network, such as the request-URI or request header fields, within
+ * the format string. Doing so makes the server vulnerable to a
+ * denial-of-service attack and other messy behavior. Instead, use a
+ * simple format string like "%s", followed by the string containing the
+ * untrusted data.
+ */
+#ifdef DOXYGEN
+AP_DECLARE(void) ap_log_cerror(const char *file, int line, int module_index,
+ int level, apr_status_t status,
+ const conn_rec *c, const char *fmt, ...);
+#else
+#ifdef AP_HAVE_C99
+/* need additional step to expand APLOG_MARK first */
+#define ap_log_cerror(...) ap_log_cerror__(__VA_ARGS__)
+#define ap_log_cerror__(file, line, mi, level, status, c, ...) \
+ do { if (APLOG_C_MODULE_IS_LEVEL(c, mi, level)) \
+ ap_log_cerror_(file, line, mi, level, status, c, __VA_ARGS__); \
+ } while(0)
+#else
+#define ap_log_cerror ap_log_cerror_
+#endif
+AP_DECLARE(void) ap_log_cerror_(const char *file, int line, int module_index,
+ int level, apr_status_t status,
+ const conn_rec *c, const char *fmt, ...)
+ __attribute__((format(printf,7,8)));
+#endif
+
+/**
+ * ap_log_cserror() - log messages which are related to a particular
+ * connection and to a vhost other than c->base_server. This uses a
+ * printf-like format to log messages to the error_log.
+ * @param file The file in which this function is called
+ * @param line The line number on which this function is called
+ * @param level The level of this error message
+ * @param module_index The module_index of the module generating this message
+ * @param status The status code from the previous command
+ * @param c The connection which we are logging for
+ * @param s The server which we are logging for
+ * @param fmt The format string
+ * @param ... The arguments to use to fill out fmt.
+ * @note ap_log_cserror is implemented as a macro
+ * @note Use APLOG_MARK to fill out file, line, and module_index
+ * @note If a request_rec is available, use that with ap_log_rerror()
+ * in preference to calling this function. This function is mainly useful for
+ * modules like mod_ssl to use before the request_rec is created.
+ * @warning It is VERY IMPORTANT that you not include any raw data from
+ * the network, such as the request-URI or request header fields, within
+ * the format string. Doing so makes the server vulnerable to a
+ * denial-of-service attack and other messy behavior. Instead, use a
+ * simple format string like "%s", followed by the string containing the
+ * untrusted data.
+ */
+#ifdef DOXYGEN
+AP_DECLARE(void) ap_log_cserror(const char *file, int line, int module_index,
+ int level, apr_status_t status,
+ const conn_rec *c, const server_rec *s,
+ const char *fmt, ...);
+#else
+#ifdef AP_HAVE_C99
+/* need additional step to expand APLOG_MARK first */
+#define ap_log_cserror(...) ap_log_cserror__(__VA_ARGS__)
+#define ap_log_cserror__(file, line, mi, level, status, c, s, ...) \
+ do { if (APLOG_CS_MODULE_IS_LEVEL(c, s, mi, level)) \
+ ap_log_cserror_(file, line, mi, level, status, c, s, \
+ __VA_ARGS__); \
+ } while(0)
+#else
+#define ap_log_cserror ap_log_cserror_
+#endif
+AP_DECLARE(void) ap_log_cserror_(const char *file, int line, int module_index,
+ int level, apr_status_t status,
+ const conn_rec *c, const server_rec *s,
+ const char *fmt, ...)
+ __attribute__((format(printf,8,9)));
+#endif
+
+/*
+ * The buffer logging functions, ap_log_data, ap_log_rdata, ap_log_cdata,
+ * and ap_log_csdata log a buffer in printable and hex format. The exact
+ * format is controlled by processing flags, described next.
+ */
+
+/**
+ * Processing flags for ap_log_data() et al
+ *
+ * AP_LOG_DATA_DEFAULT - default formatting, with printable chars and hex
+ * AP_LOG_DATA_SHOW_OFFSET - prefix each line with hex offset from the start
+ * of the buffer
+ */
+#define AP_LOG_DATA_DEFAULT 0
+#define AP_LOG_DATA_SHOW_OFFSET 1
+
+/**
+ * ap_log_data() - log buffers which are not related to a particular request
+ * or connection.
+ * @param file The file in which this function is called
+ * @param line The line number on which this function is called
+ * @param module_index The module_index of the module logging this buffer
+ * @param level The log level
+ * @param s The server on which we are logging
+ * @param label A label for the buffer, to be logged preceding the buffer
+ * @param data The buffer to be logged
+ * @param len The length of the buffer
+ * @param flags Special processing flags like AP_LOG_DATA_SHOW_OFFSET
+ * @note ap_log_data is implemented as a macro.
+ * @note Use APLOG_MARK to fill out file, line, and module_index
+ * @note If a request_rec is available, use that with ap_log_rdata()
+ * in preference to calling this function. Otherwise, if a conn_rec is
+ * available, use that with ap_log_cdata() in preference to calling
+ * this function.
+ */
+#ifdef DOXYGEN
+AP_DECLARE(void) ap_log_data(const char *file, int line, int module_index,
+ int level, const server_rec *s, const char *label,
+ const void *data, apr_size_t len, unsigned int flags);
+#else
+#ifdef AP_HAVE_C99
+/* need additional step to expand APLOG_MARK first */
+#define ap_log_data(...) ap_log_data__(__VA_ARGS__)
+/* need server_rec *sr = ... for the case if s is verbatim NULL */
+#define ap_log_data__(file, line, mi, level, s, ...) \
+ do { const server_rec *sr__ = s; if (APLOG_MODULE_IS_LEVEL(sr__, mi, level)) \
+ ap_log_data_(file, line, mi, level, sr__, __VA_ARGS__); \
+ } while(0)
+#else
+#define ap_log_data ap_log_data_
+#endif
+AP_DECLARE(void) ap_log_data_(const char *file, int line, int module_index,
+ int level, const server_rec *s, const char *label,
+ const void *data, apr_size_t len, unsigned int flags);
+#endif
+
+/**
+ * ap_log_rdata() - log buffers which are related to a particular request.
+ * @param file The file in which this function is called
+ * @param line The line number on which this function is called
+ * @param module_index The module_index of the module logging this buffer
+ * @param level The log level
+ * @param r The request which we are logging for
+ * @param label A label for the buffer, to be logged preceding the buffer
+ * @param data The buffer to be logged
+ * @param len The length of the buffer
+ * @param flags Special processing flags like AP_LOG_DATA_SHOW_OFFSET
+ * @note ap_log_rdata is implemented as a macro.
+ * @note Use APLOG_MARK to fill out file, line, and module_index
+ * @note If a request_rec is available, use that with ap_log_rerror()
+ * in preference to calling this function. Otherwise, if a conn_rec is
+ * available, use that with ap_log_cerror() in preference to calling
+ * this function.
+ */
+#ifdef DOXYGEN
+AP_DECLARE(void) ap_log_rdata(const char *file, int line, int module_index,
+ int level, const request_rec *r, const char *label,
+ const void *data, apr_size_t len, unsigned int flags);
+#else
+#ifdef AP_HAVE_C99
+/* need additional step to expand APLOG_MARK first */
+#define ap_log_rdata(...) ap_log_rdata__(__VA_ARGS__)
+#define ap_log_rdata__(file, line, mi, level, r, ...) \
+ do { if (APLOG_R_MODULE_IS_LEVEL(r, mi, level)) \
+ ap_log_rdata_(file, line, mi, level, r, __VA_ARGS__); \
+ } while(0)
+#else
+#define ap_log_rdata ap_log_rdata_
+#endif
+AP_DECLARE(void) ap_log_rdata_(const char *file, int line, int module_index,
+ int level, const request_rec *r, const char *label,
+ const void *data, apr_size_t len, unsigned int flags);
+#endif
+
+/**
+ * ap_log_cdata() - log buffers which are related to a particular connection.
+ * @param file The file in which this function is called
+ * @param line The line number on which this function is called
+ * @param module_index The module_index of the module logging this buffer
+ * @param level The log level
+ * @param c The connection which we are logging for
+ * @param label A label for the buffer, to be logged preceding the buffer
+ * @param data The buffer to be logged
+ * @param len The length of the buffer
+ * @param flags Special processing flags like AP_LOG_DATA_SHOW_OFFSET
+ * @note ap_log_cdata is implemented as a macro
+ * @note Use APLOG_MARK to fill out file, line, and module_index
+ * @note If a request_rec is available, use that with ap_log_rerror()
+ * in preference to calling this function. Otherwise, if a conn_rec is
+ * available, use that with ap_log_cerror() in preference to calling
+ * this function.
+ */
+#ifdef DOXYGEN
+AP_DECLARE(void) ap_log_cdata(const char *file, int line, int module_index,
+ int level, const conn_rec *c, const char *label,
+ const void *data, apr_size_t len, unsigned int flags);
+#else
+#ifdef AP_HAVE_C99
+/* need additional step to expand APLOG_MARK first */
+#define ap_log_cdata(...) ap_log_cdata__(__VA_ARGS__)
+#define ap_log_cdata__(file, line, mi, level, c, ...) \
+ do { if (APLOG_C_MODULE_IS_LEVEL(c, mi, level)) \
+ ap_log_cdata_(file, line, mi, level, c, __VA_ARGS__); \
+ } while(0)
+#else
+#define ap_log_cdata ap_log_cdata_
+#endif
+AP_DECLARE(void) ap_log_cdata_(const char *file, int line, int module_index,
+ int level, const conn_rec *c, const char *label,
+ const void *data, apr_size_t len, unsigned int flags);
+#endif
+
+/**
+ * ap_log_csdata() - log buffers which are related to a particular connection
+ * and to a vhost other than c->base_server.
+ * @param file The file in which this function is called
+ * @param line The line number on which this function is called
+ * @param module_index The module_index of the module logging this buffer
+ * @param level The log level
+ * @param c The connection which we are logging for
+ * @param s The server which we are logging for
+ * @param label A label for the buffer, to be logged preceding the buffer
+ * @param data The buffer to be logged
+ * @param len The length of the buffer
+ * @param flags Special processing flags like AP_LOG_DATA_SHOW_OFFSET
+ * @note ap_log_csdata is implemented as a macro
+ * @note Use APLOG_MARK to fill out file, line, and module_index
+ * @note If a request_rec is available, use that with ap_log_rerror()
+ * in preference to calling this function. Otherwise, if a conn_rec is
+ * available, use that with ap_log_cerror() in preference to calling
+ * this function.
+ */
+#ifdef DOXYGEN
+AP_DECLARE(void) ap_log_csdata(const char *file, int line, int module_index,
+ int level, const conn_rec *c, const server_rec *s,
+ const char *label, const void *data,
+ apr_size_t len, unsigned int flags);
+#else
+#ifdef AP_HAVE_C99
+/* need additional step to expand APLOG_MARK first */
+#define ap_log_csdata(...) ap_log_csdata__(__VA_ARGS__)
+#define ap_log_csdata__(file, line, mi, level, c, s, ...) \
+ do { if (APLOG_CS_MODULE_IS_LEVEL(c, s, mi, level)) \
+ ap_log_csdata_(file, line, mi, level, c, s, __VA_ARGS__); \
+ } while(0)
+#else
+#define ap_log_cdata ap_log_cdata_
+#endif
+AP_DECLARE(void) ap_log_csdata_(const char *file, int line, int module_index,
+ int level, const conn_rec *c, const server_rec *s,
+ const char *label, const void *data,
+ apr_size_t len, unsigned int flags);
+#endif
+
+/**
+ * Convert stderr to the error log
+ * @param s The current server
+ */
+AP_DECLARE(void) ap_error_log2stderr(server_rec *s);
+
+/**
+ * Log the command line used to start the server.
+ * @param p The pool to use for logging
+ * @param s The server_rec whose process's command line we want to log.
+ * The command line is logged to that server's error log.
+ */
+AP_DECLARE(void) ap_log_command_line(apr_pool_t *p, server_rec *s);
+
+/**
+ * Log common (various) MPM shared data at startup.
+ * @param s The server_rec of the error log we want to log to.
+ * Misc commonly logged data is logged to that server's error log.
+ */
+AP_DECLARE(void) ap_log_mpm_common(server_rec *s);
+
+/**
+ * Log the current pid of the parent process
+ * @param p The pool to use for processing
+ * @param fname The name of the file to log to. If the filename is not
+ * absolute then it is assumed to be relative to ServerRoot.
+ */
+AP_DECLARE(void) ap_log_pid(apr_pool_t *p, const char *fname);
+
+/**
+ * Remove the pidfile.
+ * @param p The pool to use for processing
+ * @param fname The name of the pid file to remove. If the filename is not
+ * absolute then it is assumed to be relative to ServerRoot.
+ */
+AP_DECLARE(void) ap_remove_pid(apr_pool_t *p, const char *fname);
+
+/**
+ * Retrieve the pid from a pidfile.
+ * @param p The pool to use for processing
+ * @param filename The name of the file containing the pid. If the filename is not
+ * absolute then it is assumed to be relative to ServerRoot.
+ * @param mypid Pointer to pid_t (valid only if return APR_SUCCESS)
+ */
+AP_DECLARE(apr_status_t) ap_read_pid(apr_pool_t *p, const char *filename, pid_t *mypid);
+
+/** @see piped_log */
+typedef struct piped_log piped_log;
+
+/**
+ * Open the piped log process
+ * @param p The pool to allocate out of
+ * @param program The program to run in the logging process
+ * @return The piped log structure
+ * @note The log program is invoked as @p APR_PROGRAM_ENV,
+ * @see ap_open_piped_log_ex to modify this behavior
+ */
+AP_DECLARE(piped_log *) ap_open_piped_log(apr_pool_t *p, const char *program);
+
+/**
+ * Open the piped log process specifying the execution choice for program
+ * @param p The pool to allocate out of
+ * @param program The program to run in the logging process
+ * @param cmdtype How to invoke program, e.g. APR_PROGRAM, APR_SHELLCMD_ENV, etc
+ * @return The piped log structure
+ */
+AP_DECLARE(piped_log *) ap_open_piped_log_ex(apr_pool_t *p,
+ const char *program,
+ apr_cmdtype_e cmdtype);
+
+/**
+ * Close the piped log and kill the logging process
+ * @param pl The piped log structure
+ */
+AP_DECLARE(void) ap_close_piped_log(piped_log *pl);
+
+/**
+ * A function to return the read side of the piped log pipe
+ * @param pl The piped log structure
+ * @return The native file descriptor
+ */
+AP_DECLARE(apr_file_t *) ap_piped_log_read_fd(piped_log *pl);
+
+/**
+ * A function to return the write side of the piped log pipe
+ * @param pl The piped log structure
+ * @return The native file descriptor
+ */
+AP_DECLARE(apr_file_t *) ap_piped_log_write_fd(piped_log *pl);
+
+/**
+ * hook method to generate unique id for connection or request
+ * @ingroup hooks
+ * @param c the conn_rec of the connections
+ * @param r the request_req (may be NULL)
+ * @param id the place where to store the unique id
+ * @return OK or DECLINE
+ */
+AP_DECLARE_HOOK(int, generate_log_id,
+ (const conn_rec *c, const request_rec *r, const char **id))
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !APACHE_HTTP_LOG_H */
+/** @} */
diff --git a/include/http_main.h b/include/http_main.h
new file mode 100644
index 0000000..fa1ce85
--- /dev/null
+++ b/include/http_main.h
@@ -0,0 +1,88 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file http_main.h
+ * @brief Command line options
+ *
+ * @defgroup APACHE_CORE_MAIN Command line options
+ * @ingroup APACHE_CORE
+ * @{
+ */
+
+#ifndef APACHE_HTTP_MAIN_H
+#define APACHE_HTTP_MAIN_H
+
+#include "httpd.h"
+#include "apr_optional.h"
+
+/** AP_SERVER_BASEARGS is the command argument list parsed by http_main.c
+ * in apr_getopt() format. Use this for default'ing args that the MPM
+ * can safely ignore and pass on from its rewrite_args() handler.
+ */
+#define AP_SERVER_BASEARGS "C:c:D:d:E:e:f:vVlLtTSMh?X"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** The name of the Apache executable */
+AP_DECLARE_DATA extern const char *ap_server_argv0;
+/** The global server's ServerRoot */
+AP_DECLARE_DATA extern const char *ap_server_root;
+/** The global server's DefaultRuntimeDir
+ * This is not usable directly in the general case; use
+ * ap_runtime_dir_relative() instead.
+ */
+AP_DECLARE_DATA extern const char *ap_runtime_dir;
+/** The global server's server_rec */
+AP_DECLARE_DATA extern server_rec *ap_server_conf;
+/** global pool, for access prior to creation of server_rec */
+AP_DECLARE_DATA extern apr_pool_t *ap_pglobal;
+/** state of the server (startup, exiting, ...) */
+AP_DECLARE_DATA extern int ap_main_state;
+/** run mode (normal, config test, config dump, ...) */
+AP_DECLARE_DATA extern int ap_run_mode;
+/** run mode (normal, config test, config dump, ...) */
+AP_DECLARE_DATA extern int ap_config_generation;
+
+/* for -C, -c and -D switches */
+/** An array of all -C directives. These are processed before the server's
+ * config file */
+AP_DECLARE_DATA extern apr_array_header_t *ap_server_pre_read_config;
+/** An array of all -c directives. These are processed after the server's
+ * config file */
+AP_DECLARE_DATA extern apr_array_header_t *ap_server_post_read_config;
+/** An array of all -D defines on the command line. This allows people to
+ * effect the server based on command line options */
+AP_DECLARE_DATA extern apr_array_header_t *ap_server_config_defines;
+/** Available integer for using the -T switch */
+AP_DECLARE_DATA extern int ap_document_root_check;
+
+/**
+ * An optional function to send signal to server on presence of '-k'
+ * command line argument.
+ * @param status The exit status after sending signal
+ * @param pool Memory pool to allocate from
+ */
+APR_DECLARE_OPTIONAL_FN(int, ap_signal_server, (int *status, apr_pool_t *pool));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !APACHE_HTTP_MAIN_H */
+/** @} */
diff --git a/include/http_protocol.h b/include/http_protocol.h
new file mode 100644
index 0000000..11c7b2d
--- /dev/null
+++ b/include/http_protocol.h
@@ -0,0 +1,1023 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file http_protocol.h
+ * @brief HTTP protocol handling
+ *
+ * @defgroup APACHE_CORE_PROTO HTTP Protocol Handling
+ * @ingroup APACHE_CORE
+ * @{
+ */
+
+#ifndef APACHE_HTTP_PROTOCOL_H
+#define APACHE_HTTP_PROTOCOL_H
+
+#include "httpd.h"
+#include "apr_portable.h"
+#include "apr_mmap.h"
+#include "apr_buckets.h"
+#include "util_filter.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * This hook allows modules to insert filters for the current error response
+ * @param r the current request
+ * @ingroup hooks
+ */
+AP_DECLARE_HOOK(void,insert_error_filter,(request_rec *r))
+
+/** This is an optimization. We keep a record of the filter_rec that
+ * stores the old_write filter, so that we can avoid strcmp's later.
+ */
+AP_DECLARE_DATA extern ap_filter_rec_t *ap_old_write_func;
+
+/*
+ * Prototypes for routines which either talk directly back to the user,
+ * or control the ones that eventually do.
+ */
+
+/**
+ * Read a request and fill in the fields.
+ * @param c The current connection
+ * @return The new request_rec
+ */
+request_rec *ap_read_request(conn_rec *c);
+
+/**
+ * Read the mime-encoded headers.
+ * @param r The current request
+ */
+AP_DECLARE(void) ap_get_mime_headers(request_rec *r);
+
+/**
+ * Optimized version of ap_get_mime_headers() that requires a
+ * temporary brigade to work with
+ * @param r The current request
+ * @param bb temp brigade
+ */
+AP_DECLARE(void) ap_get_mime_headers_core(request_rec *r,
+ apr_bucket_brigade *bb);
+
+/* Finish up stuff after a request */
+
+/**
+ * Called at completion of sending the response. It sends the terminating
+ * protocol information.
+ * @param r The current request
+ */
+AP_DECLARE(void) ap_finalize_request_protocol(request_rec *r);
+
+/**
+ * Send error back to client.
+ * @param r The current request
+ * @param recursive_error last arg indicates error status in case we get
+ * an error in the process of trying to deal with an ErrorDocument
+ * to handle some other error. In that case, we print the default
+ * report for the first thing that went wrong, and more briefly report
+ * on the problem with the ErrorDocument.
+ */
+AP_DECLARE(void) ap_send_error_response(request_rec *r, int recursive_error);
+
+/* Set last modified header line from the lastmod date of the associated file.
+ * Also, set content length.
+ *
+ * May return an error status, typically HTTP_NOT_MODIFIED (that when the
+ * permit_cache argument is set to one).
+ */
+
+/**
+ * Set the content length for this request
+ * @param r The current request
+ * @param length The new content length
+ */
+AP_DECLARE(void) ap_set_content_length(request_rec *r, apr_off_t length);
+
+/**
+ * Set the keepalive status for this request
+ * @param r The current request
+ * @return 1 if keepalive can be set, 0 otherwise
+ */
+AP_DECLARE(int) ap_set_keepalive(request_rec *r);
+
+/**
+ * Return the latest rational time from a request/mtime pair. Mtime is
+ * returned unless it's in the future, in which case we return the current time.
+ * @param r The current request
+ * @param mtime The last modified time
+ * @return the latest rational time.
+ */
+AP_DECLARE(apr_time_t) ap_rationalize_mtime(request_rec *r, apr_time_t mtime);
+
+/**
+ * Build the content-type that should be sent to the client from the
+ * content-type specified. The following rules are followed:
+ * - if type is NULL or "", return NULL (do not set content-type).
+ * - if charset adding is disabled, stop processing and return type.
+ * - then, if there are no parameters on type, add the default charset
+ * - return type
+ * @param r The current request
+ * @param type The content type
+ * @return The content-type
+ */
+AP_DECLARE(const char *) ap_make_content_type(request_rec *r,
+ const char *type);
+
+/**
+ * Precompile metadata structures used by ap_make_content_type()
+ * @param pool The pool to use for allocations
+ */
+AP_DECLARE(void) ap_setup_make_content_type(apr_pool_t *pool);
+
+/**
+ * Construct an entity tag from the resource information. If it's a real
+ * file, build in some of the file characteristics.
+ * @param r The current request
+ * @param force_weak Force the entity tag to be weak - it could be modified
+ * again in as short an interval.
+ * @return The entity tag
+ */
+AP_DECLARE(char *) ap_make_etag(request_rec *r, int force_weak);
+
+/**
+ * Set the E-tag outgoing header
+ * @param r The current request
+ */
+AP_DECLARE(void) ap_set_etag(request_rec *r);
+
+/**
+ * Set the last modified time for the file being sent
+ * @param r The current request
+ */
+AP_DECLARE(void) ap_set_last_modified(request_rec *r);
+
+typedef enum {
+ AP_CONDITION_NONE,
+ AP_CONDITION_NOMATCH,
+ AP_CONDITION_WEAK,
+ AP_CONDITION_STRONG
+} ap_condition_e;
+
+/**
+ * Tests conditional request rules for the If-Match header.
+ * @param r The current request
+ * @param headers The response headers to check against
+ * @return AP_CONDITION_NONE if the header is missing, AP_CONDITION_NOMATCH
+ * if the header does not match, AP_CONDITION_STRONG for a strong
+ * match. Weak matches are not permitted for the If-Match header.
+ */
+AP_DECLARE(ap_condition_e) ap_condition_if_match(request_rec *r,
+ apr_table_t *headers);
+
+/**
+ * Tests conditional request rules for the If-Unmodified-Since header.
+ * @param r The current request
+ * @param headers The response headers to check against
+ * @return AP_CONDITION_NONE if the header is missing, AP_CONDITION_NOMATCH
+ * if the header does not match, AP_CONDITION_WEAK if a weak match
+ * was present and allowed by RFC2616, AP_CONDITION_STRONG for a
+ * strong match.
+ */
+AP_DECLARE(ap_condition_e) ap_condition_if_unmodified_since(request_rec *r,
+ apr_table_t *headers);
+
+/**
+ * Tests conditional request rules for the If-None-Match header.
+ * @param r The current request
+ * @param headers The response headers to check against
+ * @return AP_CONDITION_NONE if the header is missing, AP_CONDITION_NOMATCH
+ * if the header does not match, AP_CONDITION_WEAK if a weak match
+ * was present and allowed by RFC2616, AP_CONDITION_STRONG for a
+ * strong match.
+ */
+AP_DECLARE(ap_condition_e) ap_condition_if_none_match(request_rec *r,
+ apr_table_t *headers);
+
+/**
+ * Tests conditional request rules for the If-Modified-Since header.
+ * @param r The current request
+ * @param headers The response headers to check against
+ * @return AP_CONDITION_NONE if the header is missing, AP_CONDITION_NOMATCH
+ * if the header does not match, AP_CONDITION_WEAK if a weak match
+ * was present and allowed by RFC2616, AP_CONDITION_STRONG for a
+ * strong match.
+ */
+AP_DECLARE(ap_condition_e) ap_condition_if_modified_since(request_rec *r,
+ apr_table_t *headers);
+
+/**
+ * Tests conditional request rules for the If-Range header.
+ * @param r The current request
+ * @param headers The response headers to check against
+ * @return AP_CONDITION_NONE if either the If-Range or Range header is
+ * missing, AP_CONDITION_NOMATCH if the header does not match,
+ * AP_CONDITION_STRONG for a strong match. Weak matches are not
+ * permitted for the If-Range header.
+ */
+AP_DECLARE(ap_condition_e) ap_condition_if_range(request_rec *r,
+ apr_table_t *headers);
+
+/**
+ * Implements condition GET rules for HTTP/1.1 specification. This function
+ * inspects the client headers and determines if the response fulfills
+ * the requirements specified.
+ * @param r The current request
+ * @return OK if the response fulfills the condition GET rules, some
+ * other status code otherwise
+ */
+AP_DECLARE(int) ap_meets_conditions(request_rec *r);
+
+/* Other ways to send stuff at the client. All of these keep track
+ * of bytes_sent automatically. This indirection is intended to make
+ * it a little more painless to slide things like HTTP-NG packetization
+ * underneath the main body of the code later. In the meantime, it lets
+ * us centralize a bit of accounting (bytes_sent).
+ *
+ * These also return the number of bytes written by the call.
+ * They should only be called with a timeout registered, for obvious reaasons.
+ * (Ditto the send_header stuff).
+ */
+
+/**
+ * Send an entire file to the client, using sendfile if supported by the
+ * current platform
+ * @param fd The file to send.
+ * @param r The current request
+ * @param offset Offset into the file to start sending.
+ * @param length Amount of data to send
+ * @param nbytes Amount of data actually sent
+ */
+AP_DECLARE(apr_status_t) ap_send_fd(apr_file_t *fd, request_rec *r, apr_off_t offset,
+ apr_size_t length, apr_size_t *nbytes);
+
+#if APR_HAS_MMAP
+/**
+ * Send an MMAP'ed file to the client
+ * @param mm The MMAP'ed file to send
+ * @param r The current request
+ * @param offset The offset into the MMAP to start sending
+ * @param length The amount of data to send
+ * @return The number of bytes sent
+ */
+AP_DECLARE(apr_size_t) ap_send_mmap(apr_mmap_t *mm,
+ request_rec *r,
+ apr_size_t offset,
+ apr_size_t length);
+#endif
+
+
+/**
+ * Register a new request method, and return the offset that will be
+ * associated with that method.
+ *
+ * @param p The pool to create registered method numbers from.
+ * @param methname The name of the new method to register.
+ * @return An int value representing an offset into a bitmask.
+ */
+AP_DECLARE(int) ap_method_register(apr_pool_t *p, const char *methname);
+
+/**
+ * Initialize the method_registry and allocate memory for it.
+ *
+ * @param p Pool to allocate memory for the registry from.
+ */
+AP_DECLARE(void) ap_method_registry_init(apr_pool_t *p);
+
+/**
+ * This is a convenience macro to ease with checking a mask
+ * against a method name.
+ */
+#define AP_METHOD_CHECK_ALLOWED(mask, methname) \
+ ((mask) & (AP_METHOD_BIT << ap_method_number_of((methname))))
+
+/**
+ * Create a new method list with the specified number of preallocated
+ * slots for extension methods.
+ *
+ * @param p Pointer to a pool in which the structure should be
+ * allocated.
+ * @param nelts Number of preallocated extension slots
+ * @return Pointer to the newly created structure.
+ */
+AP_DECLARE(ap_method_list_t *) ap_make_method_list(apr_pool_t *p, int nelts);
+
+
+/**
+ * Copy a method list
+ *
+ * @param dest List to copy to
+ * @param src List to copy from
+ */
+AP_DECLARE(void) ap_copy_method_list(ap_method_list_t *dest,
+ ap_method_list_t *src);
+
+/**
+ * Search for an HTTP method name in an ap_method_list_t structure, and
+ * return true if found.
+ *
+ * @param method String containing the name of the method to check.
+ * @param l Pointer to a method list, such as r->allowed_methods.
+ * @return 1 if method is in the list, otherwise 0
+ */
+AP_DECLARE(int) ap_method_in_list(ap_method_list_t *l, const char *method);
+
+/**
+ * Add an HTTP method name to an ap_method_list_t structure if it isn't
+ * already listed.
+ *
+ * @param method String containing the name of the method to check.
+ * @param l Pointer to a method list, such as r->allowed_methods.
+ * @return None.
+ */
+AP_DECLARE(void) ap_method_list_add(ap_method_list_t *l, const char *method);
+
+/**
+ * Remove an HTTP method name from an ap_method_list_t structure.
+ *
+ * @param l Pointer to a method list, such as r->allowed_methods.
+ * @param method String containing the name of the method to remove.
+ * @return None.
+ */
+AP_DECLARE(void) ap_method_list_remove(ap_method_list_t *l,
+ const char *method);
+
+/**
+ * Reset a method list to be completely empty.
+ *
+ * @param l Pointer to a method list, such as r->allowed_methods.
+ * @return None.
+ */
+AP_DECLARE(void) ap_clear_method_list(ap_method_list_t *l);
+
+/**
+ * Set the content type for this request (r->content_type).
+ * @param r The current request
+ * @param ct The new content type
+ * @warning This function must be called to set r->content_type in order
+ * for the AddOutputFilterByType directive to work correctly.
+ */
+AP_DECLARE(void) ap_set_content_type(request_rec *r, const char *ct);
+
+/**
+ * Set the Accept-Ranges header for this response
+ * @param r The current request
+ */
+AP_DECLARE(void) ap_set_accept_ranges(request_rec *r);
+
+
+/* Hmmm... could macrofy these for now, and maybe forever, though the
+ * definitions of the macros would get a whole lot hairier.
+ */
+
+/**
+ * Output one character for this request
+ * @param c the character to output
+ * @param r the current request
+ * @return The number of bytes sent
+ */
+AP_DECLARE(int) ap_rputc(int c, request_rec *r);
+
+/**
+ * Write a buffer for the current request
+ * @param buf The buffer to write
+ * @param nbyte The number of bytes to send from the buffer
+ * @param r The current request
+ * @return The number of bytes sent
+ */
+AP_DECLARE(int) ap_rwrite(const void *buf, int nbyte, request_rec *r);
+
+/**
+ * Output a string for the current request
+ * @param str The string to output
+ * @param r The current request
+ * @return The number of bytes sent
+ * @note ap_rputs may be implemented as macro or inline function
+ */
+static APR_INLINE int ap_rputs(const char *str, request_rec *r)
+{
+ return ap_rwrite(str, (int)strlen(str), r);
+}
+
+/**
+ * Write an unspecified number of strings to the request
+ * @param r The current request
+ * @param ... The strings to write
+ * @return The number of bytes sent
+ */
+AP_DECLARE_NONSTD(int) ap_rvputs(request_rec *r,...)
+ AP_FN_ATTR_SENTINEL;
+
+/**
+ * Output data to the client in a printf format
+ * @param r The current request
+ * @param fmt The format string
+ * @param vlist The arguments to use to fill out the format string
+ * @return The number of bytes sent
+ */
+AP_DECLARE(int) ap_vrprintf(request_rec *r, const char *fmt, va_list vlist);
+
+/**
+ * Output data to the client in a printf format
+ * @param r The current request
+ * @param fmt The format string
+ * @param ... The arguments to use to fill out the format string
+ * @return The number of bytes sent
+ */
+AP_DECLARE_NONSTD(int) ap_rprintf(request_rec *r, const char *fmt,...)
+ __attribute__((format(printf,2,3)));
+
+/**
+ * Flush all of the data for the current request to the client
+ * @param r The current request
+ * @return 0 on success, -1 if an error occurred
+ */
+AP_DECLARE(int) ap_rflush(request_rec *r);
+
+/**
+ * Index used in custom_responses array for a specific error code
+ * (only use outside protocol.c is in getting them configured).
+ * @param status HTTP status code
+ * @return The index of the response
+ */
+AP_DECLARE(int) ap_index_of_response(int status);
+
+/**
+ * Return the Status-Line for a given status code (excluding the
+ * HTTP-Version field). If an invalid or unknown status code is
+ * passed, "500 Internal Server Error" will be returned.
+ * @param status The HTTP status code
+ * @return The Status-Line
+ */
+AP_DECLARE(const char *) ap_get_status_line(int status);
+
+/* Reading a block of data from the client connection (e.g., POST arg) */
+
+/**
+ * Setup the client to allow Apache to read the request body.
+ * @param r The current request
+ * @param read_policy How the server should interpret a chunked
+ * transfer-encoding. One of: <pre>
+ * REQUEST_NO_BODY Send 413 error if message has any body
+ * REQUEST_CHUNKED_ERROR Send 411 error if body without Content-Length
+ * REQUEST_CHUNKED_DECHUNK If chunked, remove the chunks for me.
+ * </pre>
+ * @return either OK or an error code
+ */
+AP_DECLARE(int) ap_setup_client_block(request_rec *r, int read_policy);
+
+/**
+ * Determine if the client has sent any data. This also sends a
+ * 100 Continue response to HTTP/1.1 clients, so modules should not be called
+ * until the module is ready to read content.
+ * @warning Never call this function more than once.
+ * @param r The current request
+ * @return 0 if there is no message to read, 1 otherwise
+ */
+AP_DECLARE(int) ap_should_client_block(request_rec *r);
+
+/**
+ * Call this in a loop. It will put data into a buffer and return the length
+ * of the input block
+ * @param r The current request
+ * @param buffer The buffer in which to store the data
+ * @param bufsiz The size of the buffer
+ * @return Number of bytes inserted into the buffer. When done reading, 0
+ * if EOF, or -1 if there was an error
+ */
+AP_DECLARE(long) ap_get_client_block(request_rec *r, char *buffer, apr_size_t bufsiz);
+
+/**
+ * Map specific APR codes returned by the filter stack to HTTP error
+ * codes, or the default status code provided. Use it as follows:
+ *
+ * return ap_map_http_request_error(rv, HTTP_BAD_REQUEST);
+ *
+ * If the filter has already handled the error, AP_FILTER_ERROR will
+ * be returned, which is cleanly passed through.
+ *
+ * These mappings imply that the filter stack is reading from the
+ * downstream client, the proxy will map these codes differently.
+ * @param rv APR status code
+ * @param status Default HTTP code should the APR code not be recognised
+ * @return Mapped HTTP status code
+ */
+AP_DECLARE(int) ap_map_http_request_error(apr_status_t rv, int status);
+
+/**
+ * In HTTP/1.1, any method can have a body. However, most GET handlers
+ * wouldn't know what to do with a request body if they received one.
+ * This helper routine tests for and reads any message body in the request,
+ * simply discarding whatever it receives. We need to do this because
+ * failing to read the request body would cause it to be interpreted
+ * as the next request on a persistent connection.
+ * @param r The current request
+ * @return error status if request is malformed, OK otherwise
+ */
+AP_DECLARE(int) ap_discard_request_body(request_rec *r);
+
+/**
+ * Setup the output headers so that the client knows how to authenticate
+ * itself the next time, if an authentication request failed.
+ * @param r The current request
+ */
+AP_DECLARE(void) ap_note_auth_failure(request_rec *r);
+
+/**
+ * @deprecated @see ap_note_auth_failure
+ */
+AP_DECLARE(void) ap_note_basic_auth_failure(request_rec *r);
+
+/**
+ * @deprecated @see ap_note_auth_failure
+ */
+AP_DECLARE(void) ap_note_digest_auth_failure(request_rec *r);
+
+/**
+ * This hook allows modules to add support for a specific auth type to
+ * ap_note_auth_failure
+ * @param r the current request
+ * @param auth_type the configured auth_type
+ * @return OK, DECLINED
+ */
+AP_DECLARE_HOOK(int, note_auth_failure, (request_rec *r, const char *auth_type))
+
+/**
+ * Get the password from the request headers. This function has multiple side
+ * effects due to its prior use in the old authentication framework.
+ * ap_get_basic_auth_components() should be preferred.
+ *
+ * @deprecated @see ap_get_basic_auth_components
+ * @param r The current request
+ * @param pw The password as set in the headers
+ * @return 0 (OK) if it set the 'pw' argument (and assured
+ * a correct value in r->user); otherwise it returns
+ * an error code, either HTTP_INTERNAL_SERVER_ERROR if things are
+ * really confused, HTTP_UNAUTHORIZED if no authentication at all
+ * seemed to be in use, or DECLINED if there was authentication but
+ * it wasn't Basic (in which case, the caller should presumably
+ * decline as well).
+ */
+AP_DECLARE(int) ap_get_basic_auth_pw(request_rec *r, const char **pw);
+
+#define AP_GET_BASIC_AUTH_PW_NOTE "AP_GET_BASIC_AUTH_PW_NOTE"
+
+/**
+ * Get the username and/or password from the request's Basic authentication
+ * headers. Unlike ap_get_basic_auth_pw(), calling this function has no side
+ * effects on the passed request_rec.
+ *
+ * @param r The current request
+ * @param username If not NULL, set to the username sent by the client
+ * @param password If not NULL, set to the password sent by the client
+ * @return APR_SUCCESS if the credentials were successfully parsed and returned;
+ * APR_EINVAL if there was no authentication header sent or if the
+ * client was not using the Basic authentication scheme. username and
+ * password are unchanged on failure.
+ */
+AP_DECLARE(apr_status_t) ap_get_basic_auth_components(const request_rec *r,
+ const char **username,
+ const char **password);
+
+/**
+ * parse_uri: break apart the uri
+ * @warning Side Effects:
+ * @li sets r->args to rest after '?' (or NULL if no '?')
+ * @li sets r->uri to request uri (without r->args part)
+ * @li sets r->hostname (if not set already) from request (scheme://host:port)
+ * @param r The current request
+ * @param uri The uri to break apart
+ */
+AP_CORE_DECLARE(void) ap_parse_uri(request_rec *r, const char *uri);
+
+#define AP_GETLINE_FOLD 1 /* Whether to merge continuation lines */
+#define AP_GETLINE_CRLF 2 /* Whether line ends must be in the form CR LF */
+#define AP_GETLINE_NOSPC_EOL 4 /* Whether to consume up to and including the
+ end of line on APR_ENOSPC */
+
+/**
+ * Get the next line of input for the request
+ * @param s The buffer into which to read the line
+ * @param n The size of the buffer
+ * @param r The request
+ * @param flags Bit flag of multiple parsing options
+ * AP_GETLINE_FOLD Whether to merge continuation lines
+ * AP_GETLINE_CRLF Whether line ends must be in the form CR LF
+ * @return The length of the line, if successful
+ * n, if the line is too big to fit in the buffer
+ * -1 for miscellaneous errors
+ */
+AP_DECLARE(int) ap_getline(char *s, int n, request_rec *r, int flags);
+
+/**
+ * Get the next line of input for the request
+ *
+ * Note: on ASCII boxes, ap_rgetline is a macro which simply calls
+ * ap_rgetline_core to get the line of input.
+ *
+ * on EBCDIC boxes, ap_rgetline is a wrapper function which
+ * translates ASCII protocol lines to the local EBCDIC code page
+ * after getting the line of input.
+ *
+ * @param s Pointer to the pointer to the buffer into which the line
+ * should be read; if *s==NULL, a buffer of the necessary size
+ * to hold the data will be allocated from the request pool
+ * @param n The size of the buffer
+ * @param read The length of the line.
+ * @param r The request
+ * @param flags Bit flag of multiple parsing options
+ * AP_GETLINE_FOLD Whether to merge continuation lines
+ * AP_GETLINE_CRLF Whether line ends must be in the form CR LF
+ * @param bb Working brigade to use when reading buckets
+ * @return APR_SUCCESS, if successful
+ * APR_ENOSPC, if the line is too big to fit in the buffer
+ * Other errors where appropriate
+ */
+#if APR_CHARSET_EBCDIC
+AP_DECLARE(apr_status_t) ap_rgetline(char **s, apr_size_t n,
+ apr_size_t *read,
+ request_rec *r, int flags,
+ apr_bucket_brigade *bb);
+#else /* ASCII box */
+#define ap_rgetline(s, n, read, r, fold, bb) \
+ ap_rgetline_core((s), (n), (read), (r), (fold), (bb))
+#endif
+
+/** @see ap_rgetline */
+AP_DECLARE(apr_status_t) ap_rgetline_core(char **s, apr_size_t n,
+ apr_size_t *read,
+ request_rec *r, int flags,
+ apr_bucket_brigade *bb);
+
+/**
+ * Get the method number associated with the given string, assumed to
+ * contain an HTTP method. Returns M_INVALID if not recognized.
+ * @param method A string containing a valid HTTP method
+ * @return The method number
+ */
+AP_DECLARE(int) ap_method_number_of(const char *method);
+
+/**
+ * Get the method name associated with the given internal method
+ * number. Returns NULL if not recognized.
+ * @param p A pool to use for temporary allocations.
+ * @param methnum An integer value corresponding to an internal method number
+ * @return The name corresponding to the method number
+ */
+AP_DECLARE(const char *) ap_method_name_of(apr_pool_t *p, int methnum);
+
+
+/* Hooks */
+/*
+ * pre_read_request --- run right before read_request_line(),
+ * and not run during any subrequests.
+ */
+/**
+ * This hook allows modules to affect the request or connection immediately before
+ * the request has been read, and before any other phases have been processes.
+ * @param r The current request of the soon-to-be-read request
+ * @param c The connection
+ * @return None/void
+ */
+AP_DECLARE_HOOK(void,pre_read_request,(request_rec *r, conn_rec *c))
+
+/*
+ * post_read_request --- run right after read_request or internal_redirect,
+ * and not run during any subrequests.
+ */
+/**
+ * This hook allows modules to affect the request immediately after the request
+ * has been read, and before any other phases have been processes. This allows
+ * modules to make decisions based upon the input header fields
+ * @param r The current request
+ * @return OK or DECLINED
+ */
+AP_DECLARE_HOOK(int,post_read_request,(request_rec *r))
+
+/**
+ * This hook allows modules to perform any module-specific logging activities
+ * over and above the normal server things.
+ * @param r The current request
+ * @return OK, DECLINED, or HTTP_...
+ */
+AP_DECLARE_HOOK(int,log_transaction,(request_rec *r))
+
+/**
+ * This hook allows modules to retrieve the http scheme for a request. This
+ * allows Apache modules to easily extend the schemes that Apache understands
+ * @param r The current request
+ * @return The http scheme from the request
+ */
+AP_DECLARE_HOOK(const char *,http_scheme,(const request_rec *r))
+
+/**
+ * Return the default port from the current request
+ * @param r The current request
+ * @return The current port
+ */
+AP_DECLARE_HOOK(apr_port_t,default_port,(const request_rec *r))
+
+
+#define AP_PROTOCOL_HTTP1 "http/1.1"
+
+/**
+ * Determine the list of protocols available for a connection/request. This may
+ * be collected with or without any request sent, in which case the request is
+ * NULL. Or it may be triggered by the request received, e.g. through the
+ * "Upgrade" header.
+ *
+ * This hook will be run whenever protocols are being negotiated (ALPN as
+ * one example). It may also be invoked at other times, e.g. when the server
+ * wants to advertise protocols it is capable of switching to.
+ *
+ * The identifiers for protocols are taken from the TLS extension type ALPN:
+ * https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xml
+ *
+ * If no protocols are added to the proposals, the server not perform any
+ * switch. If the protocol selected from the proposals is the protocol
+ * already in place, also no protocol switch will be invoked.
+ *
+ * The client may already have announced the protocols it is willing to
+ * accept. These will then be listed as offers. This parameter may also
+ * be NULL, indicating that offers from the client are not known and
+ * the hooks should propose all protocols that are valid for the
+ * current connection/request.
+ *
+ * All hooks are run, unless one returns an error. Proposals may contain
+ * duplicates. The order in which proposals are added is usually ignored.
+ *
+ * @param c The current connection
+ * @param r The current request or NULL
+ * @param s The server/virtual host selected
+ * @param offers A list of protocol identifiers offered by the client or
+ * NULL to indicated that the hooks are free to propose
+ * @param proposals The list of protocol identifiers proposed by the hooks
+ * @return OK or DECLINED
+ * @bug This API or implementation and order of operations should be considered
+ * experimental and will continue to evolve in future 2.4 releases, with
+ * a corresponding minor module magic number (MMN) bump to indicate the
+ * API revision level.
+ */
+AP_DECLARE_HOOK(int,protocol_propose,(conn_rec *c, request_rec *r,
+ server_rec *s,
+ const apr_array_header_t *offers,
+ apr_array_header_t *proposals))
+
+/**
+ * Perform a protocol switch on the connection. The exact requirements for
+ * that depend on the protocol in place and the one switched to. The first
+ * protocol module to handle the switch is the last module run.
+ *
+ * For a connection level switch (r == NULL), the handler must on return
+ * leave the conn_rec in a state suitable for processing the switched
+ * protocol, e.g. correct filters in place.
+ *
+ * For a request triggered switch (r != NULL), the protocol switch is done
+ * before the response is sent out. When switching from "http/1.1" via Upgrade
+ * header, the 101 intermediate response will have been sent. The
+ * hook needs then to process the connection until it can be closed. Which
+ * the server will enforce on hook return.
+ * Any error the hook might encounter must already be sent by the hook itself
+ * to the client in whatever form the new protocol requires.
+ *
+ * @param c The current connection
+ * @param r The current request or NULL
+ * @param s The server/virtual host selected
+ * @param choices A list of protocol identifiers, normally the clients whishes
+ * @param proposals the list of protocol identifiers proposed by the hooks
+ * @return OK or DECLINED
+ * @bug This API or implementation and order of operations should be considered
+ * experimental and will continue to evolve in future 2.4 releases, with
+ * a corresponding minor module magic number (MMN) bump to indicate the
+ * API revision level.
+ */
+AP_DECLARE_HOOK(int,protocol_switch,(conn_rec *c, request_rec *r,
+ server_rec *s,
+ const char *protocol))
+
+/**
+ * Return the protocol used on the connection. Modules implementing
+ * protocol switching must register here and return the correct protocol
+ * identifier for connections they switched.
+ *
+ * To find out the protocol for the current connection, better call
+ * @see ap_get_protocol which internally uses this hook.
+ *
+ * @param c The current connection
+ * @return The identifier of the protocol in place or NULL
+ * @bug This API or implementation and order of operations should be considered
+ * experimental and will continue to evolve in future 2.4 releases, with
+ * a corresponding minor module magic number (MMN) bump to indicate the
+ * API revision level.
+ */
+AP_DECLARE_HOOK(const char *,protocol_get,(const conn_rec *c))
+
+/**
+ * Get the protocols that the connection and optional request may
+ * upgrade to - besides the protocol currently active on the connection. These
+ * values may be used to announce to a client what choices it has.
+ *
+ * If report_all == 0, only protocols more preferable than the one currently
+ * being used, are reported. Otherwise, all available protocols beside the
+ * current one are being reported.
+ *
+ * @param c The current connection
+ * @param r The current request or NULL
+ * @param s The server/virtual host selected or NULL
+ * @param report_all include also protocols less preferred than the current one
+ * @param pupgrades on return, possible protocols to upgrade to in descending order
+ * of preference. Maybe NULL if none are available.
+ * @bug This API or implementation and order of operations should be considered
+ * experimental and will continue to evolve in future 2.4 releases, with
+ * a corresponding minor module magic number (MMN) bump to indicate the
+ * API revision level.
+ */
+AP_DECLARE(apr_status_t) ap_get_protocol_upgrades(conn_rec *c, request_rec *r,
+ server_rec *s, int report_all,
+ const apr_array_header_t **pupgrades);
+
+/**
+ * Select a protocol for the given connection and optional request. Will return
+ * the protocol identifier selected which may be the protocol already in place
+ * on the connection. The selected protocol will be NULL if non of the given
+ * choices could be agreed upon (e.g. no proposal as made).
+ *
+ * A special case is where the choices itself is NULL (instead of empty). In
+ * this case there are no restrictions imposed on protocol selection.
+ *
+ * @param c The current connection
+ * @param r The current request or NULL
+ * @param s The server/virtual host selected
+ * @param choices A list of protocol identifiers, normally the clients whishes
+ * @return The selected protocol or NULL if no protocol could be agreed upon
+ * @bug This API or implementation and order of operations should be considered
+ * experimental and will continue to evolve in future 2.4 releases, with
+ * a corresponding minor module magic number (MMN) bump to indicate the
+ * API revision level.
+ */
+AP_DECLARE(const char *) ap_select_protocol(conn_rec *c, request_rec *r,
+ server_rec *s,
+ const apr_array_header_t *choices);
+
+/**
+ * Perform the actual protocol switch. The protocol given must have been
+ * selected before on the very same connection and request pair.
+ *
+ * @param c The current connection
+ * @param r The current request or NULL
+ * @param s The server/virtual host selected
+ * @param protocol the protocol to switch to
+ * @return APR_SUCCESS, if caller may continue processing as usual
+ * APR_EOF, if caller needs to stop processing the connection
+ * APR_EINVAL, if the protocol is already in place
+ * APR_NOTIMPL, if no module performed the switch
+ * Other errors where appropriate
+ * @bug This API or implementation and order of operations should be considered
+ * experimental and will continue to evolve in future 2.4 releases, with
+ * a corresponding minor module magic number (MMN) bump to indicate the
+ * API revision level.
+ */
+AP_DECLARE(apr_status_t) ap_switch_protocol(conn_rec *c, request_rec *r,
+ server_rec *s,
+ const char *protocol);
+
+/**
+ * Call the protocol_get hook to determine the protocol currently in use
+ * for the given connection.
+ *
+ * Unless another protocol has been switch to, will default to
+ * @see AP_PROTOCOL_HTTP1 and modules implementing a new protocol must
+ * report a switched connection via the protocol_get hook.
+ *
+ * @param c The connection to determine the protocol for
+ * @return the protocol in use, never NULL
+ * @bug This API or implementation and order of operations should be considered
+ * experimental and will continue to evolve in future 2.4 releases, with
+ * a corresponding minor module magic number (MMN) bump to indicate the
+ * API revision level.
+ */
+AP_DECLARE(const char *) ap_get_protocol(conn_rec *c);
+
+/**
+ * Check if the given protocol is an allowed choice on the given
+ * combination of connection, request and server.
+ *
+ * When server is NULL, it is taken from request_rec, unless
+ * request_rec is NULL. Then it is taken from the connection base
+ * server.
+ *
+ * @param c The current connection
+ * @param r The current request or NULL
+ * @param s The server/virtual host selected or NULL
+ * @param protocol the protocol to switch to
+ * @return != 0 iff protocol is allowed
+ * @bug This API or implementation and order of operations should be considered
+ * experimental and will continue to evolve in future 2.4 releases, with
+ * a corresponding minor module magic number (MMN) bump to indicate the
+ * API revision level.
+ */
+AP_DECLARE(int) ap_is_allowed_protocol(conn_rec *c, request_rec *r,
+ server_rec *s, const char *protocol);
+
+/** @see ap_bucket_type_error */
+typedef struct ap_bucket_error ap_bucket_error;
+
+/**
+ * @struct ap_bucket_error
+ * @brief A bucket referring to an HTTP error
+ *
+ * This bucket can be passed down the filter stack to indicate that an
+ * HTTP error occurred while running a filter. In order for this bucket
+ * to be used successfully, it MUST be sent as the first bucket in the
+ * first brigade to be sent from a given filter.
+ */
+struct ap_bucket_error {
+ /** Number of buckets using this memory */
+ apr_bucket_refcount refcount;
+ /** The error code */
+ int status;
+ /** The error string */
+ const char *data;
+};
+
+/** @see ap_bucket_type_error */
+AP_DECLARE_DATA extern const apr_bucket_type_t ap_bucket_type_error;
+
+/**
+ * Determine if a bucket is an error bucket
+ * @param e The bucket to inspect
+ * @return true or false
+ */
+#define AP_BUCKET_IS_ERROR(e) (e->type == &ap_bucket_type_error)
+
+/**
+ * Make the bucket passed in an error bucket
+ * @param b The bucket to make into an error bucket
+ * @param error The HTTP error code to put in the bucket.
+ * @param buf An optional error string to put in the bucket.
+ * @param p A pool to allocate out of.
+ * @return The new bucket, or NULL if allocation failed
+ */
+AP_DECLARE(apr_bucket *) ap_bucket_error_make(apr_bucket *b, int error,
+ const char *buf, apr_pool_t *p);
+
+/**
+ * Create a bucket referring to an HTTP error.
+ * @param error The HTTP error code to put in the bucket.
+ * @param buf An optional error string to put in the bucket.
+ * @param p A pool to allocate the error string out of.
+ * @param list The bucket allocator from which to allocate the bucket
+ * @return The new bucket, or NULL if allocation failed
+ */
+AP_DECLARE(apr_bucket *) ap_bucket_error_create(int error, const char *buf,
+ apr_pool_t *p,
+ apr_bucket_alloc_t *list);
+
+AP_DECLARE_NONSTD(apr_status_t) ap_byterange_filter(ap_filter_t *f, apr_bucket_brigade *b);
+AP_DECLARE_NONSTD(apr_status_t) ap_http_header_filter(ap_filter_t *f, apr_bucket_brigade *b);
+AP_DECLARE_NONSTD(apr_status_t) ap_content_length_filter(ap_filter_t *,
+ apr_bucket_brigade *);
+AP_DECLARE_NONSTD(apr_status_t) ap_old_write_filter(ap_filter_t *f, apr_bucket_brigade *b);
+
+/**
+ * Sett up the protocol fields for subsidiary requests
+ * @param rnew New Sub Request
+ * @param r current request
+ */
+AP_DECLARE(void) ap_set_sub_req_protocol(request_rec *rnew, const request_rec *r);
+
+/**
+ * A wrapup function to keep the internal accounting straight.
+ * Indicates that there is no more content coming.
+ * @param sub_r Subrequest that is now compete
+ */
+AP_DECLARE(void) ap_finalize_sub_req_protocol(request_rec *sub_r);
+
+/**
+ * Send an interim (HTTP 1xx) response immediately.
+ * @param r The request
+ * @param send_headers Whether to send&clear headers in r->headers_out
+ */
+AP_DECLARE(void) ap_send_interim_response(request_rec *r, int send_headers);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !APACHE_HTTP_PROTOCOL_H */
+/** @} */
diff --git a/include/http_request.h b/include/http_request.h
new file mode 100644
index 0000000..0013d39
--- /dev/null
+++ b/include/http_request.h
@@ -0,0 +1,630 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file http_request.h
+ * @brief Apache Request library
+ *
+ * @defgroup APACHE_CORE_REQ Apache Request Processing
+ * @ingroup APACHE_CORE
+ * @{
+ */
+
+/*
+ * request.c is the code which handles the main line of request
+ * processing, once a request has been read in (finding the right per-
+ * directory configuration, building it if necessary, and calling all
+ * the module dispatch functions in the right order).
+ *
+ * The pieces here which are public to the modules, allow them to learn
+ * how the server would handle some other file or URI, or perhaps even
+ * direct the server to serve that other file instead of the one the
+ * client requested directly.
+ *
+ * There are two ways to do that. The first is the sub_request mechanism,
+ * which handles looking up files and URIs as adjuncts to some other
+ * request (e.g., directory entries for multiviews and directory listings);
+ * the lookup functions stop short of actually running the request, but
+ * (e.g., for includes), a module may call for the request to be run
+ * by calling run_sub_req. The space allocated to create sub_reqs can be
+ * reclaimed by calling destroy_sub_req --- be sure to copy anything you care
+ * about which was allocated in its apr_pool_t elsewhere before doing this.
+ */
+
+#ifndef APACHE_HTTP_REQUEST_H
+#define APACHE_HTTP_REQUEST_H
+
+#include "apr_optional.h"
+#include "util_filter.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define AP_SUBREQ_NO_ARGS 0
+#define AP_SUBREQ_MERGE_ARGS 1
+
+/**
+ * An internal handler used by the ap_process_request, all subrequest mechanisms
+ * and the redirect mechanism.
+ * @param r The request, subrequest or internal redirect to pre-process
+ * @return The return code for the request
+ */
+AP_DECLARE(int) ap_process_request_internal(request_rec *r);
+
+/**
+ * Create a subrequest from the given URI. This subrequest can be
+ * inspected to find information about the requested URI
+ * @param new_uri The URI to lookup
+ * @param r The current request
+ * @param next_filter The first filter the sub_request should use. If this is
+ * NULL, it defaults to the first filter for the main request
+ * @return The new request record
+ */
+AP_DECLARE(request_rec *) ap_sub_req_lookup_uri(const char *new_uri,
+ const request_rec *r,
+ ap_filter_t *next_filter);
+
+/**
+ * Create a subrequest for the given file. This subrequest can be
+ * inspected to find information about the requested file
+ * @param new_file The file to lookup
+ * @param r The current request
+ * @param next_filter The first filter the sub_request should use. If this is
+ * NULL, it defaults to the first filter for the main request
+ * @return The new request record
+ */
+AP_DECLARE(request_rec *) ap_sub_req_lookup_file(const char *new_file,
+ const request_rec *r,
+ ap_filter_t *next_filter);
+/**
+ * Create a subrequest for the given apr_dir_read result. This subrequest
+ * can be inspected to find information about the requested file
+ * @param finfo The apr_dir_read result to lookup
+ * @param r The current request
+ * @param subtype What type of subrequest to perform, one of;
+ * <PRE>
+ * AP_SUBREQ_NO_ARGS ignore r->args and r->path_info
+ * AP_SUBREQ_MERGE_ARGS merge r->args and r->path_info
+ * </PRE>
+ * @param next_filter The first filter the sub_request should use. If this is
+ * NULL, it defaults to the first filter for the main request
+ * @return The new request record
+ * @note The apr_dir_read flags value APR_FINFO_MIN|APR_FINFO_NAME flag is the
+ * minimum recommended query if the results will be passed to apr_dir_read.
+ * The file info passed must include the name, and must have the same relative
+ * directory as the current request.
+ */
+AP_DECLARE(request_rec *) ap_sub_req_lookup_dirent(const apr_finfo_t *finfo,
+ const request_rec *r,
+ int subtype,
+ ap_filter_t *next_filter);
+/**
+ * Create a subrequest for the given URI using a specific method. This
+ * subrequest can be inspected to find information about the requested URI
+ * @param method The method to use in the new subrequest
+ * @param new_uri The URI to lookup
+ * @param r The current request
+ * @param next_filter The first filter the sub_request should use. If this is
+ * NULL, it defaults to the first filter for the main request
+ * @return The new request record
+ */
+AP_DECLARE(request_rec *) ap_sub_req_method_uri(const char *method,
+ const char *new_uri,
+ const request_rec *r,
+ ap_filter_t *next_filter);
+/**
+ * An output filter to strip EOS buckets from sub-requests. This always
+ * has to be inserted at the end of a sub-requests filter stack.
+ * @param f The current filter
+ * @param bb The brigade to filter
+ * @return status code
+ */
+AP_CORE_DECLARE_NONSTD(apr_status_t) ap_sub_req_output_filter(ap_filter_t *f,
+ apr_bucket_brigade *bb);
+
+/**
+ * Run the handler for the subrequest
+ * @param r The subrequest to run
+ * @return The return code for the subrequest
+ */
+AP_DECLARE(int) ap_run_sub_req(request_rec *r);
+
+/**
+ * Free the memory associated with a subrequest
+ * @param r The subrequest to finish
+ */
+AP_DECLARE(void) ap_destroy_sub_req(request_rec *r);
+
+/*
+ * Then there's the case that you want some other request to be served
+ * as the top-level request INSTEAD of what the client requested directly.
+ * If so, call this from a handler, and then immediately return OK.
+ */
+
+/**
+ * Redirect the current request to some other uri
+ * @param new_uri The URI to replace the current request with
+ * @param r The current request
+ */
+AP_DECLARE(void) ap_internal_redirect(const char *new_uri, request_rec *r);
+
+/**
+ * This function is designed for things like actions or CGI scripts, when
+ * using AddHandler, and you want to preserve the content type across
+ * an internal redirect.
+ * @param new_uri The URI to replace the current request with.
+ * @param r The current request
+ */
+AP_DECLARE(void) ap_internal_redirect_handler(const char *new_uri, request_rec *r);
+
+/**
+ * Redirect the current request to a sub_req, merging the pools
+ * @param sub_req A subrequest created from this request
+ * @param r The current request
+ * @note the sub_req's pool will be merged into r's pool, be very careful
+ * not to destroy this subrequest, it will be destroyed with the main request!
+ */
+AP_DECLARE(void) ap_internal_fast_redirect(request_rec *sub_req, request_rec *r);
+
+/**
+ * Can be used within any handler to determine if any authentication
+ * is required for the current request
+ * @param r The current request
+ * @return 1 if authentication is required, 0 otherwise
+ * @bug Behavior changed in 2.4.x refactoring, API no longer usable
+ * @deprecated @see ap_some_authn_required()
+ */
+AP_DECLARE(int) ap_some_auth_required(request_rec *r);
+
+/**
+ * @defgroup APACHE_CORE_REQ_AUTH Access Control for Sub-Requests and
+ * Internal Redirects
+ * @ingroup APACHE_CORE_REQ
+ * @{
+ */
+
+#define AP_AUTH_INTERNAL_PER_URI 0 /**< Run access control hooks on all
+ internal requests with URIs
+ distinct from that of initial
+ request */
+#define AP_AUTH_INTERNAL_PER_CONF 1 /**< Run access control hooks only on
+ internal requests with
+ configurations distinct from
+ that of initial request */
+#define AP_AUTH_INTERNAL_MASK 0x000F /**< mask to extract internal request
+ processing mode */
+
+/**
+ * Clear flag which determines when access control hooks will be run for
+ * internal requests.
+ */
+AP_DECLARE(void) ap_clear_auth_internal(void);
+
+/**
+ * Determine whether access control hooks will be run for all internal
+ * requests with URIs distinct from that of the initial request, or only
+ * those for which different configurations apply than those which applied
+ * to the initial request. To accommodate legacy external modules which
+ * may expect access control hooks to be run for all internal requests
+ * with distinct URIs, this is the default behaviour unless all access
+ * control hooks and authentication and authorization providers are
+ * registered with AP_AUTH_INTERNAL_PER_CONF.
+ * @param ptemp Pool used for temporary allocations
+ */
+AP_DECLARE(void) ap_setup_auth_internal(apr_pool_t *ptemp);
+
+/**
+ * Register an authentication or authorization provider with the global
+ * provider pool.
+ * @param pool The pool to create any storage from
+ * @param provider_group The group to store the provider in
+ * @param provider_name The name for this provider
+ * @param provider_version The version for this provider
+ * @param provider Opaque structure for this provider
+ * @param type Internal request processing mode, either
+ * AP_AUTH_INTERNAL_PER_URI or AP_AUTH_INTERNAL_PER_CONF
+ * @return APR_SUCCESS if all went well
+ */
+AP_DECLARE(apr_status_t) ap_register_auth_provider(apr_pool_t *pool,
+ const char *provider_group,
+ const char *provider_name,
+ const char *provider_version,
+ const void *provider,
+ int type);
+
+/** @} */
+
+/* Optional functions coming from mod_authn_core and mod_authz_core
+ * that list all registered authn/z providers.
+ */
+APR_DECLARE_OPTIONAL_FN(apr_array_header_t *, authn_ap_list_provider_names,
+ (apr_pool_t *ptemp));
+APR_DECLARE_OPTIONAL_FN(apr_array_header_t *, authz_ap_list_provider_names,
+ (apr_pool_t *ptemp));
+
+/**
+ * Determine if the current request is the main request or a subrequest
+ * @param r The current request
+ * @return 1 if this is the main request, 0 otherwise
+ */
+AP_DECLARE(int) ap_is_initial_req(request_rec *r);
+
+/**
+ * Function to set the r->mtime field to the specified value if it's later
+ * than what's already there.
+ * @param r The current request
+ * @param dependency_mtime Time to set the mtime to
+ */
+AP_DECLARE(void) ap_update_mtime(request_rec *r, apr_time_t dependency_mtime);
+
+/**
+ * Add one or more methods to the list permitted to access the resource.
+ * Usually executed by the content handler before the response header is
+ * sent, but sometimes invoked at an earlier phase if a module knows it
+ * can set the list authoritatively. Note that the methods are ADDED
+ * to any already permitted unless the reset flag is non-zero. The
+ * list is used to generate the Allow response header field when it
+ * is needed.
+ * @param r The pointer to the request identifying the resource.
+ * @param reset Boolean flag indicating whether this list should
+ * completely replace any current settings.
+ * @param ... A NULL-terminated list of strings, each identifying a
+ * method name to add.
+ * @return None.
+ */
+AP_DECLARE(void) ap_allow_methods(request_rec *r, int reset, ...)
+ AP_FN_ATTR_SENTINEL;
+
+/**
+ * Add one or more methods to the list permitted to access the resource.
+ * Usually executed by the content handler before the response header is
+ * sent, but sometimes invoked at an earlier phase if a module knows it
+ * can set the list authoritatively. Note that the methods are ADDED
+ * to any already permitted unless the reset flag is non-zero. The
+ * list is used to generate the Allow response header field when it
+ * is needed.
+ * @param r The pointer to the request identifying the resource.
+ * @param reset Boolean flag indicating whether this list should
+ * completely replace any current settings.
+ * @param ... A list of method identifiers, from the "M_" series
+ * defined in httpd.h, terminated with a value of -1
+ * (e.g., "M_GET, M_POST, M_OPTIONS, -1")
+ * @return None.
+ */
+AP_DECLARE(void) ap_allow_standard_methods(request_rec *r, int reset, ...);
+
+#define MERGE_ALLOW 0
+#define REPLACE_ALLOW 1
+
+/**
+ * Process a top-level request from a client, and synchronously write
+ * the response to the client
+ * @param r The current request
+ */
+AP_DECLARE(void) ap_process_request(request_rec *r);
+
+/* For post-processing after a handler has finished with a request.
+ * (Commonly used after it was suspended)
+ */
+AP_DECLARE(void) ap_process_request_after_handler(request_rec *r);
+
+/**
+ * Process a top-level request from a client, allowing some or all of
+ * the response to remain buffered in the core output filter for later,
+ * asynchronous write completion
+ * @param r The current request
+ */
+void ap_process_async_request(request_rec *r);
+
+/**
+ * Kill the current request
+ * @param type Why the request is dieing
+ * @param r The current request
+ */
+AP_DECLARE(void) ap_die(int type, request_rec *r);
+
+/**
+ * Check whether a connection is still established and has data available,
+ * optionnaly consuming blank lines ([CR]LF).
+ * @param c The current connection
+ * @param bb The brigade to filter
+ * @param max_blank_lines Max number of blank lines to consume, or zero
+ * to consider them as data (single read).
+ * @return APR_SUCCESS: connection established with data available,
+ * APR_EAGAIN: connection established and empty,
+ * APR_NOTFOUND: too much blank lines,
+ * APR_E*: connection/general error.
+ */
+AP_DECLARE(apr_status_t) ap_check_pipeline(conn_rec *c, apr_bucket_brigade *bb,
+ unsigned int max_blank_lines);
+
+/* Hooks */
+
+/**
+ * Gives modules a chance to create their request_config entry when the
+ * request is created.
+ * @param r The current request
+ * @ingroup hooks
+ */
+AP_DECLARE_HOOK(int,create_request,(request_rec *r))
+
+/**
+ * This hook allow modules an opportunity to translate the URI into an
+ * actual filename. If no modules do anything special, the server's default
+ * rules will be followed.
+ * @param r The current request
+ * @return OK, DECLINED, or HTTP_...
+ * @ingroup hooks
+ */
+AP_DECLARE_HOOK(int,translate_name,(request_rec *r))
+
+/**
+ * This hook allow modules to set the per_dir_config based on their own
+ * context (such as "<Proxy>" sections) and responds to contextless requests
+ * such as TRACE that need no security or filesystem mapping.
+ * based on the filesystem.
+ * @param r The current request
+ * @return DONE (or HTTP_) if this contextless request was just fulfilled
+ * (such as TRACE), OK if this is not a file, and DECLINED if this is a file.
+ * The core map_to_storage (HOOK_RUN_REALLY_LAST) will directory_walk
+ * and file_walk the r->filename.
+ *
+ * @ingroup hooks
+ */
+AP_DECLARE_HOOK(int,map_to_storage,(request_rec *r))
+
+/**
+ * This hook is used to analyze the request headers, authenticate the user,
+ * and set the user information in the request record (r->user and
+ * r->ap_auth_type). This hook is only run when Apache determines that
+ * authentication/authorization is required for this resource (as determined
+ * by the 'Require' directive). It runs after the access_checker hook, and
+ * before the auth_checker hook. This hook should be registered with
+ * ap_hook_check_authn().
+ *
+ * @param r The current request
+ * @return OK, DECLINED, or HTTP_...
+ * @ingroup hooks
+ * @see ap_hook_check_authn
+ */
+AP_DECLARE_HOOK(int,check_user_id,(request_rec *r))
+
+/**
+ * Allows modules to perform module-specific fixing of header fields. This
+ * is invoked just before any content-handler
+ * @param r The current request
+ * @return OK, DECLINED, or HTTP_...
+ * @ingroup hooks
+ */
+AP_DECLARE_HOOK(int,fixups,(request_rec *r))
+
+/**
+ * This routine is called to determine and/or set the various document type
+ * information bits, like Content-type (via r->content_type), language, et
+ * cetera.
+ * @param r the current request
+ * @return OK, DECLINED, or HTTP_...
+ * @ingroup hooks
+ */
+AP_DECLARE_HOOK(int,type_checker,(request_rec *r))
+
+/**
+ * This hook is used to apply additional access control to this resource.
+ * It runs *before* a user is authenticated, so this hook is really to
+ * apply additional restrictions independent of a user. It also runs
+ * independent of 'Require' directive usage. This hook should be registered
+ * with ap_hook_check_access().
+ *
+ * @param r the current request
+ * @return OK, DECLINED, or HTTP_...
+ * @ingroup hooks
+ * @see ap_hook_check_access
+ */
+AP_DECLARE_HOOK(int,access_checker,(request_rec *r))
+
+/**
+ * This hook is used to apply additional access control and/or bypass
+ * authentication for this resource. It runs *before* a user is authenticated,
+ * but after the auth_checker hook.
+ * This hook should be registered with ap_hook_check_access_ex().
+ *
+ * @param r the current request
+ * @return OK (allow acces), DECLINED (let later modules decide),
+ * or HTTP_... (deny access)
+ * @ingroup hooks
+ * @see ap_hook_check_access_ex
+ */
+AP_DECLARE_HOOK(int,access_checker_ex,(request_rec *r))
+
+/**
+ * This hook is used to check to see if the resource being requested
+ * is available for the authenticated user (r->user and r->ap_auth_type).
+ * It runs after the access_checker and check_user_id hooks. Note that
+ * it will *only* be called if Apache determines that access control has
+ * been applied to this resource (through a 'Require' directive). This
+ * hook should be registered with ap_hook_check_authz().
+ *
+ * @param r the current request
+ * @return OK, DECLINED, or HTTP_...
+ * @ingroup hooks
+ * @see ap_hook_check_authz
+ */
+AP_DECLARE_HOOK(int,auth_checker,(request_rec *r))
+
+/**
+ * Register a hook function that will apply additional access control to
+ * the current request.
+ * @param pf An access_checker hook function
+ * @param aszPre A NULL-terminated array of strings that name modules whose
+ * hooks should precede this one
+ * @param aszSucc A NULL-terminated array of strings that name modules whose
+ * hooks should succeed this one
+ * @param nOrder An integer determining order before honouring aszPre and
+ * aszSucc (for example, HOOK_MIDDLE)
+ * @param type Internal request processing mode, either
+ * AP_AUTH_INTERNAL_PER_URI or AP_AUTH_INTERNAL_PER_CONF
+ */
+AP_DECLARE(void) ap_hook_check_access(ap_HOOK_access_checker_t *pf,
+ const char * const *aszPre,
+ const char * const *aszSucc,
+ int nOrder, int type);
+
+/**
+ * Register a hook function that will apply additional access control
+ * and/or bypass authentication for the current request.
+ * @param pf An access_checker_ex hook function
+ * @param aszPre A NULL-terminated array of strings that name modules whose
+ * hooks should precede this one
+ * @param aszSucc A NULL-terminated array of strings that name modules whose
+ * hooks should succeed this one
+ * @param nOrder An integer determining order before honouring aszPre and
+ * aszSucc (for example, HOOK_MIDDLE)
+ * @param type Internal request processing mode, either
+ * AP_AUTH_INTERNAL_PER_URI or AP_AUTH_INTERNAL_PER_CONF
+ */
+AP_DECLARE(void) ap_hook_check_access_ex(ap_HOOK_access_checker_ex_t *pf,
+ const char * const *aszPre,
+ const char * const *aszSucc,
+ int nOrder, int type);
+
+
+/**
+ * Register a hook function that will analyze the request headers,
+ * authenticate the user, and set the user information in the request record.
+ * @param pf A check_user_id hook function
+ * @param aszPre A NULL-terminated array of strings that name modules whose
+ * hooks should precede this one
+ * @param aszSucc A NULL-terminated array of strings that name modules whose
+ * hooks should succeed this one
+ * @param nOrder An integer determining order before honouring aszPre and
+ * aszSucc (for example, HOOK_MIDDLE)
+ * @param type Internal request processing mode, either
+ * AP_AUTH_INTERNAL_PER_URI or AP_AUTH_INTERNAL_PER_CONF
+ */
+AP_DECLARE(void) ap_hook_check_authn(ap_HOOK_check_user_id_t *pf,
+ const char * const *aszPre,
+ const char * const *aszSucc,
+ int nOrder, int type);
+
+/**
+ * Register a hook function that determine if the resource being requested
+ * is available for the currently authenticated user.
+ * @param pf An auth_checker hook function
+ * @param aszPre A NULL-terminated array of strings that name modules whose
+ * hooks should precede this one
+ * @param aszSucc A NULL-terminated array of strings that name modules whose
+ * hooks should succeed this one
+ * @param nOrder An integer determining order before honouring aszPre and
+ * aszSucc (for example, HOOK_MIDDLE)
+ * @param type Internal request processing mode, either
+ * AP_AUTH_INTERNAL_PER_URI or AP_AUTH_INTERNAL_PER_CONF
+ */
+AP_DECLARE(void) ap_hook_check_authz(ap_HOOK_auth_checker_t *pf,
+ const char * const *aszPre,
+ const char * const *aszSucc,
+ int nOrder, int type);
+
+/**
+ * This hook allows modules to insert filters for the current request
+ * @param r the current request
+ * @ingroup hooks
+ */
+AP_DECLARE_HOOK(void,insert_filter,(request_rec *r))
+
+/**
+ * This hook allows modules to affect the request immediately after the
+ * per-directory configuration for the request has been generated.
+ * @param r The current request
+ * @return OK (allow acces), DECLINED (let later modules decide),
+ * or HTTP_... (deny access)
+ * @ingroup hooks
+ */
+AP_DECLARE_HOOK(int,post_perdir_config,(request_rec *r))
+
+/**
+ * This hook allows a module to force authn to be required when
+ * processing a request.
+ * This hook should be registered with ap_hook_force_authn().
+ * @param r The current request
+ * @return OK (force authn), DECLINED (let later modules decide)
+ * @ingroup hooks
+ */
+AP_DECLARE_HOOK(int,force_authn,(request_rec *r))
+
+/**
+ * This hook allows modules to handle/emulate the apr_stat() calls
+ * needed for directory walk.
+ * @param finfo where to put the stat data
+ * @param r The current request
+ * @param wanted APR_FINFO_* flags to pass to apr_stat()
+ * @return apr_status_t or AP_DECLINED (let later modules decide)
+ * @ingroup hooks
+ */
+AP_DECLARE_HOOK(apr_status_t,dirwalk_stat,(apr_finfo_t *finfo, request_rec *r, apr_int32_t wanted))
+
+AP_DECLARE(int) ap_location_walk(request_rec *r);
+AP_DECLARE(int) ap_directory_walk(request_rec *r);
+AP_DECLARE(int) ap_file_walk(request_rec *r);
+AP_DECLARE(int) ap_if_walk(request_rec *r);
+
+/** End Of REQUEST (EOR) bucket */
+AP_DECLARE_DATA extern const apr_bucket_type_t ap_bucket_type_eor;
+
+/**
+ * Determine if a bucket is an End Of REQUEST (EOR) bucket
+ * @param e The bucket to inspect
+ * @return true or false
+ */
+#define AP_BUCKET_IS_EOR(e) (e->type == &ap_bucket_type_eor)
+
+/**
+ * Make the bucket passed in an End Of REQUEST (EOR) bucket
+ * @param b The bucket to make into an EOR bucket
+ * @param r The request to destroy when this bucket is destroyed
+ * @return The new bucket, or NULL if allocation failed
+ */
+AP_DECLARE(apr_bucket *) ap_bucket_eor_make(apr_bucket *b, request_rec *r);
+
+/**
+ * Create a bucket referring to an End Of REQUEST (EOR). This bucket
+ * holds a pointer to the request_rec, so that the request can be
+ * destroyed right after all of the output has been sent to the client.
+ *
+ * @param list The freelist from which this bucket should be allocated
+ * @param r The request to destroy when this bucket is destroyed
+ * @return The new bucket, or NULL if allocation failed
+ */
+AP_DECLARE(apr_bucket *) ap_bucket_eor_create(apr_bucket_alloc_t *list,
+ request_rec *r);
+
+/**
+ * Can be used within any handler to determine if any authentication
+ * is required for the current request. Note that if used with an
+ * access_checker hook, an access_checker_ex hook or an authz provider; the
+ * caller should take steps to avoid a loop since this function is
+ * implemented by calling these hooks.
+ * @param r The current request
+ * @return TRUE if authentication is required, FALSE otherwise
+ */
+AP_DECLARE(int) ap_some_authn_required(request_rec *r);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !APACHE_HTTP_REQUEST_H */
+/** @} */
diff --git a/include/http_vhost.h b/include/http_vhost.h
new file mode 100644
index 0000000..473c9c7
--- /dev/null
+++ b/include/http_vhost.h
@@ -0,0 +1,119 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file http_vhost.h
+ * @brief Virtual Host package
+ *
+ * @defgroup APACHE_CORE_VHOST Virtual Host Package
+ * @ingroup APACHE_CORE
+ * @{
+ */
+
+#ifndef APACHE_HTTP_VHOST_H
+#define APACHE_HTTP_VHOST_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * called before any config is read
+ * @param p Pool to allocate out of
+ */
+AP_DECLARE(void) ap_init_vhost_config(apr_pool_t *p);
+
+/**
+ * called after the config has been read to compile the tables needed to do
+ * the run-time vhost lookups
+ * @param p The pool to allocate out of
+ * @param main_server The start of the virtual host list
+ */
+AP_DECLARE(void) ap_fini_vhost_config(apr_pool_t *p, server_rec *main_server);
+
+/**
+ * handle addresses in "<VirtualHost>" statement
+ * @param p The pool to allocate out of
+ * @param hostname The hostname in the VirtualHost statement
+ * @param s The list of Virtual Hosts.
+ */
+const char *ap_parse_vhost_addrs(apr_pool_t *p, const char *hostname, server_rec *s);
+
+/**
+ * handle NameVirtualHost directive
+ * @param cmd Command Parameters structure
+ * @param dummy NOT USED
+ * @param arg a host of the form "<address>[:port]"
+ */
+AP_DECLARE_NONSTD(const char *)ap_set_name_virtual_host(cmd_parms *cmd,
+ void *dummy,
+ const char *arg);
+
+/**
+ * Callback function for every Name Based Virtual Host.
+ * @param baton Opaque user object
+ * @param conn The current Connection
+ * @param s The current Server
+ * @see ap_vhost_iterate_given_conn
+ * @return 0 on success, any non-zero return will stop the iteration.
+ */
+typedef int(*ap_vhost_iterate_conn_cb)(void* baton, conn_rec* conn, server_rec* s);
+
+/**
+ * For every virtual host on this connection, call func_cb.
+ * @param conn The current connection
+ * @param func_cb Function called for every Name Based Virtual Host for this
+ * connection.
+ * @param baton Opaque object passed to func_cb.
+ * @return The return value from func_cb.
+ * @note If func_cb returns non-zero, the function will return at this point,
+ * and not continue iterating the virtual hosts.
+ */
+AP_DECLARE(int) ap_vhost_iterate_given_conn(conn_rec *conn,
+ ap_vhost_iterate_conn_cb func_cb,
+ void* baton);
+
+/**
+ * given an ip address only, give our best guess as to what vhost it is
+ * @param conn The current connection
+ */
+AP_DECLARE(void) ap_update_vhost_given_ip(conn_rec *conn);
+
+/**
+ * ap_update_vhost_given_ip is never enough, and this is always called after
+ * the headers have been read. It may change r->server.
+ * @param r The current request
+ */
+AP_DECLARE(void) ap_update_vhost_from_headers(request_rec *r);
+
+/**
+ * Match the host in the header with the hostname of the server for this
+ * request.
+ * @param r The current request
+ * @param host The hostname in the headers
+ * @param port The port from the headers
+ * @return return 1 if the host:port matches any of the aliases of r->server,
+ * return 0 otherwise
+ */
+AP_DECLARE(int) ap_matches_request_vhost(request_rec *r, const char *host,
+ apr_port_t port);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !APACHE_HTTP_VHOST_H */
+/** @} */
diff --git a/include/httpd.h b/include/httpd.h
new file mode 100644
index 0000000..65392f8
--- /dev/null
+++ b/include/httpd.h
@@ -0,0 +1,2409 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file httpd.h
+ * @brief HTTP Daemon routines
+ *
+ * @defgroup APACHE Apache HTTP Server
+ *
+ * Top level group of which all other groups are a member
+ * @{
+ *
+ * @defgroup APACHE_MODS Loadable modules
+ * Top level group for modules
+ * @defgroup APACHE_OS Operating System Specific
+ * @defgroup APACHE_INTERNAL Internal interfaces
+ * @defgroup APACHE_CORE Core routines
+ * @{
+ * @defgroup APACHE_CORE_DAEMON HTTP Daemon Routine
+ * @{
+ */
+
+#ifndef APACHE_HTTPD_H
+#define APACHE_HTTPD_H
+
+/* XXX - We need to push more stuff to other .h files, or even .c files, to
+ * make this file smaller
+ */
+
+/* Headers in which EVERYONE has an interest... */
+#include "ap_config.h"
+#include "ap_mmn.h"
+
+#include "ap_release.h"
+
+#include "apr.h"
+#include "apr_general.h"
+#include "apr_tables.h"
+#include "apr_pools.h"
+#include "apr_time.h"
+#include "apr_network_io.h"
+#include "apr_buckets.h"
+#include "apr_poll.h"
+#include "apr_thread_proc.h"
+
+#include "os.h"
+
+#include "ap_regex.h"
+
+#if APR_HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+/* Note: apr_uri.h is also included, see below */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* ----------------------------- config dir ------------------------------ */
+
+/** Define this to be the default server home dir. Most things later in this
+ * file with a relative pathname will have this added.
+ */
+#ifndef HTTPD_ROOT
+#ifdef OS2
+/** Set default for OS/2 file system */
+#define HTTPD_ROOT "/os2httpd"
+#elif defined(WIN32)
+/** Set default for Windows file system */
+#define HTTPD_ROOT "/apache"
+#elif defined (NETWARE)
+/** Set the default for NetWare */
+#define HTTPD_ROOT "/apache"
+#else
+/** Set for all other OSs */
+#define HTTPD_ROOT "/usr/local/apache"
+#endif
+#endif /* HTTPD_ROOT */
+
+/*
+ * --------- You shouldn't have to edit anything below this line ----------
+ *
+ * Any modifications to any defaults not defined above should be done in the
+ * respective configuration file.
+ *
+ */
+
+/**
+ * Default location of documents. Can be overridden by the DocumentRoot
+ * directive.
+ */
+#ifndef DOCUMENT_LOCATION
+#ifdef OS2
+/* Set default for OS/2 file system */
+#define DOCUMENT_LOCATION HTTPD_ROOT "/docs"
+#else
+/* Set default for non OS/2 file system */
+#define DOCUMENT_LOCATION HTTPD_ROOT "/htdocs"
+#endif
+#endif /* DOCUMENT_LOCATION */
+
+/** Maximum number of dynamically loaded modules */
+#ifndef DYNAMIC_MODULE_LIMIT
+#define DYNAMIC_MODULE_LIMIT 256
+#endif
+
+/** Default administrator's address */
+#define DEFAULT_ADMIN "[no address given]"
+
+/** The name of the log files */
+#ifndef DEFAULT_ERRORLOG
+#if defined(OS2) || defined(WIN32)
+#define DEFAULT_ERRORLOG "logs/error.log"
+#else
+#define DEFAULT_ERRORLOG "logs/error_log"
+#endif
+#endif /* DEFAULT_ERRORLOG */
+
+/** Define this to be what your per-directory security files are called */
+#ifndef DEFAULT_ACCESS_FNAME
+#ifdef OS2
+/* Set default for OS/2 file system */
+#define DEFAULT_ACCESS_FNAME "htaccess"
+#else
+#define DEFAULT_ACCESS_FNAME ".htaccess"
+#endif
+#endif /* DEFAULT_ACCESS_FNAME */
+
+/** The name of the server config file */
+#ifndef SERVER_CONFIG_FILE
+#define SERVER_CONFIG_FILE "conf/httpd.conf"
+#endif
+
+/** The default path for CGI scripts if none is currently set */
+#ifndef DEFAULT_PATH
+#define DEFAULT_PATH "/bin:/usr/bin:/usr/ucb:/usr/bsd:/usr/local/bin"
+#endif
+
+/** The path to the suExec wrapper, can be overridden in Configuration */
+#ifndef SUEXEC_BIN
+#define SUEXEC_BIN HTTPD_ROOT "/bin/suexec"
+#endif
+
+/** The timeout for waiting for messages */
+#ifndef DEFAULT_TIMEOUT
+#define DEFAULT_TIMEOUT 60
+#endif
+
+/** The timeout for waiting for keepalive timeout until next request */
+#ifndef DEFAULT_KEEPALIVE_TIMEOUT
+#define DEFAULT_KEEPALIVE_TIMEOUT 5
+#endif
+
+/** The number of requests to entertain per connection */
+#ifndef DEFAULT_KEEPALIVE
+#define DEFAULT_KEEPALIVE 100
+#endif
+
+/*
+ * Limits on the size of various request items. These limits primarily
+ * exist to prevent simple denial-of-service attacks on a server based
+ * on misuse of the protocol. The recommended values will depend on the
+ * nature of the server resources -- CGI scripts and database backends
+ * might require large values, but most servers could get by with much
+ * smaller limits than we use below. The request message body size can
+ * be limited by the per-dir config directive LimitRequestBody.
+ *
+ * Internal buffer sizes are two bytes more than the DEFAULT_LIMIT_REQUEST_LINE
+ * and DEFAULT_LIMIT_REQUEST_FIELDSIZE below, which explains the 8190.
+ * These two limits can be lowered or raised by the server config
+ * directives LimitRequestLine and LimitRequestFieldsize, respectively.
+ *
+ * DEFAULT_LIMIT_REQUEST_FIELDS can be modified or disabled (set = 0) by
+ * the server config directive LimitRequestFields.
+ */
+
+/** default limit on bytes in Request-Line (Method+URI+HTTP-version) */
+#ifndef DEFAULT_LIMIT_REQUEST_LINE
+#define DEFAULT_LIMIT_REQUEST_LINE 8190
+#endif
+/** default limit on bytes in any one header field */
+#ifndef DEFAULT_LIMIT_REQUEST_FIELDSIZE
+#define DEFAULT_LIMIT_REQUEST_FIELDSIZE 8190
+#endif
+/** default limit on number of request header fields */
+#ifndef DEFAULT_LIMIT_REQUEST_FIELDS
+#define DEFAULT_LIMIT_REQUEST_FIELDS 100
+#endif
+/** default/hard limit on number of leading/trailing empty lines */
+#ifndef DEFAULT_LIMIT_BLANK_LINES
+#define DEFAULT_LIMIT_BLANK_LINES 10
+#endif
+
+/**
+ * The default default character set name to add if AddDefaultCharset is
+ * enabled. Overridden with AddDefaultCharsetName.
+ */
+#define DEFAULT_ADD_DEFAULT_CHARSET_NAME "iso-8859-1"
+
+/** default HTTP Server protocol */
+#define AP_SERVER_PROTOCOL "HTTP/1.1"
+
+
+/* ------------------ stuff that modules are allowed to look at ----------- */
+
+/** Define this to be what your HTML directory content files are called */
+#ifndef AP_DEFAULT_INDEX
+#define AP_DEFAULT_INDEX "index.html"
+#endif
+
+/** The name of the MIME types file */
+#ifndef AP_TYPES_CONFIG_FILE
+#define AP_TYPES_CONFIG_FILE "conf/mime.types"
+#endif
+
+/*
+ * Define the HTML doctype strings centrally.
+ */
+/** HTML 2.0 Doctype */
+#define DOCTYPE_HTML_2_0 "<!DOCTYPE HTML PUBLIC \"-//IETF//" \
+ "DTD HTML 2.0//EN\">\n"
+/** HTML 3.2 Doctype */
+#define DOCTYPE_HTML_3_2 "<!DOCTYPE HTML PUBLIC \"-//W3C//" \
+ "DTD HTML 3.2 Final//EN\">\n"
+/** HTML 4.0 Strict Doctype */
+#define DOCTYPE_HTML_4_0S "<!DOCTYPE HTML PUBLIC \"-//W3C//" \
+ "DTD HTML 4.0//EN\"\n" \
+ "\"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
+/** HTML 4.0 Transitional Doctype */
+#define DOCTYPE_HTML_4_0T "<!DOCTYPE HTML PUBLIC \"-//W3C//" \
+ "DTD HTML 4.0 Transitional//EN\"\n" \
+ "\"http://www.w3.org/TR/REC-html40/loose.dtd\">\n"
+/** HTML 4.0 Frameset Doctype */
+#define DOCTYPE_HTML_4_0F "<!DOCTYPE HTML PUBLIC \"-//W3C//" \
+ "DTD HTML 4.0 Frameset//EN\"\n" \
+ "\"http://www.w3.org/TR/REC-html40/frameset.dtd\">\n"
+/** XHTML 1.0 Strict Doctype */
+#define DOCTYPE_XHTML_1_0S "<!DOCTYPE html PUBLIC \"-//W3C//" \
+ "DTD XHTML 1.0 Strict//EN\"\n" \
+ "\"http://www.w3.org/TR/xhtml1/DTD/" \
+ "xhtml1-strict.dtd\">\n"
+/** XHTML 1.0 Transitional Doctype */
+#define DOCTYPE_XHTML_1_0T "<!DOCTYPE html PUBLIC \"-//W3C//" \
+ "DTD XHTML 1.0 Transitional//EN\"\n" \
+ "\"http://www.w3.org/TR/xhtml1/DTD/" \
+ "xhtml1-transitional.dtd\">\n"
+/** XHTML 1.0 Frameset Doctype */
+#define DOCTYPE_XHTML_1_0F "<!DOCTYPE html PUBLIC \"-//W3C//" \
+ "DTD XHTML 1.0 Frameset//EN\"\n" \
+ "\"http://www.w3.org/TR/xhtml1/DTD/" \
+ "xhtml1-frameset.dtd\">"
+
+/** Internal representation for a HTTP protocol number, e.g., HTTP/1.1 */
+#define HTTP_VERSION(major,minor) (1000*(major)+(minor))
+/** Major part of HTTP protocol */
+#define HTTP_VERSION_MAJOR(number) ((number)/1000)
+/** Minor part of HTTP protocol */
+#define HTTP_VERSION_MINOR(number) ((number)%1000)
+
+/* -------------- Port number for server running standalone --------------- */
+
+/** default HTTP Port */
+#define DEFAULT_HTTP_PORT 80
+/** default HTTPS Port */
+#define DEFAULT_HTTPS_PORT 443
+/**
+ * Check whether @a port is the default port for the request @a r.
+ * @param port The port number
+ * @param r The request
+ * @see #ap_default_port
+ */
+#define ap_is_default_port(port,r) ((port) == ap_default_port(r))
+/**
+ * Get the default port for a request (which depends on the scheme).
+ * @param r The request
+ */
+#define ap_default_port(r) ap_run_default_port(r)
+/**
+ * Get the scheme for a request.
+ * @param r The request
+ */
+#define ap_http_scheme(r) ap_run_http_scheme(r)
+
+/** The default string length */
+#define MAX_STRING_LEN HUGE_STRING_LEN
+
+/** The length of a Huge string */
+#define HUGE_STRING_LEN 8192
+
+/** The size of the server's internal read-write buffers */
+#define AP_IOBUFSIZE 8192
+
+/** The max number of regex captures that can be expanded by ap_pregsub */
+#define AP_MAX_REG_MATCH 10
+
+/**
+ * APR_HAS_LARGE_FILES introduces the problem of spliting sendfile into
+ * multiple buckets, no greater than MAX(apr_size_t), and more granular
+ * than that in case the brigade code/filters attempt to read it directly.
+ * ### 16mb is an invention, no idea if it is reasonable.
+ */
+#define AP_MAX_SENDFILE 16777216 /* 2^24 */
+
+/**
+ * MPM child process exit status values
+ * The MPM parent process may check the status to see if special
+ * error handling is required.
+ */
+/** a normal exit */
+#define APEXIT_OK 0x0
+/** A fatal error arising during the server's init sequence */
+#define APEXIT_INIT 0x2
+/** The child died during its init sequence */
+#define APEXIT_CHILDINIT 0x3
+/**
+ * The child exited due to a resource shortage.
+ * The parent should limit the rate of forking until
+ * the situation is resolved.
+ */
+#define APEXIT_CHILDSICK 0x7
+/**
+ * A fatal error, resulting in the whole server aborting.
+ * If a child exits with this error, the parent process
+ * considers this a server-wide fatal error and aborts.
+ */
+#define APEXIT_CHILDFATAL 0xf
+
+#ifndef AP_DECLARE
+/**
+ * Stuff marked #AP_DECLARE is part of the API, and intended for use
+ * by modules. Its purpose is to allow us to add attributes that
+ * particular platforms or compilers require to every exported function.
+ */
+# define AP_DECLARE(type) type
+#endif
+
+#ifndef AP_DECLARE_NONSTD
+/**
+ * Stuff marked #AP_DECLARE_NONSTD is part of the API, and intended for
+ * use by modules. The difference between #AP_DECLARE and
+ * #AP_DECLARE_NONSTD is that the latter is required for any functions
+ * which use varargs or are used via indirect function call. This
+ * is to accommodate the two calling conventions in windows dlls.
+ */
+# define AP_DECLARE_NONSTD(type) type
+#endif
+#ifndef AP_DECLARE_DATA
+# define AP_DECLARE_DATA
+#endif
+
+#ifndef AP_MODULE_DECLARE
+# define AP_MODULE_DECLARE(type) type
+#endif
+#ifndef AP_MODULE_DECLARE_NONSTD
+# define AP_MODULE_DECLARE_NONSTD(type) type
+#endif
+#ifndef AP_MODULE_DECLARE_DATA
+# define AP_MODULE_DECLARE_DATA
+#endif
+
+/**
+ * @internal
+ * modules should not use functions marked AP_CORE_DECLARE
+ */
+#ifndef AP_CORE_DECLARE
+# define AP_CORE_DECLARE AP_DECLARE
+#endif
+
+/**
+ * @internal
+ * modules should not use functions marked AP_CORE_DECLARE_NONSTD
+ */
+
+#ifndef AP_CORE_DECLARE_NONSTD
+# define AP_CORE_DECLARE_NONSTD AP_DECLARE_NONSTD
+#endif
+
+/**
+ * @defgroup APACHE_APR_STATUS_T HTTPD specific values of apr_status_t
+ * @{
+ */
+#define AP_START_USERERR (APR_OS_START_USERERR + 2000)
+#define AP_USERERR_LEN 1000
+
+/** The function declines to handle the request */
+#define AP_DECLINED (AP_START_USERERR + 0)
+
+/** @} */
+
+/**
+ * @brief The numeric version information is broken out into fields within this
+ * structure.
+ */
+typedef struct {
+ int major; /**< major number */
+ int minor; /**< minor number */
+ int patch; /**< patch number */
+ const char *add_string; /**< additional string like "-dev" */
+} ap_version_t;
+
+/**
+ * Return httpd's version information in a numeric form.
+ *
+ * @param version Pointer to a version structure for returning the version
+ * information.
+ */
+AP_DECLARE(void) ap_get_server_revision(ap_version_t *version);
+
+/**
+ * Get the server banner in a form suitable for sending over the
+ * network, with the level of information controlled by the
+ * ServerTokens directive.
+ * @return The server banner
+ */
+AP_DECLARE(const char *) ap_get_server_banner(void);
+
+/**
+ * Get the server description in a form suitable for local displays,
+ * status reports, or logging. This includes the detailed server
+ * version and information about some modules. It is not affected
+ * by the ServerTokens directive.
+ * @return The server description
+ */
+AP_DECLARE(const char *) ap_get_server_description(void);
+
+/**
+ * Add a component to the server description and banner strings
+ * @param pconf The pool to allocate the component from
+ * @param component The string to add
+ */
+AP_DECLARE(void) ap_add_version_component(apr_pool_t *pconf, const char *component);
+
+/**
+ * Get the date a time that the server was built
+ * @return The server build time string
+ */
+AP_DECLARE(const char *) ap_get_server_built(void);
+
+/* non-HTTP status codes returned by hooks */
+
+#define OK 0 /**< Module has handled this stage. */
+#define DECLINED -1 /**< Module declines to handle */
+#define DONE -2 /**< Module has served the response completely
+ * - it's safe to die() with no more output
+ */
+#define SUSPENDED -3 /**< Module will handle the remainder of the request.
+ * The core will never invoke the request again, */
+
+/** Returned by the bottom-most filter if no data was written.
+ * @see ap_pass_brigade(). */
+#define AP_NOBODY_WROTE -100
+/** Returned by the bottom-most filter if no data was read.
+ * @see ap_get_brigade(). */
+#define AP_NOBODY_READ -101
+/** Returned by any filter if the filter chain encounters an error
+ * and has already dealt with the error response.
+ */
+#define AP_FILTER_ERROR -102
+
+/**
+ * @defgroup HTTP_Status HTTP Status Codes
+ * @{
+ */
+/**
+ * The size of the static status_lines array in http_protocol.c for
+ * storing all of the potential response status-lines (a sparse table).
+ * When adding a new code here add it to status_lines as well.
+ * A future version should dynamically generate the apr_table_t at startup.
+ */
+#define RESPONSE_CODES 103
+
+#define HTTP_CONTINUE 100
+#define HTTP_SWITCHING_PROTOCOLS 101
+#define HTTP_PROCESSING 102
+#define HTTP_OK 200
+#define HTTP_CREATED 201
+#define HTTP_ACCEPTED 202
+#define HTTP_NON_AUTHORITATIVE 203
+#define HTTP_NO_CONTENT 204
+#define HTTP_RESET_CONTENT 205
+#define HTTP_PARTIAL_CONTENT 206
+#define HTTP_MULTI_STATUS 207
+#define HTTP_ALREADY_REPORTED 208
+#define HTTP_IM_USED 226
+#define HTTP_MULTIPLE_CHOICES 300
+#define HTTP_MOVED_PERMANENTLY 301
+#define HTTP_MOVED_TEMPORARILY 302
+#define HTTP_SEE_OTHER 303
+#define HTTP_NOT_MODIFIED 304
+#define HTTP_USE_PROXY 305
+#define HTTP_TEMPORARY_REDIRECT 307
+#define HTTP_PERMANENT_REDIRECT 308
+#define HTTP_BAD_REQUEST 400
+#define HTTP_UNAUTHORIZED 401
+#define HTTP_PAYMENT_REQUIRED 402
+#define HTTP_FORBIDDEN 403
+#define HTTP_NOT_FOUND 404
+#define HTTP_METHOD_NOT_ALLOWED 405
+#define HTTP_NOT_ACCEPTABLE 406
+#define HTTP_PROXY_AUTHENTICATION_REQUIRED 407
+#define HTTP_REQUEST_TIME_OUT 408
+#define HTTP_CONFLICT 409
+#define HTTP_GONE 410
+#define HTTP_LENGTH_REQUIRED 411
+#define HTTP_PRECONDITION_FAILED 412
+#define HTTP_REQUEST_ENTITY_TOO_LARGE 413
+#define HTTP_REQUEST_URI_TOO_LARGE 414
+#define HTTP_UNSUPPORTED_MEDIA_TYPE 415
+#define HTTP_RANGE_NOT_SATISFIABLE 416
+#define HTTP_EXPECTATION_FAILED 417
+#define HTTP_MISDIRECTED_REQUEST 421
+#define HTTP_UNPROCESSABLE_ENTITY 422
+#define HTTP_LOCKED 423
+#define HTTP_FAILED_DEPENDENCY 424
+#define HTTP_UPGRADE_REQUIRED 426
+#define HTTP_PRECONDITION_REQUIRED 428
+#define HTTP_TOO_MANY_REQUESTS 429
+#define HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE 431
+#define HTTP_UNAVAILABLE_FOR_LEGAL_REASONS 451
+#define HTTP_INTERNAL_SERVER_ERROR 500
+#define HTTP_NOT_IMPLEMENTED 501
+#define HTTP_BAD_GATEWAY 502
+#define HTTP_SERVICE_UNAVAILABLE 503
+#define HTTP_GATEWAY_TIME_OUT 504
+#define HTTP_VERSION_NOT_SUPPORTED 505
+#define HTTP_VARIANT_ALSO_VARIES 506
+#define HTTP_INSUFFICIENT_STORAGE 507
+#define HTTP_LOOP_DETECTED 508
+#define HTTP_NOT_EXTENDED 510
+#define HTTP_NETWORK_AUTHENTICATION_REQUIRED 511
+
+/** is the status code informational */
+#define ap_is_HTTP_INFO(x) (((x) >= 100)&&((x) < 200))
+/** is the status code OK ?*/
+#define ap_is_HTTP_SUCCESS(x) (((x) >= 200)&&((x) < 300))
+/** is the status code a redirect */
+#define ap_is_HTTP_REDIRECT(x) (((x) >= 300)&&((x) < 400))
+/** is the status code a error (client or server) */
+#define ap_is_HTTP_ERROR(x) (((x) >= 400)&&((x) < 600))
+/** is the status code a client error */
+#define ap_is_HTTP_CLIENT_ERROR(x) (((x) >= 400)&&((x) < 500))
+/** is the status code a server error */
+#define ap_is_HTTP_SERVER_ERROR(x) (((x) >= 500)&&((x) < 600))
+/** is the status code a (potentially) valid response code? */
+#define ap_is_HTTP_VALID_RESPONSE(x) (((x) >= 100)&&((x) < 600))
+
+/** should the status code drop the connection */
+#define ap_status_drops_connection(x) \
+ (((x) == HTTP_BAD_REQUEST) || \
+ ((x) == HTTP_REQUEST_TIME_OUT) || \
+ ((x) == HTTP_LENGTH_REQUIRED) || \
+ ((x) == HTTP_REQUEST_ENTITY_TOO_LARGE) || \
+ ((x) == HTTP_REQUEST_URI_TOO_LARGE) || \
+ ((x) == HTTP_INTERNAL_SERVER_ERROR) || \
+ ((x) == HTTP_SERVICE_UNAVAILABLE) || \
+ ((x) == HTTP_NOT_IMPLEMENTED))
+
+/** does the status imply header only response (i.e. never w/ a body)? */
+#define AP_STATUS_IS_HEADER_ONLY(x) ((x) == HTTP_NO_CONTENT || \
+ (x) == HTTP_NOT_MODIFIED)
+/** @} */
+
+/**
+ * @defgroup Methods List of Methods recognized by the server
+ * @ingroup APACHE_CORE_DAEMON
+ * @{
+ *
+ * @brief Methods recognized (but not necessarily handled) by the server.
+ *
+ * These constants are used in bit shifting masks of size int, so it is
+ * unsafe to have more methods than bits in an int. HEAD == M_GET.
+ * This list must be tracked by the list in http_protocol.c in routine
+ * ap_method_name_of().
+ *
+ */
+
+#define M_GET 0 /** RFC 2616: HTTP */
+#define M_PUT 1 /* : */
+#define M_POST 2
+#define M_DELETE 3
+#define M_CONNECT 4
+#define M_OPTIONS 5
+#define M_TRACE 6 /** RFC 2616: HTTP */
+#define M_PATCH 7 /** no rfc(!) ### remove this one? */
+#define M_PROPFIND 8 /** RFC 2518: WebDAV */
+#define M_PROPPATCH 9 /* : */
+#define M_MKCOL 10
+#define M_COPY 11
+#define M_MOVE 12
+#define M_LOCK 13
+#define M_UNLOCK 14 /** RFC 2518: WebDAV */
+#define M_VERSION_CONTROL 15 /** RFC 3253: WebDAV Versioning */
+#define M_CHECKOUT 16 /* : */
+#define M_UNCHECKOUT 17
+#define M_CHECKIN 18
+#define M_UPDATE 19
+#define M_LABEL 20
+#define M_REPORT 21
+#define M_MKWORKSPACE 22
+#define M_MKACTIVITY 23
+#define M_BASELINE_CONTROL 24
+#define M_MERGE 25
+#define M_INVALID 26 /** no valid method */
+
+/**
+ * METHODS needs to be equal to the number of bits
+ * we are using for limit masks.
+ */
+#define METHODS 64
+
+/**
+ * The method mask bit to shift for anding with a bitmask.
+ */
+#define AP_METHOD_BIT ((apr_int64_t)1)
+/** @} */
+
+
+/** @see ap_method_list_t */
+typedef struct ap_method_list_t ap_method_list_t;
+
+/**
+ * @struct ap_method_list_t
+ * @brief Structure for handling HTTP methods.
+ *
+ * Methods known to the server are accessed via a bitmask shortcut;
+ * extension methods are handled by an array.
+ */
+struct ap_method_list_t {
+ /** The bitmask used for known methods */
+ apr_int64_t method_mask;
+ /** the array used for extension methods */
+ apr_array_header_t *method_list;
+};
+
+/**
+ * @defgroup module_magic Module Magic mime types
+ * @{
+ */
+/** Magic for mod_cgi[d] */
+#define CGI_MAGIC_TYPE "application/x-httpd-cgi"
+/** Magic for mod_include */
+#define INCLUDES_MAGIC_TYPE "text/x-server-parsed-html"
+/** Magic for mod_include */
+#define INCLUDES_MAGIC_TYPE3 "text/x-server-parsed-html3"
+/** Magic for mod_dir */
+#define DIR_MAGIC_TYPE "httpd/unix-directory"
+/** Default for r->handler if no content-type set by type_checker */
+#define AP_DEFAULT_HANDLER_NAME ""
+#define AP_IS_DEFAULT_HANDLER_NAME(x) (*x == '\0')
+
+/** @} */
+/* Just in case your linefeed isn't the one the other end is expecting. */
+#if !APR_CHARSET_EBCDIC
+/** linefeed */
+#define LF 10
+/** carrige return */
+#define CR 13
+/** carrige return /Line Feed Combo */
+#define CRLF "\015\012"
+#else /* APR_CHARSET_EBCDIC */
+/* For platforms using the EBCDIC charset, the transition ASCII->EBCDIC is done
+ * in the buff package (bread/bputs/bwrite). Everywhere else, we use
+ * "native EBCDIC" CR and NL characters. These are therefore
+ * defined as
+ * '\r' and '\n'.
+ */
+#define CR '\r'
+#define LF '\n'
+#define CRLF "\r\n"
+#endif /* APR_CHARSET_EBCDIC */
+/** Useful for common code with either platform charset. */
+#define CRLF_ASCII "\015\012"
+
+/**
+ * @defgroup values_request_rec_body Possible values for request_rec.read_body
+ * @{
+ * Possible values for request_rec.read_body (set by handling module):
+ */
+
+/** Send 413 error if message has any body */
+#define REQUEST_NO_BODY 0
+/** Send 411 error if body without Content-Length */
+#define REQUEST_CHUNKED_ERROR 1
+/** If chunked, remove the chunks for me. */
+#define REQUEST_CHUNKED_DECHUNK 2
+/** @} // values_request_rec_body */
+
+/**
+ * @defgroup values_request_rec_used_path_info Possible values for request_rec.used_path_info
+ * @ingroup APACHE_CORE_DAEMON
+ * @{
+ * Possible values for request_rec.used_path_info:
+ */
+
+/** Accept the path_info from the request */
+#define AP_REQ_ACCEPT_PATH_INFO 0
+/** Return a 404 error if path_info was given */
+#define AP_REQ_REJECT_PATH_INFO 1
+/** Module may chose to use the given path_info */
+#define AP_REQ_DEFAULT_PATH_INFO 2
+
+/** @} // values_request_rec_used_path_info */
+
+
+/*
+ * Things which may vary per file-lookup WITHIN a request ---
+ * e.g., state of MIME config. Basically, the name of an object, info
+ * about the object, and any other info we may ahve which may need to
+ * change as we go poking around looking for it (e.g., overridden by
+ * .htaccess files).
+ *
+ * Note how the default state of almost all these things is properly
+ * zero, so that allocating it with pcalloc does the right thing without
+ * a whole lot of hairy initialization... so long as we are willing to
+ * make the (fairly) portable assumption that the bit pattern of a NULL
+ * pointer is, in fact, zero.
+ */
+
+/**
+ * @brief This represents the result of calling htaccess; these are cached for
+ * each request.
+ */
+struct htaccess_result {
+ /** the directory to which this applies */
+ const char *dir;
+ /** the overrides allowed for the .htaccess file */
+ int override;
+ /** the override options allowed for the .htaccess file */
+ int override_opts;
+ /** Table of allowed directives for override */
+ apr_table_t *override_list;
+ /** the configuration directives */
+ struct ap_conf_vector_t *htaccess;
+ /** the next one, or NULL if no more; N.B. never change this */
+ const struct htaccess_result *next;
+};
+
+/* The following four types define a hierarchy of activities, so that
+ * given a request_rec r you can write r->connection->server->process
+ * to get to the process_rec. While this reduces substantially the
+ * number of arguments that various hooks require beware that in
+ * threaded versions of the server you must consider multiplexing
+ * issues. */
+
+
+/** A structure that represents one process */
+typedef struct process_rec process_rec;
+/** A structure that represents a virtual server */
+typedef struct server_rec server_rec;
+/** A structure that represents one connection */
+typedef struct conn_rec conn_rec;
+/** A structure that represents the current request */
+typedef struct request_rec request_rec;
+/** A structure that represents the status of the current connection */
+typedef struct conn_state_t conn_state_t;
+
+/* ### would be nice to not include this from httpd.h ... */
+/* This comes after we have defined the request_rec type */
+#include "apr_uri.h"
+
+/**
+ * @brief A structure that represents one process
+ */
+struct process_rec {
+ /** Global pool. Cleared upon normal exit */
+ apr_pool_t *pool;
+ /** Configuration pool. Cleared upon restart */
+ apr_pool_t *pconf;
+ /** The program name used to execute the program */
+ const char *short_name;
+ /** The command line arguments */
+ const char * const *argv;
+ /** Number of command line arguments passed to the program */
+ int argc;
+};
+
+/**
+ * @brief A structure that represents the current request
+ */
+struct request_rec {
+ /** The pool associated with the request */
+ apr_pool_t *pool;
+ /** The connection to the client */
+ conn_rec *connection;
+ /** The virtual host for this request */
+ server_rec *server;
+
+ /** Pointer to the redirected request if this is an external redirect */
+ request_rec *next;
+ /** Pointer to the previous request if this is an internal redirect */
+ request_rec *prev;
+
+ /** Pointer to the main request if this is a sub-request
+ * (see http_request.h) */
+ request_rec *main;
+
+ /* Info about the request itself... we begin with stuff that only
+ * protocol.c should ever touch...
+ */
+ /** First line of request */
+ char *the_request;
+ /** HTTP/0.9, "simple" request (e.g. GET /foo\n w/no headers) */
+ int assbackwards;
+ /** A proxy request (calculated during post_read_request/translate_name)
+ * possible values PROXYREQ_NONE, PROXYREQ_PROXY, PROXYREQ_REVERSE,
+ * PROXYREQ_RESPONSE
+ */
+ int proxyreq;
+ /** HEAD request, as opposed to GET */
+ int header_only;
+ /** Protocol version number of protocol; 1.1 = 1001 */
+ int proto_num;
+ /** Protocol string, as given to us, or HTTP/0.9 */
+ char *protocol;
+ /** Host, as set by full URI or Host: */
+ const char *hostname;
+
+ /** Time when the request started */
+ apr_time_t request_time;
+
+ /** Status line, if set by script */
+ const char *status_line;
+ /** Status line */
+ int status;
+
+ /* Request method, two ways; also, protocol, etc.. Outside of protocol.c,
+ * look, but don't touch.
+ */
+
+ /** M_GET, M_POST, etc. */
+ int method_number;
+ /** Request method (eg. GET, HEAD, POST, etc.) */
+ const char *method;
+
+ /**
+ * 'allowed' is a bitvector of the allowed methods.
+ *
+ * A handler must ensure that the request method is one that
+ * it is capable of handling. Generally modules should DECLINE
+ * any request methods they do not handle. Prior to aborting the
+ * handler like this the handler should set r->allowed to the list
+ * of methods that it is willing to handle. This bitvector is used
+ * to construct the "Allow:" header required for OPTIONS requests,
+ * and HTTP_METHOD_NOT_ALLOWED and HTTP_NOT_IMPLEMENTED status codes.
+ *
+ * Since the default_handler deals with OPTIONS, all modules can
+ * usually decline to deal with OPTIONS. TRACE is always allowed,
+ * modules don't need to set it explicitly.
+ *
+ * Since the default_handler will always handle a GET, a
+ * module which does *not* implement GET should probably return
+ * HTTP_METHOD_NOT_ALLOWED. Unfortunately this means that a Script GET
+ * handler can't be installed by mod_actions.
+ */
+ apr_int64_t allowed;
+ /** Array of extension methods */
+ apr_array_header_t *allowed_xmethods;
+ /** List of allowed methods */
+ ap_method_list_t *allowed_methods;
+
+ /** byte count in stream is for body */
+ apr_off_t sent_bodyct;
+ /** body byte count, for easy access */
+ apr_off_t bytes_sent;
+ /** Last modified time of the requested resource */
+ apr_time_t mtime;
+
+ /* HTTP/1.1 connection-level features */
+
+ /** The Range: header */
+ const char *range;
+ /** The "real" content length */
+ apr_off_t clength;
+ /** sending chunked transfer-coding */
+ int chunked;
+
+ /** Method for reading the request body
+ * (eg. REQUEST_CHUNKED_ERROR, REQUEST_NO_BODY,
+ * REQUEST_CHUNKED_DECHUNK, etc...) */
+ int read_body;
+ /** reading chunked transfer-coding */
+ int read_chunked;
+ /** is client waiting for a 100 response? */
+ unsigned expecting_100;
+ /** The optional kept body of the request. */
+ apr_bucket_brigade *kept_body;
+ /** For ap_body_to_table(): parsed body */
+ /* XXX: ap_body_to_table has been removed. Remove body_table too or
+ * XXX: keep it to reintroduce ap_body_to_table without major bump? */
+ apr_table_t *body_table;
+ /** Remaining bytes left to read from the request body */
+ apr_off_t remaining;
+ /** Number of bytes that have been read from the request body */
+ apr_off_t read_length;
+
+ /* MIME header environments, in and out. Also, an array containing
+ * environment variables to be passed to subprocesses, so people can
+ * write modules to add to that environment.
+ *
+ * The difference between headers_out and err_headers_out is that the
+ * latter are printed even on error, and persist across internal redirects
+ * (so the headers printed for ErrorDocument handlers will have them).
+ *
+ * The 'notes' apr_table_t is for notes from one module to another, with no
+ * other set purpose in mind...
+ */
+
+ /** MIME header environment from the request */
+ apr_table_t *headers_in;
+ /** MIME header environment for the response */
+ apr_table_t *headers_out;
+ /** MIME header environment for the response, printed even on errors and
+ * persist across internal redirects */
+ apr_table_t *err_headers_out;
+ /** Array of environment variables to be used for sub processes */
+ apr_table_t *subprocess_env;
+ /** Notes from one module to another */
+ apr_table_t *notes;
+
+ /* content_type, handler, content_encoding, and all content_languages
+ * MUST be lowercased strings. They may be pointers to static strings;
+ * they should not be modified in place.
+ */
+ /** The content-type for the current request */
+ const char *content_type; /* Break these out --- we dispatch on 'em */
+ /** The handler string that we use to call a handler function */
+ const char *handler; /* What we *really* dispatch on */
+
+ /** How to encode the data */
+ const char *content_encoding;
+ /** Array of strings representing the content languages */
+ apr_array_header_t *content_languages;
+
+ /** variant list validator (if negotiated) */
+ char *vlist_validator;
+
+ /** If an authentication check was made, this gets set to the user name. */
+ char *user;
+ /** If an authentication check was made, this gets set to the auth type. */
+ char *ap_auth_type;
+
+ /* What object is being requested (either directly, or via include
+ * or content-negotiation mapping).
+ */
+
+ /** The URI without any parsing performed */
+ char *unparsed_uri;
+ /** The path portion of the URI, or "/" if no path provided */
+ char *uri;
+ /** The filename on disk corresponding to this response */
+ char *filename;
+ /** The true filename stored in the filesystem, as in the true alpha case
+ * and alias correction, e.g. "Image.jpeg" not "IMAGE$1.JPE" on Windows.
+ * The core map_to_storage canonicalizes r->filename when they mismatch */
+ char *canonical_filename;
+ /** The PATH_INFO extracted from this request */
+ char *path_info;
+ /** The QUERY_ARGS extracted from this request */
+ char *args;
+
+ /**
+ * Flag for the handler to accept or reject path_info on
+ * the current request. All modules should respect the
+ * AP_REQ_ACCEPT_PATH_INFO and AP_REQ_REJECT_PATH_INFO
+ * values, while AP_REQ_DEFAULT_PATH_INFO indicates they
+ * may follow existing conventions. This is set to the
+ * user's preference upon HOOK_VERY_FIRST of the fixups.
+ */
+ int used_path_info;
+
+ /** A flag to determine if the eos bucket has been sent yet */
+ int eos_sent;
+
+ /* Various other config info which may change with .htaccess files
+ * These are config vectors, with one void* pointer for each module
+ * (the thing pointed to being the module's business).
+ */
+
+ /** Options set in config files, etc. */
+ struct ap_conf_vector_t *per_dir_config;
+ /** Notes on *this* request */
+ struct ap_conf_vector_t *request_config;
+
+ /** Optional request log level configuration. Will usually point
+ * to a server or per_dir config, i.e. must be copied before
+ * modifying */
+ const struct ap_logconf *log;
+
+ /** Id to identify request in access and error log. Set when the first
+ * error log entry for this request is generated.
+ */
+ const char *log_id;
+
+ /**
+ * A linked list of the .htaccess configuration directives
+ * accessed by this request.
+ * N.B. always add to the head of the list, _never_ to the end.
+ * that way, a sub request's list can (temporarily) point to a parent's list
+ */
+ const struct htaccess_result *htaccess;
+
+ /** A list of output filters to be used for this request */
+ struct ap_filter_t *output_filters;
+ /** A list of input filters to be used for this request */
+ struct ap_filter_t *input_filters;
+
+ /** A list of protocol level output filters to be used for this
+ * request */
+ struct ap_filter_t *proto_output_filters;
+ /** A list of protocol level input filters to be used for this
+ * request */
+ struct ap_filter_t *proto_input_filters;
+
+ /** This response can not be cached */
+ int no_cache;
+ /** There is no local copy of this response */
+ int no_local_copy;
+
+ /** Mutex protect callbacks registered with ap_mpm_register_timed_callback
+ * from being run before the original handler finishes running
+ */
+ apr_thread_mutex_t *invoke_mtx;
+
+ /** A struct containing the components of URI */
+ apr_uri_t parsed_uri;
+ /** finfo.protection (st_mode) set to zero if no such file */
+ apr_finfo_t finfo;
+
+ /** remote address information from conn_rec, can be overridden if
+ * necessary by a module.
+ * This is the address that originated the request.
+ */
+ apr_sockaddr_t *useragent_addr;
+ char *useragent_ip;
+
+ /** MIME trailer environment from the request */
+ apr_table_t *trailers_in;
+ /** MIME trailer environment from the response */
+ apr_table_t *trailers_out;
+
+ /** Originator's DNS name, if known. NULL if DNS hasn't been checked,
+ * "" if it has and no address was found. N.B. Only access this though
+ * ap_get_useragent_host() */
+ char *useragent_host;
+ /** have we done double-reverse DNS? -1 yes/failure, 0 not yet,
+ * 1 yes/success
+ */
+ int double_reverse;
+};
+
+/**
+ * @defgroup ProxyReq Proxy request types
+ *
+ * Possible values of request_rec->proxyreq. A request could be normal,
+ * proxied or reverse proxied. Normally proxied and reverse proxied are
+ * grouped together as just "proxied", but sometimes it's necessary to
+ * tell the difference between the two, such as for authentication.
+ * @{
+ */
+
+#define PROXYREQ_NONE 0 /**< No proxy */
+#define PROXYREQ_PROXY 1 /**< Standard proxy */
+#define PROXYREQ_REVERSE 2 /**< Reverse proxy */
+#define PROXYREQ_RESPONSE 3 /**< Origin response */
+
+/* @} */
+
+/**
+ * @brief Enumeration of connection keepalive options
+ */
+typedef enum {
+ AP_CONN_UNKNOWN,
+ AP_CONN_CLOSE,
+ AP_CONN_KEEPALIVE
+} ap_conn_keepalive_e;
+
+/**
+ * @brief Structure to store things which are per connection
+ */
+struct conn_rec {
+ /** Pool associated with this connection */
+ apr_pool_t *pool;
+ /** Physical vhost this conn came in on */
+ server_rec *base_server;
+ /** used by http_vhost.c */
+ void *vhost_lookup_data;
+
+ /* Information about the connection itself */
+ /** local address */
+ apr_sockaddr_t *local_addr;
+ /** remote address; this is the end-point of the next hop, for the address
+ * of the request creator, see useragent_addr in request_rec
+ */
+ apr_sockaddr_t *client_addr;
+
+ /** Client's IP address; this is the end-point of the next hop, for the
+ * IP of the request creator, see useragent_ip in request_rec
+ */
+ char *client_ip;
+ /** Client's DNS name, if known. NULL if DNS hasn't been checked,
+ * "" if it has and no address was found. N.B. Only access this though
+ * get_remote_host() */
+ char *remote_host;
+ /** Only ever set if doing rfc1413 lookups. N.B. Only access this through
+ * get_remote_logname() */
+ char *remote_logname;
+
+ /** server IP address */
+ char *local_ip;
+ /** used for ap_get_server_name when UseCanonicalName is set to DNS
+ * (ignores setting of HostnameLookups) */
+ char *local_host;
+
+ /** ID of this connection; unique at any point in time */
+ long id;
+ /** Config vector containing pointers to connections per-server
+ * config structures. */
+ struct ap_conf_vector_t *conn_config;
+ /** Notes on *this* connection: send note from one module to
+ * another. must remain valid for all requests on this conn */
+ apr_table_t *notes;
+ /** A list of input filters to be used for this connection */
+ struct ap_filter_t *input_filters;
+ /** A list of output filters to be used for this connection */
+ struct ap_filter_t *output_filters;
+ /** handle to scoreboard information for this connection */
+ void *sbh;
+ /** The bucket allocator to use for all bucket/brigade creations */
+ struct apr_bucket_alloc_t *bucket_alloc;
+ /** The current state of this connection; may be NULL if not used by MPM */
+ conn_state_t *cs;
+ /** Is there data pending in the input filters? */
+ int data_in_input_filters;
+ /** Is there data pending in the output filters? */
+ int data_in_output_filters;
+
+ /** Are there any filters that clogg/buffer the input stream, breaking
+ * the event mpm.
+ */
+ unsigned int clogging_input_filters:1;
+
+ /** have we done double-reverse DNS? -1 yes/failure, 0 not yet,
+ * 1 yes/success */
+ signed int double_reverse:2;
+
+ /** Are we still talking? */
+ unsigned aborted;
+
+ /** Are we going to keep the connection alive for another request?
+ * @see ap_conn_keepalive_e */
+ ap_conn_keepalive_e keepalive;
+
+ /** How many times have we used it? */
+ int keepalives;
+
+ /** Optional connection log level configuration. May point to a server or
+ * per_dir config, i.e. must be copied before modifying */
+ const struct ap_logconf *log;
+
+ /** Id to identify this connection in error log. Set when the first
+ * error log entry for this connection is generated.
+ */
+ const char *log_id;
+
+
+ /** This points to the current thread being used to process this request,
+ * over the lifetime of a request, the value may change. Users of the connection
+ * record should not rely upon it staying the same between calls that involve
+ * the MPM.
+ */
+#if APR_HAS_THREADS
+ apr_thread_t *current_thread;
+#endif
+
+ /** The "real" master connection. NULL if I am the master. */
+ conn_rec *master;
+};
+
+/**
+ * Enumeration of connection states
+ * The two states CONN_STATE_LINGER_NORMAL and CONN_STATE_LINGER_SHORT may
+ * only be set by the MPM. Use CONN_STATE_LINGER outside of the MPM.
+ */
+typedef enum {
+ CONN_STATE_CHECK_REQUEST_LINE_READABLE,
+ CONN_STATE_READ_REQUEST_LINE,
+ CONN_STATE_HANDLER,
+ CONN_STATE_WRITE_COMPLETION,
+ CONN_STATE_SUSPENDED,
+ CONN_STATE_LINGER, /* connection may be closed with lingering */
+ CONN_STATE_LINGER_NORMAL, /* MPM has started lingering close with normal timeout */
+ CONN_STATE_LINGER_SHORT, /* MPM has started lingering close with short timeout */
+
+ CONN_STATE_NUM /* Number of states (keep/kept last) */
+} conn_state_e;
+
+typedef enum {
+ CONN_SENSE_DEFAULT,
+ CONN_SENSE_WANT_READ, /* next event must be read */
+ CONN_SENSE_WANT_WRITE /* next event must be write */
+} conn_sense_e;
+
+/**
+ * @brief A structure to contain connection state information
+ */
+struct conn_state_t {
+ /** Current state of the connection */
+ conn_state_e state;
+ /** Whether to read instead of write, or write instead of read */
+ conn_sense_e sense;
+};
+
+/* Per-vhost config... */
+
+/**
+ * The address 255.255.255.255, when used as a virtualhost address,
+ * will become the "default" server when the ip doesn't match other vhosts.
+ */
+#define DEFAULT_VHOST_ADDR 0xfffffffful
+
+
+/**
+ * @struct server_addr_rec
+ * @brief A structure to be used for Per-vhost config
+ */
+typedef struct server_addr_rec server_addr_rec;
+struct server_addr_rec {
+ /** The next server in the list */
+ server_addr_rec *next;
+ /** The name given in "<VirtualHost>" */
+ char *virthost;
+ /** The bound address, for this server */
+ apr_sockaddr_t *host_addr;
+ /** The bound port, for this server */
+ apr_port_t host_port;
+};
+
+struct ap_logconf {
+ /** The per-module log levels */
+ signed char *module_levels;
+
+ /** The log level for this server */
+ int level;
+};
+/**
+ * @brief A structure to store information for each virtual server
+ */
+struct server_rec {
+ /** The process this server is running in */
+ process_rec *process;
+ /** The next server in the list */
+ server_rec *next;
+
+ /* Log files --- note that transfer log is now in the modules... */
+
+ /** The name of the error log */
+ char *error_fname;
+ /** A file descriptor that references the error log */
+ apr_file_t *error_log;
+ /** The log level configuration */
+ struct ap_logconf log;
+
+ /* Module-specific configuration for server, and defaults... */
+
+ /** Config vector containing pointers to modules' per-server config
+ * structures. */
+ struct ap_conf_vector_t *module_config;
+ /** MIME type info, etc., before we start checking per-directory info */
+ struct ap_conf_vector_t *lookup_defaults;
+
+ /** The name of the server */
+ const char *defn_name;
+ /** The line of the config file that the server was defined on */
+ unsigned defn_line_number;
+ /** true if this is the virtual server */
+ char is_virtual;
+
+
+ /* Information for redirects */
+
+ /** for redirects, etc. */
+ apr_port_t port;
+ /** The server request scheme for redirect responses */
+ const char *server_scheme;
+
+ /* Contact information */
+
+ /** The admin's contact information */
+ char *server_admin;
+ /** The server hostname */
+ char *server_hostname;
+
+ /* Transaction handling */
+
+ /** I haven't got a clue */
+ server_addr_rec *addrs;
+ /** Timeout, as an apr interval, before we give up */
+ apr_interval_time_t timeout;
+ /** The apr interval we will wait for another request */
+ apr_interval_time_t keep_alive_timeout;
+ /** Maximum requests per connection */
+ int keep_alive_max;
+ /** Use persistent connections? */
+ int keep_alive;
+
+ /** Normal names for ServerAlias servers */
+ apr_array_header_t *names;
+ /** Wildcarded names for ServerAlias servers */
+ apr_array_header_t *wild_names;
+
+ /** Pathname for ServerPath */
+ const char *path;
+ /** Length of path */
+ int pathlen;
+
+ /** limit on size of the HTTP request line */
+ int limit_req_line;
+ /** limit on size of any request header field */
+ int limit_req_fieldsize;
+ /** limit on number of request header fields */
+ int limit_req_fields;
+
+ /** Opaque storage location */
+ void *context;
+
+ /** Whether the keepalive timeout is explicit (1) or
+ * inherited (0) from the base server (either first
+ * server on the same IP:port or main server) */
+ unsigned int keep_alive_timeout_set:1;
+};
+
+/**
+ * @struct ap_sload_t
+ * @brief A structure to hold server load params
+ */
+typedef struct ap_sload_t ap_sload_t;
+struct ap_sload_t {
+ /* percentage of process/threads ready/idle (0->100)*/
+ int idle;
+ /* percentage of process/threads busy (0->100) */
+ int busy;
+ /* total bytes served */
+ apr_off_t bytes_served;
+ /* total access count */
+ unsigned long access_count;
+};
+
+/**
+ * @struct ap_loadavg_t
+ * @brief A structure to hold various server loadavg
+ */
+typedef struct ap_loadavg_t ap_loadavg_t;
+struct ap_loadavg_t {
+ /* current loadavg, ala getloadavg() */
+ float loadavg;
+ /* 5 min loadavg */
+ float loadavg5;
+ /* 15 min loadavg */
+ float loadavg15;
+};
+
+/**
+ * Get the context_document_root for a request. This is a generalization of
+ * the document root, which is too limited in the presence of mappers like
+ * mod_userdir and mod_alias. The context_document_root is the directory
+ * on disk that maps to the context_prefix URI prefix.
+ * @param r The request
+ * @note For resources that do not map to the file system or for very complex
+ * mappings, this information may still be wrong.
+ */
+AP_DECLARE(const char *) ap_context_document_root(request_rec *r);
+
+/**
+ * Get the context_prefix for a request. The context_prefix URI prefix
+ * maps to the context_document_root on disk.
+ * @param r The request
+ */
+AP_DECLARE(const char *) ap_context_prefix(request_rec *r);
+
+/** Set context_prefix and context_document_root for a request.
+ * @param r The request
+ * @param prefix the URI prefix, without trailing slash
+ * @param document_root the corresponding directory on disk, without trailing
+ * slash
+ * @note If one of prefix of document_root is NULL, the corrsponding
+ * property will not be changed.
+ */
+AP_DECLARE(void) ap_set_context_info(request_rec *r, const char *prefix,
+ const char *document_root);
+
+/** Set per-request document root. This is for mass virtual hosting modules
+ * that want to provide the correct DOCUMENT_ROOT value to scripts.
+ * @param r The request
+ * @param document_root the document root for the request.
+ */
+AP_DECLARE(void) ap_set_document_root(request_rec *r, const char *document_root);
+
+/**
+ * Examine a field value (such as a media-/content-type) string and return
+ * it sans any parameters; e.g., strip off any ';charset=foo' and the like.
+ * @param p Pool to allocate memory from
+ * @param intype The field to examine
+ * @return A copy of the field minus any parameters
+ */
+AP_DECLARE(char *) ap_field_noparam(apr_pool_t *p, const char *intype);
+
+/**
+ * Convert a time from an integer into a string in a specified format
+ * @param p The pool to allocate memory from
+ * @param t The time to convert
+ * @param fmt The format to use for the conversion
+ * @param gmt Convert the time for GMT?
+ * @return The string that represents the specified time
+ */
+AP_DECLARE(char *) ap_ht_time(apr_pool_t *p, apr_time_t t, const char *fmt, int gmt);
+
+/* String handling. The *_nc variants allow you to use non-const char **s as
+ arguments (unfortunately C won't automatically convert a char ** to a const
+ char **) */
+
+/**
+ * Get the characters until the first occurrence of a specified character
+ * @param p The pool to allocate memory from
+ * @param line The string to get the characters from
+ * @param stop The character to stop at
+ * @return A copy of the characters up to the first stop character
+ */
+AP_DECLARE(char *) ap_getword(apr_pool_t *p, const char **line, char stop);
+
+/**
+ * Get the characters until the first occurrence of a specified character
+ * @param p The pool to allocate memory from
+ * @param line The string to get the characters from
+ * @param stop The character to stop at
+ * @return A copy of the characters up to the first stop character
+ * @note This is the same as ap_getword(), except it doesn't use const char **.
+ */
+AP_DECLARE(char *) ap_getword_nc(apr_pool_t *p, char **line, char stop);
+
+/**
+ * Get the first word from a given string. A word is defined as all characters
+ * up to the first whitespace.
+ * @param p The pool to allocate memory from
+ * @param line The string to traverse
+ * @return The first word in the line
+ */
+AP_DECLARE(char *) ap_getword_white(apr_pool_t *p, const char **line);
+
+/**
+ * Get the first word from a given string. A word is defined as all characters
+ * up to the first whitespace.
+ * @param p The pool to allocate memory from
+ * @param line The string to traverse
+ * @return The first word in the line
+ * @note The same as ap_getword_white(), except it doesn't use const char**
+ */
+AP_DECLARE(char *) ap_getword_white_nc(apr_pool_t *p, char **line);
+
+/**
+ * Get all characters from the first occurrence of @a stop to the first "\0"
+ * @param p The pool to allocate memory from
+ * @param line The line to traverse
+ * @param stop The character to start at
+ * @return A copy of all characters after the first occurrence of the specified
+ * character
+ */
+AP_DECLARE(char *) ap_getword_nulls(apr_pool_t *p, const char **line,
+ char stop);
+
+/**
+ * Get all characters from the first occurrence of @a stop to the first "\0"
+ * @param p The pool to allocate memory from
+ * @param line The line to traverse
+ * @param stop The character to start at
+ * @return A copy of all characters after the first occurrence of the specified
+ * character
+ * @note The same as ap_getword_nulls(), except it doesn't use const char **.
+ */
+AP_DECLARE(char *) ap_getword_nulls_nc(apr_pool_t *p, char **line, char stop);
+
+/**
+ * Get the second word in the string paying attention to quoting
+ * @param p The pool to allocate from
+ * @param line The line to traverse
+ * @return A copy of the string
+ */
+AP_DECLARE(char *) ap_getword_conf(apr_pool_t *p, const char **line);
+
+/**
+ * Get the second word in the string paying attention to quoting
+ * @param p The pool to allocate from
+ * @param line The line to traverse
+ * @return A copy of the string
+ * @note The same as ap_getword_conf(), except it doesn't use const char **.
+ */
+AP_DECLARE(char *) ap_getword_conf_nc(apr_pool_t *p, char **line);
+
+/**
+ * Get the second word in the string paying attention to quoting,
+ * with {...} supported as well as "..." and '...'
+ * @param p The pool to allocate from
+ * @param line The line to traverse
+ * @return A copy of the string
+ */
+AP_DECLARE(char *) ap_getword_conf2(apr_pool_t *p, const char **line);
+
+/**
+ * Get the second word in the string paying attention to quoting,
+ * with {...} supported as well as "..." and '...'
+ * @param p The pool to allocate from
+ * @param line The line to traverse
+ * @return A copy of the string
+ * @note The same as ap_getword_conf2(), except it doesn't use const char **.
+ */
+AP_DECLARE(char *) ap_getword_conf2_nc(apr_pool_t *p, char **line);
+
+/**
+ * Check a string for any config define or environment variable construct
+ * and replace each of them by the value of that variable, if it exists.
+ * The default syntax of the constructs is ${ENV} but can be changed by
+ * setting the define::* config defines. If the variable does not exist,
+ * leave the ${ENV} construct alone but print a warning.
+ * @param p The pool to allocate from
+ * @param word The string to check
+ * @return The string with the replaced environment variables
+ */
+AP_DECLARE(const char *) ap_resolve_env(apr_pool_t *p, const char * word);
+
+/**
+ * Size an HTTP header field list item, as separated by a comma.
+ * @param field The field to size
+ * @param len The length of the field
+ * @return The return value is a pointer to the beginning of the non-empty
+ * list item within the original string (or NULL if there is none) and the
+ * address of field is shifted to the next non-comma, non-whitespace
+ * character. len is the length of the item excluding any beginning whitespace.
+ */
+AP_DECLARE(const char *) ap_size_list_item(const char **field, int *len);
+
+/**
+ * Retrieve an HTTP header field list item, as separated by a comma,
+ * while stripping insignificant whitespace and lowercasing anything not in
+ * a quoted string or comment.
+ * @param p The pool to allocate from
+ * @param field The field to retrieve
+ * @return The return value is a new string containing the converted list
+ * item (or NULL if none) and the address pointed to by field is
+ * shifted to the next non-comma, non-whitespace.
+ */
+AP_DECLARE(char *) ap_get_list_item(apr_pool_t *p, const char **field);
+
+/**
+ * Find an item in canonical form (lowercase, no extra spaces) within
+ * an HTTP field value list.
+ * @param p The pool to allocate from
+ * @param line The field value list to search
+ * @param tok The token to search for
+ * @return 1 if found, 0 if not found.
+ */
+AP_DECLARE(int) ap_find_list_item(apr_pool_t *p, const char *line, const char *tok);
+
+/**
+ * Do a weak ETag comparison within an HTTP field value list.
+ * @param p The pool to allocate from
+ * @param line The field value list to search
+ * @param tok The token to search for
+ * @return 1 if found, 0 if not found.
+ */
+AP_DECLARE(int) ap_find_etag_weak(apr_pool_t *p, const char *line, const char *tok);
+
+/**
+ * Do a strong ETag comparison within an HTTP field value list.
+ * @param p The pool to allocate from
+ * @param line The field value list to search
+ * @param tok The token to search for
+ * @return 1 if found, 0 if not found.
+ */
+AP_DECLARE(int) ap_find_etag_strong(apr_pool_t *p, const char *line, const char *tok);
+
+/* Scan a string for field content chars, as defined by RFC7230 section 3.2
+ * including VCHAR/obs-text, as well as HT and SP
+ * @param ptr The string to scan
+ * @return A pointer to the first (non-HT) ASCII ctrl character.
+ * @note lws and trailing whitespace are scanned, the caller is responsible
+ * for trimming leading and trailing whitespace
+ */
+AP_DECLARE(const char *) ap_scan_http_field_content(const char *ptr);
+
+/* Scan a string for token characters, as defined by RFC7230 section 3.2.6
+ * @param ptr The string to scan
+ * @return A pointer to the first non-token character.
+ */
+AP_DECLARE(const char *) ap_scan_http_token(const char *ptr);
+
+/* Scan a string for visible ASCII (0x21-0x7E) or obstext (0x80+)
+ * and return a pointer to the first SP/CTL/NUL character encountered.
+ * @param ptr The string to scan
+ * @return A pointer to the first SP/CTL character.
+ */
+AP_DECLARE(const char *) ap_scan_vchar_obstext(const char *ptr);
+
+/**
+ * Retrieve an array of tokens in the format "1#token" defined in RFC2616. Only
+ * accepts ',' as a delimiter, does not accept quoted strings, and errors on
+ * any separator.
+ * @param p The pool to allocate from
+ * @param tok The line to read tokens from
+ * @param tokens Pointer to an array of tokens. If not NULL, must be an array
+ * of char*, otherwise it will be allocated on @a p when a token is found
+ * @param skip_invalid If true, when an invalid separator is encountered, it
+ * will be ignored.
+ * @return NULL on success, an error string otherwise.
+ * @remark *tokens may be NULL on output if NULL in input and no token is found
+ */
+AP_DECLARE(const char *) ap_parse_token_list_strict(apr_pool_t *p, const char *tok,
+ apr_array_header_t **tokens,
+ int skip_invalid);
+
+/**
+ * Retrieve a token, spacing over it and adjusting the pointer to
+ * the first non-white byte afterwards. Note that these tokens
+ * are delimited by semis and commas and can also be delimited
+ * by whitespace at the caller's option.
+ * @param p The pool to allocate from
+ * @param accept_line The line to retrieve the token from (adjusted afterwards)
+ * @param accept_white Is it delimited by whitespace
+ * @return the token
+ */
+AP_DECLARE(char *) ap_get_token(apr_pool_t *p, const char **accept_line, int accept_white);
+
+/**
+ * Find http tokens, see the definition of token from RFC2068
+ * @param p The pool to allocate from
+ * @param line The line to find the token
+ * @param tok The token to find
+ * @return 1 if the token is found, 0 otherwise
+ */
+AP_DECLARE(int) ap_find_token(apr_pool_t *p, const char *line, const char *tok);
+
+/**
+ * find http tokens from the end of the line
+ * @param p The pool to allocate from
+ * @param line The line to find the token
+ * @param tok The token to find
+ * @return 1 if the token is found, 0 otherwise
+ */
+AP_DECLARE(int) ap_find_last_token(apr_pool_t *p, const char *line, const char *tok);
+
+/**
+ * Check for an Absolute URI syntax
+ * @param u The string to check
+ * @return 1 if URI, 0 otherwise
+ */
+AP_DECLARE(int) ap_is_url(const char *u);
+
+/**
+ * Unescape a string
+ * @param url The string to unescape
+ * @return 0 on success, non-zero otherwise
+ */
+AP_DECLARE(int) ap_unescape_all(char *url);
+
+/**
+ * Unescape a URL
+ * @param url The url to unescape
+ * @return 0 on success, non-zero otherwise
+ */
+AP_DECLARE(int) ap_unescape_url(char *url);
+
+/**
+ * Unescape a URL, but leaving %2f (slashes) escaped
+ * @param url The url to unescape
+ * @param decode_slashes Whether or not slashes should be decoded
+ * @return 0 on success, non-zero otherwise
+ */
+AP_DECLARE(int) ap_unescape_url_keep2f(char *url, int decode_slashes);
+
+/**
+ * Unescape an application/x-www-form-urlencoded string
+ * @param query The query to unescape
+ * @return 0 on success, non-zero otherwise
+ */
+AP_DECLARE(int) ap_unescape_urlencoded(char *query);
+
+/**
+ * Convert all double slashes to single slashes
+ * @param name The string to convert
+ */
+AP_DECLARE(void) ap_no2slash(char *name);
+
+/**
+ * Remove all ./ and xx/../ substrings from a file name. Also remove
+ * any leading ../ or /../ substrings.
+ * @param name the file name to parse
+ */
+AP_DECLARE(void) ap_getparents(char *name);
+
+/**
+ * Escape a path segment, as defined in RFC 1808
+ * @param p The pool to allocate from
+ * @param s The path to convert
+ * @return The converted URL
+ */
+AP_DECLARE(char *) ap_escape_path_segment(apr_pool_t *p, const char *s);
+
+/**
+ * Escape a path segment, as defined in RFC 1808, to a preallocated buffer.
+ * @param c The preallocated buffer to write to
+ * @param s The path to convert
+ * @return The converted URL (c)
+ */
+AP_DECLARE(char *) ap_escape_path_segment_buffer(char *c, const char *s);
+
+/**
+ * convert an OS path to a URL in an OS dependent way.
+ * @param p The pool to allocate from
+ * @param path The path to convert
+ * @param partial if set, assume that the path will be appended to something
+ * with a '/' in it (and thus does not prefix "./")
+ * @return The converted URL
+ */
+AP_DECLARE(char *) ap_os_escape_path(apr_pool_t *p, const char *path, int partial);
+
+/** @see ap_os_escape_path */
+#define ap_escape_uri(ppool,path) ap_os_escape_path(ppool,path,1)
+
+/**
+ * Escape a string as application/x-www-form-urlencoded
+ * @param p The pool to allocate from
+ * @param s The path to convert
+ * @return The converted URL
+ */
+AP_DECLARE(char *) ap_escape_urlencoded(apr_pool_t *p, const char *s);
+
+/**
+ * Escape a string as application/x-www-form-urlencoded, to a preallocated buffer
+ * @param c The preallocated buffer to write to
+ * @param s The path to convert
+ * @return The converted URL (c)
+ */
+AP_DECLARE(char *) ap_escape_urlencoded_buffer(char *c, const char *s);
+
+/**
+ * Escape an html string
+ * @param p The pool to allocate from
+ * @param s The html to escape
+ * @return The escaped string
+ */
+#define ap_escape_html(p,s) ap_escape_html2(p,s,0)
+/**
+ * Escape an html string
+ * @param p The pool to allocate from
+ * @param s The html to escape
+ * @param toasc Whether to escape all non-ASCII chars to \&\#nnn;
+ * @return The escaped string
+ */
+AP_DECLARE(char *) ap_escape_html2(apr_pool_t *p, const char *s, int toasc);
+
+/**
+ * Escape a string for logging
+ * @param p The pool to allocate from
+ * @param str The string to escape
+ * @return The escaped string
+ */
+AP_DECLARE(char *) ap_escape_logitem(apr_pool_t *p, const char *str);
+
+/**
+ * Escape a string for logging into the error log (without a pool)
+ * @param dest The buffer to write to
+ * @param source The string to escape
+ * @param buflen The buffer size for the escaped string (including "\0")
+ * @return The len of the escaped string (always < maxlen)
+ */
+AP_DECLARE(apr_size_t) ap_escape_errorlog_item(char *dest, const char *source,
+ apr_size_t buflen);
+
+/**
+ * Construct a full hostname
+ * @param p The pool to allocate from
+ * @param hostname The hostname of the server
+ * @param port The port the server is running on
+ * @param r The current request
+ * @return The server's hostname
+ */
+AP_DECLARE(char *) ap_construct_server(apr_pool_t *p, const char *hostname,
+ apr_port_t port, const request_rec *r);
+
+/**
+ * Escape a shell command
+ * @param p The pool to allocate from
+ * @param s The command to escape
+ * @return The escaped shell command
+ */
+AP_DECLARE(char *) ap_escape_shell_cmd(apr_pool_t *p, const char *s);
+
+/**
+ * Count the number of directories in a path
+ * @param path The path to count
+ * @return The number of directories
+ */
+AP_DECLARE(int) ap_count_dirs(const char *path);
+
+/**
+ * Copy at most @a n leading directories of @a s into @a d. @a d
+ * should be at least as large as @a s plus 1 extra byte
+ *
+ * @param d The location to copy to
+ * @param s The location to copy from
+ * @param n The number of directories to copy
+ * @return value is the ever useful pointer to the trailing "\0" of d
+ * @note on platforms with drive letters, n = 0 returns the "/" root,
+ * whereas n = 1 returns the "d:/" root. On all other platforms, n = 0
+ * returns the empty string. */
+AP_DECLARE(char *) ap_make_dirstr_prefix(char *d, const char *s, int n);
+
+/**
+ * Return the parent directory name (including trailing /) of the file
+ * @a s
+ * @param p The pool to allocate from
+ * @param s The file to get the parent of
+ * @return A copy of the file's parent directory
+ */
+AP_DECLARE(char *) ap_make_dirstr_parent(apr_pool_t *p, const char *s);
+
+/**
+ * Given a directory and filename, create a single path from them. This
+ * function is smart enough to ensure that there is a single '/' between the
+ * directory and file names
+ * @param a The pool to allocate from
+ * @param dir The directory name
+ * @param f The filename
+ * @return A copy of the full path
+ * @note Never consider using this function if you are dealing with filesystem
+ * names that need to remain canonical, unless you are merging an apr_dir_read
+ * path and returned filename. Otherwise, the result is not canonical.
+ */
+AP_DECLARE(char *) ap_make_full_path(apr_pool_t *a, const char *dir, const char *f);
+
+/**
+ * Test if the given path has an absolute path.
+ * @param p The pool to allocate from
+ * @param dir The directory name
+ * @note The converse is not necessarily true, some OS's (Win32/OS2/Netware) have
+ * multiple forms of absolute paths. This only reports if the path is absolute
+ * in a canonical sense.
+ */
+AP_DECLARE(int) ap_os_is_path_absolute(apr_pool_t *p, const char *dir);
+
+/**
+ * Does the provided string contain wildcard characters? This is useful
+ * for determining if the string should be passed to strcmp_match or to strcmp.
+ * The only wildcard characters recognized are '?' and '*'
+ * @param str The string to check
+ * @return 1 if the string has wildcards, 0 otherwise
+ */
+AP_DECLARE(int) ap_is_matchexp(const char *str);
+
+/**
+ * Determine if a string matches a pattern containing the wildcards '?' or '*'
+ * @param str The string to check
+ * @param expected The pattern to match against
+ * @return 0 if the two strings match, 1 otherwise
+ */
+AP_DECLARE(int) ap_strcmp_match(const char *str, const char *expected);
+
+/**
+ * Determine if a string matches a pattern containing the wildcards '?' or '*',
+ * ignoring case
+ * @param str The string to check
+ * @param expected The pattern to match against
+ * @return 0 if the two strings match, 1 otherwise
+ */
+AP_DECLARE(int) ap_strcasecmp_match(const char *str, const char *expected);
+
+/**
+ * Find the first occurrence of the substring s2 in s1, regardless of case
+ * @param s1 The string to search
+ * @param s2 The substring to search for
+ * @return A pointer to the beginning of the substring
+ * @remark See apr_strmatch() for a faster alternative
+ */
+AP_DECLARE(char *) ap_strcasestr(const char *s1, const char *s2);
+
+/**
+ * Return a pointer to the location inside of bigstring immediately after prefix
+ * @param bigstring The input string
+ * @param prefix The prefix to strip away
+ * @return A pointer relative to bigstring after prefix
+ */
+AP_DECLARE(const char *) ap_stripprefix(const char *bigstring,
+ const char *prefix);
+
+/**
+ * Decode a base64 encoded string into memory allocated from a pool
+ * @param p The pool to allocate from
+ * @param bufcoded The encoded string
+ * @return The decoded string
+ */
+AP_DECLARE(char *) ap_pbase64decode(apr_pool_t *p, const char *bufcoded);
+
+/**
+ * Encode a string into memory allocated from a pool in base 64 format
+ * @param p The pool to allocate from
+ * @param string The plaintext string
+ * @return The encoded string
+ */
+AP_DECLARE(char *) ap_pbase64encode(apr_pool_t *p, char *string);
+
+/**
+ * Compile a regular expression to be used later. The regex is freed when
+ * the pool is destroyed.
+ * @param p The pool to allocate from
+ * @param pattern the regular expression to compile
+ * @param cflags The bitwise or of one or more of the following:
+ * @li REG_EXTENDED - Use POSIX extended Regular Expressions
+ * @li REG_ICASE - Ignore case
+ * @li REG_NOSUB - Support for substring addressing of matches
+ * not required
+ * @li REG_NEWLINE - Match-any-character operators don't match new-line
+ * @return The compiled regular expression
+ */
+AP_DECLARE(ap_regex_t *) ap_pregcomp(apr_pool_t *p, const char *pattern,
+ int cflags);
+
+/**
+ * Free the memory associated with a compiled regular expression
+ * @param p The pool the regex was allocated from
+ * @param reg The regular expression to free
+ * @note This function is only necessary if the regex should be cleaned
+ * up before the pool
+ */
+AP_DECLARE(void) ap_pregfree(apr_pool_t *p, ap_regex_t *reg);
+
+/**
+ * After performing a successful regex match, you may use this function to
+ * perform a series of string substitutions based on subexpressions that were
+ * matched during the call to ap_regexec. This function is limited to
+ * result strings of 64K. Consider using ap_pregsub_ex() instead.
+ * @param p The pool to allocate from
+ * @param input An arbitrary string containing $1 through $9. These are
+ * replaced with the corresponding matched sub-expressions
+ * @param source The string that was originally matched to the regex
+ * @param nmatch the nmatch returned from ap_pregex
+ * @param pmatch the pmatch array returned from ap_pregex
+ * @return The substituted string, or NULL on error
+ */
+AP_DECLARE(char *) ap_pregsub(apr_pool_t *p, const char *input,
+ const char *source, apr_size_t nmatch,
+ ap_regmatch_t pmatch[]);
+
+/**
+ * After performing a successful regex match, you may use this function to
+ * perform a series of string substitutions based on subexpressions that were
+ * matched during the call to ap_regexec
+ * @param p The pool to allocate from
+ * @param result where to store the result, will be set to NULL on error
+ * @param input An arbitrary string containing $1 through $9. These are
+ * replaced with the corresponding matched sub-expressions
+ * @param source The string that was originally matched to the regex
+ * @param nmatch the nmatch returned from ap_pregex
+ * @param pmatch the pmatch array returned from ap_pregex
+ * @param maxlen the maximum string length to return, 0 for unlimited
+ * @return APR_SUCCESS if successful, APR_ENOMEM or other error code otherwise.
+ */
+AP_DECLARE(apr_status_t) ap_pregsub_ex(apr_pool_t *p, char **result,
+ const char *input, const char *source,
+ apr_size_t nmatch,
+ ap_regmatch_t pmatch[],
+ apr_size_t maxlen);
+
+/**
+ * We want to downcase the type/subtype for comparison purposes
+ * but nothing else because ;parameter=foo values are case sensitive.
+ * @param s The content-type to convert to lowercase
+ */
+AP_DECLARE(void) ap_content_type_tolower(char *s);
+
+/**
+ * convert a string to all lowercase
+ * @param s The string to convert to lowercase
+ */
+AP_DECLARE(void) ap_str_tolower(char *s);
+
+/**
+ * convert a string to all uppercase
+ * @param s The string to convert to uppercase
+ */
+AP_DECLARE(void) ap_str_toupper(char *s);
+
+/**
+ * Search a string from left to right for the first occurrence of a
+ * specific character
+ * @param str The string to search
+ * @param c The character to search for
+ * @return The index of the first occurrence of c in str
+ */
+AP_DECLARE(int) ap_ind(const char *str, char c); /* Sigh... */
+
+/**
+ * Search a string from right to left for the first occurrence of a
+ * specific character
+ * @param str The string to search
+ * @param c The character to search for
+ * @return The index of the first occurrence of c in str
+ */
+AP_DECLARE(int) ap_rind(const char *str, char c);
+
+/**
+ * Given a string, replace any bare &quot; with \\&quot; .
+ * @param p The pool to allocate memory from
+ * @param instring The string to search for &quot;
+ * @return A copy of the string with escaped quotes
+ */
+AP_DECLARE(char *) ap_escape_quotes(apr_pool_t *p, const char *instring);
+
+/**
+ * Given a string, append the PID deliminated by delim.
+ * Usually used to create a pid-appended filepath name
+ * (eg: /a/b/foo -> /a/b/foo.6726). A function, and not
+ * a macro, to avoid unistd.h dependency
+ * @param p The pool to allocate memory from
+ * @param string The string to append the PID to
+ * @param delim The string to use to deliminate the string from the PID
+ * @return A copy of the string with the PID appended
+ */
+AP_DECLARE(char *) ap_append_pid(apr_pool_t *p, const char *string,
+ const char *delim);
+
+/**
+ * Parse a given timeout parameter string into an apr_interval_time_t value.
+ * The unit of the time interval is given as postfix string to the numeric
+ * string. Currently the following units are understood:
+ *
+ * ms : milliseconds
+ * s : seconds
+ * mi[n] : minutes
+ * h : hours
+ *
+ * If no unit is contained in the given timeout parameter the default_time_unit
+ * will be used instead.
+ * @param timeout_parameter The string containing the timeout parameter.
+ * @param timeout The timeout value to be returned.
+ * @param default_time_unit The default time unit to use if none is specified
+ * in timeout_parameter.
+ * @return Status value indicating whether the parsing was successful or not.
+ */
+AP_DECLARE(apr_status_t) ap_timeout_parameter_parse(
+ const char *timeout_parameter,
+ apr_interval_time_t *timeout,
+ const char *default_time_unit);
+
+/**
+ * Determine if a request has a request body or not.
+ *
+ * @param r the request_rec of the request
+ * @return truth value
+ */
+AP_DECLARE(int) ap_request_has_body(request_rec *r);
+
+/**
+ * Cleanup a string (mainly to be filesystem safe)
+ * We only allow '_' and alphanumeric chars. Non-printable
+ * map to 'x' and all others map to '_'
+ *
+ * @param p pool to use to allocate dest
+ * @param src string to clean up
+ * @param dest cleaned up, allocated string
+ * @return Status value indicating whether the cleaning was successful or not.
+ */
+AP_DECLARE(apr_status_t) ap_pstr2_alnum(apr_pool_t *p, const char *src,
+ const char **dest);
+
+/**
+ * Cleanup a string (mainly to be filesystem safe)
+ * We only allow '_' and alphanumeric chars. Non-printable
+ * map to 'x' and all others map to '_'
+ *
+ * @param src string to clean up
+ * @param dest cleaned up, pre-allocated string
+ * @return Status value indicating whether the cleaning was successful or not.
+ */
+AP_DECLARE(apr_status_t) ap_str2_alnum(const char *src, char *dest);
+
+/**
+ * Structure to store the contents of an HTTP form of the type
+ * application/x-www-form-urlencoded.
+ *
+ * Currently it contains the name as a char* of maximum length
+ * HUGE_STRING_LEN, and a value in the form of a bucket brigade
+ * of arbitrary length.
+ */
+typedef struct {
+ const char *name;
+ apr_bucket_brigade *value;
+} ap_form_pair_t;
+
+/**
+ * Read the body and parse any form found, which must be of the
+ * type application/x-www-form-urlencoded.
+ * @param r request containing POSTed form data
+ * @param f filter
+ * @param ptr returned array of ap_form_pair_t
+ * @param num max num of params or -1 for unlimited
+ * @param size max size allowed for parsed data
+ * @return OK or HTTP error
+ */
+AP_DECLARE(int) ap_parse_form_data(request_rec *r, struct ap_filter_t *f,
+ apr_array_header_t **ptr,
+ apr_size_t num, apr_size_t size);
+
+/* Misc system hackery */
+/**
+ * Given the name of an object in the file system determine if it is a directory
+ * @param p The pool to allocate from
+ * @param name The name of the object to check
+ * @return 1 if it is a directory, 0 otherwise
+ */
+AP_DECLARE(int) ap_is_rdirectory(apr_pool_t *p, const char *name);
+
+/**
+ * Given the name of an object in the file system determine if it is a directory - this version is symlink aware
+ * @param p The pool to allocate from
+ * @param name The name of the object to check
+ * @return 1 if it is a directory, 0 otherwise
+ */
+AP_DECLARE(int) ap_is_directory(apr_pool_t *p, const char *name);
+
+#ifdef _OSD_POSIX
+extern int os_init_job_environment(server_rec *s, const char *user_name, int one_process);
+#endif /* _OSD_POSIX */
+
+/**
+ * Determine the local host name for the current machine
+ * @param p The pool to allocate from
+ * @return A copy of the local host name
+ */
+char *ap_get_local_host(apr_pool_t *p);
+
+/**
+ * Log an assertion to the error log
+ * @param szExp The assertion that failed
+ * @param szFile The file the assertion is in
+ * @param nLine The line the assertion is defined on
+ */
+AP_DECLARE(void) ap_log_assert(const char *szExp, const char *szFile, int nLine)
+ __attribute__((noreturn));
+
+/**
+ * @internal Internal Assert function
+ */
+#define ap_assert(exp) ((exp) ? (void)0 : ap_log_assert(#exp,__FILE__,__LINE__))
+
+/**
+ * Redefine assert() to something more useful for an Apache...
+ *
+ * Use ap_assert() if the condition should always be checked.
+ * Use AP_DEBUG_ASSERT() if the condition should only be checked when AP_DEBUG
+ * is defined.
+ */
+#ifdef AP_DEBUG
+#define AP_DEBUG_ASSERT(exp) ap_assert(exp)
+#else
+#define AP_DEBUG_ASSERT(exp) ((void)0)
+#endif
+
+/**
+ * @defgroup stopsignal Flags which indicate places where the server should stop for debugging.
+ * @{
+ * A set of flags which indicate places where the server should raise(SIGSTOP).
+ * This is useful for debugging, because you can then attach to that process
+ * with gdb and continue. This is important in cases where one_process
+ * debugging isn't possible.
+ */
+/** stop on a Detach */
+#define SIGSTOP_DETACH 1
+/** stop making a child process */
+#define SIGSTOP_MAKE_CHILD 2
+/** stop spawning a child process */
+#define SIGSTOP_SPAWN_CHILD 4
+/** stop spawning a child process with a piped log */
+#define SIGSTOP_PIPED_LOG_SPAWN 8
+/** stop spawning a CGI child process */
+#define SIGSTOP_CGI_CHILD 16
+
+/** Macro to get GDB started */
+#ifdef DEBUG_SIGSTOP
+extern int raise_sigstop_flags;
+#define RAISE_SIGSTOP(x) do { \
+ if (raise_sigstop_flags & SIGSTOP_##x) raise(SIGSTOP);\
+ } while (0)
+#else
+#define RAISE_SIGSTOP(x)
+#endif
+/** @} */
+/**
+ * Get HTML describing the address and (optionally) admin of the server.
+ * @param prefix Text which is prepended to the return value
+ * @param r The request_rec
+ * @return HTML describing the server, allocated in @a r's pool.
+ */
+AP_DECLARE(const char *) ap_psignature(const char *prefix, request_rec *r);
+
+ /* The C library has functions that allow const to be silently dropped ...
+ these macros detect the drop in maintainer mode, but use the native
+ methods for normal builds
+
+ Note that on some platforms (e.g., AIX with gcc, Solaris with gcc), string.h needs
+ to be included before the macros are defined or compilation will fail.
+ */
+#include <string.h>
+
+AP_DECLARE(char *) ap_strchr(char *s, int c);
+AP_DECLARE(const char *) ap_strchr_c(const char *s, int c);
+AP_DECLARE(char *) ap_strrchr(char *s, int c);
+AP_DECLARE(const char *) ap_strrchr_c(const char *s, int c);
+AP_DECLARE(char *) ap_strstr(char *s, const char *c);
+AP_DECLARE(const char *) ap_strstr_c(const char *s, const char *c);
+
+#ifdef AP_DEBUG
+
+#undef strchr
+# define strchr(s, c) ap_strchr(s,c)
+#undef strrchr
+# define strrchr(s, c) ap_strrchr(s,c)
+#undef strstr
+# define strstr(s, c) ap_strstr(s,c)
+
+#else
+
+/** use this instead of strchr */
+# define ap_strchr(s, c) strchr(s, c)
+/** use this instead of strchr */
+# define ap_strchr_c(s, c) strchr(s, c)
+/** use this instead of strrchr */
+# define ap_strrchr(s, c) strrchr(s, c)
+/** use this instead of strrchr */
+# define ap_strrchr_c(s, c) strrchr(s, c)
+/** use this instead of strrstr*/
+# define ap_strstr(s, c) strstr(s, c)
+/** use this instead of strrstr*/
+# define ap_strstr_c(s, c) strstr(s, c)
+
+#endif
+
+/**
+ * Generate pseudo random bytes.
+ * This is a convenience interface to apr_random. It is cheaper but less
+ * secure than apr_generate_random_bytes().
+ * @param buf where to store the bytes
+ * @param size number of bytes to generate
+ * @note ap_random_insecure_bytes() is thread-safe, it uses a mutex on
+ * threaded MPMs.
+ */
+AP_DECLARE(void) ap_random_insecure_bytes(void *buf, apr_size_t size);
+
+/**
+ * Get a pseudo random number in a range.
+ * @param min low end of range
+ * @param max high end of range
+ * @return a number in the range
+ */
+AP_DECLARE(apr_uint32_t) ap_random_pick(apr_uint32_t min, apr_uint32_t max);
+
+/**
+ * Abort with a error message signifying out of memory
+ */
+AP_DECLARE(void) ap_abort_on_oom(void) __attribute__((noreturn));
+
+/**
+ * Wrapper for malloc() that calls ap_abort_on_oom() if out of memory
+ * @param size size of the memory block
+ * @return pointer to the allocated memory
+ * @note ap_malloc may be implemented as a macro
+ */
+AP_DECLARE(void *) ap_malloc(size_t size)
+ __attribute__((malloc))
+ AP_FN_ATTR_ALLOC_SIZE(1);
+
+/**
+ * Wrapper for calloc() that calls ap_abort_on_oom() if out of memory
+ * @param nelem number of elements to allocate memory for
+ * @param size size of a single element
+ * @return pointer to the allocated memory
+ * @note ap_calloc may be implemented as a macro
+ */
+AP_DECLARE(void *) ap_calloc(size_t nelem, size_t size)
+ __attribute__((malloc))
+ AP_FN_ATTR_ALLOC_SIZE2(1,2);
+
+/**
+ * Wrapper for realloc() that calls ap_abort_on_oom() if out of memory
+ * @param ptr pointer to the old memory block (or NULL)
+ * @param size new size of the memory block
+ * @return pointer to the reallocated memory
+ * @note ap_realloc may be implemented as a macro
+ */
+AP_DECLARE(void *) ap_realloc(void *ptr, size_t size)
+ AP_FN_ATTR_WARN_UNUSED_RESULT
+ AP_FN_ATTR_ALLOC_SIZE(2);
+
+/**
+ * Get server load params
+ * @param ld struct to populate: -1 in fields means error
+ */
+AP_DECLARE(void) ap_get_sload(ap_sload_t *ld);
+
+/**
+ * Get server load averages (ala getloadavg)
+ * @param ld struct to populate: -1 in fields means error
+ */
+AP_DECLARE(void) ap_get_loadavg(ap_loadavg_t *ld);
+
+/**
+ * Convert binary data into a hex string
+ * @param src pointer to the data
+ * @param srclen length of the data
+ * @param dest pointer to buffer of length (2 * srclen + 1). The resulting
+ * string will be NUL-terminated.
+ */
+AP_DECLARE(void) ap_bin2hex(const void *src, apr_size_t srclen, char *dest);
+
+/**
+ * Short function to execute a command and return the first line of
+ * output minus \r \n. Useful for "obscuring" passwords via exec calls
+ * @param p the pool to allocate from
+ * @param cmd the command to execute
+ * @param argv the arguments to pass to the cmd
+ * @return ptr to characters or NULL on any error
+ */
+AP_DECLARE(char *) ap_get_exec_line(apr_pool_t *p,
+ const char *cmd,
+ const char * const *argv);
+
+#define AP_NORESTART APR_OS_START_USEERR + 1
+
+/**
+ * Get the first index of the string in the array or -1 if not found. Start
+ * searching a start.
+ * @param array The array the check
+ * @param s The string to find
+ * @param start Start index for search. If start is out of bounds (negative or
+ equal to array length or greater), -1 will be returned.
+ * @return index of string in array or -1
+ */
+AP_DECLARE(int) ap_array_str_index(const apr_array_header_t *array,
+ const char *s,
+ int start);
+
+/**
+ * Check if the string is member of the given array by strcmp.
+ * @param array The array the check
+ * @param s The string to find
+ * @return !=0 iff string is member of array (via strcmp)
+ */
+AP_DECLARE(int) ap_array_str_contains(const apr_array_header_t *array,
+ const char *s);
+
+/**
+ * Perform a case-insensitive comparison of two strings @a str1 and @a str2,
+ * treating upper and lower case values of the 26 standard C/POSIX alphabetic
+ * characters as equivalent. Extended latin characters outside of this set
+ * are treated as unique octets, irrespective of the current locale.
+ *
+ * Returns in integer greater than, equal to, or less than 0,
+ * according to whether @a str1 is considered greater than, equal to,
+ * or less than @a str2.
+ *
+ * @note Same code as apr_cstr_casecmp, which arrives in APR 1.6
+ */
+AP_DECLARE(int) ap_cstr_casecmp(const char *s1, const char *s2);
+
+/**
+ * Perform a case-insensitive comparison of two strings @a str1 and @a str2,
+ * treating upper and lower case values of the 26 standard C/POSIX alphabetic
+ * characters as equivalent. Extended latin characters outside of this set
+ * are treated as unique octets, irrespective of the current locale.
+ *
+ * Returns in integer greater than, equal to, or less than 0,
+ * according to whether @a str1 is considered greater than, equal to,
+ * or less than @a str2.
+ *
+ * @note Same code as apr_cstr_casecmpn, which arrives in APR 1.6
+ */
+AP_DECLARE(int) ap_cstr_casecmpn(const char *s1, const char *s2, apr_size_t n);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !APACHE_HTTPD_H */
+
+/** @} //APACHE Daemon */
+/** @} //APACHE Core */
+/** @} //APACHE super group */
+
diff --git a/include/mod_auth.h b/include/mod_auth.h
new file mode 100644
index 0000000..9b9561e
--- /dev/null
+++ b/include/mod_auth.h
@@ -0,0 +1,141 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file mod_auth.h
+ * @brief Authentication and Authorization Extension for Apache
+ *
+ * @defgroup MOD_AUTH mod_auth
+ * @ingroup APACHE_MODS
+ */
+
+#ifndef APACHE_MOD_AUTH_H
+#define APACHE_MOD_AUTH_H
+
+#include "apr_pools.h"
+#include "apr_hash.h"
+#include "apr_optional.h"
+
+#include "httpd.h"
+#include "http_config.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define AUTHN_PROVIDER_GROUP "authn"
+#define AUTHZ_PROVIDER_GROUP "authz"
+#define AUTHN_PROVIDER_VERSION "0"
+#define AUTHZ_PROVIDER_VERSION "0"
+#define AUTHN_DEFAULT_PROVIDER "file"
+
+#define AUTHN_PROVIDER_NAME_NOTE "authn_provider_name"
+#define AUTHZ_PROVIDER_NAME_NOTE "authz_provider_name"
+
+#define AUTHN_PREFIX "AUTHENTICATE_"
+#define AUTHZ_PREFIX "AUTHORIZE_"
+
+/** all of the requirements must be met */
+#ifndef SATISFY_ALL
+#define SATISFY_ALL 0
+#endif
+/** any of the requirements must be met */
+#ifndef SATISFY_ANY
+#define SATISFY_ANY 1
+#endif
+/** There are no applicable satisfy lines */
+#ifndef SATISFY_NOSPEC
+#define SATISFY_NOSPEC 2
+#endif
+
+typedef enum {
+ AUTH_DENIED,
+ AUTH_GRANTED,
+ AUTH_USER_FOUND,
+ AUTH_USER_NOT_FOUND,
+ AUTH_GENERAL_ERROR
+} authn_status;
+
+typedef enum {
+ AUTHZ_DENIED,
+ AUTHZ_GRANTED,
+ AUTHZ_NEUTRAL,
+ AUTHZ_GENERAL_ERROR,
+ AUTHZ_DENIED_NO_USER /* denied because r->user == NULL */
+} authz_status;
+
+typedef struct {
+ /* Given a username and password, expected to return AUTH_GRANTED
+ * if we can validate this user/password combination.
+ */
+ authn_status (*check_password)(request_rec *r, const char *user,
+ const char *password);
+
+ /* Given a user and realm, expected to return AUTH_USER_FOUND if we
+ * can find a md5 hash of 'user:realm:password'
+ */
+ authn_status (*get_realm_hash)(request_rec *r, const char *user,
+ const char *realm, char **rethash);
+} authn_provider;
+
+/* A linked-list of authn providers. */
+typedef struct authn_provider_list authn_provider_list;
+
+struct authn_provider_list {
+ const char *provider_name;
+ const authn_provider *provider;
+ authn_provider_list *next;
+};
+
+typedef struct {
+ /* Given a request_rec, expected to return AUTHZ_GRANTED
+ * if we can authorize user access.
+ * @param r the request record
+ * @param require_line the argument to the authz provider
+ * @param parsed_require_line the value set by parse_require_line(), if any
+ */
+ authz_status (*check_authorization)(request_rec *r,
+ const char *require_line,
+ const void *parsed_require_line);
+
+ /** Check the syntax of a require line and optionally cache the parsed
+ * line. This function may be NULL.
+ * @param cmd the config directive
+ * @param require_line the argument to the authz provider
+ * @param parsed_require_line place to store parsed require_line for use by provider
+ * @return Error message or NULL on success
+ */
+ const char *(*parse_require_line)(cmd_parms *cmd, const char *require_line,
+ const void **parsed_require_line);
+} authz_provider;
+
+/* ap_authn_cache_store: Optional function for authn providers
+ * to enable cacheing their lookups with mod_authn_cache
+ * @param r The request rec
+ * @param module Module identifier
+ * @param user User name to authenticate
+ * @param realm Digest authn realm (NULL for basic authn)
+ * @param data The value looked up by the authn provider, to cache
+ */
+APR_DECLARE_OPTIONAL_FN(void, ap_authn_cache_store,
+ (request_rec*, const char*, const char*,
+ const char*, const char*));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/mod_core.h b/include/mod_core.h
new file mode 100644
index 0000000..8eab3e1
--- /dev/null
+++ b/include/mod_core.h
@@ -0,0 +1,103 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+/**
+ * @file mod_core.h
+ * @brief mod_core private header file
+ *
+ * @defgroup MOD_CORE mod_core
+ * @ingroup APACHE_MODS
+ * @{
+ */
+
+#ifndef MOD_CORE_H
+#define MOD_CORE_H
+
+#include "apr.h"
+#include "apr_buckets.h"
+
+#include "httpd.h"
+#include "util_filter.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Handles for core filters */
+AP_DECLARE_DATA extern ap_filter_rec_t *ap_http_input_filter_handle;
+AP_DECLARE_DATA extern ap_filter_rec_t *ap_http_header_filter_handle;
+AP_DECLARE_DATA extern ap_filter_rec_t *ap_chunk_filter_handle;
+AP_DECLARE_DATA extern ap_filter_rec_t *ap_http_outerror_filter_handle;
+AP_DECLARE_DATA extern ap_filter_rec_t *ap_byterange_filter_handle;
+
+/*
+ * These (input) filters are internal to the mod_core operation.
+ */
+apr_status_t ap_http_filter(ap_filter_t *f, apr_bucket_brigade *b,
+ ap_input_mode_t mode, apr_read_type_e block,
+ apr_off_t readbytes);
+
+/* HTTP/1.1 chunked transfer encoding filter. */
+apr_status_t ap_http_chunk_filter(ap_filter_t *f, apr_bucket_brigade *b);
+
+/* Filter to handle any error buckets on output */
+apr_status_t ap_http_outerror_filter(ap_filter_t *f,
+ apr_bucket_brigade *b);
+
+char *ap_response_code_string(request_rec *r, int error_index);
+
+/**
+ * Send the minimal part of an HTTP response header.
+ * @param r The current request
+ * @param bb The brigade to add the header to.
+ * @warning Modules should be very careful about using this, and should
+ * the default behavior. Much of the HTTP/1.1 implementation
+ * correctness depends on the full headers.
+ * @fn void ap_basic_http_header(request_rec *r, apr_bucket_brigade *bb)
+ */
+AP_DECLARE(void) ap_basic_http_header(request_rec *r, apr_bucket_brigade *bb);
+
+/**
+ * Send an appropriate response to an http TRACE request.
+ * @param r The current request
+ * @note returns DONE or the HTTP status error if it handles the TRACE,
+ * or DECLINED if the request was not for TRACE.
+ * request method was not TRACE.
+ */
+AP_DECLARE_NONSTD(int) ap_send_http_trace(request_rec *r);
+
+/**
+ * Send an appropriate response to an http OPTIONS request.
+ * @param r The current request
+ */
+AP_DECLARE(int) ap_send_http_options(request_rec *r);
+
+/* Used for multipart/byteranges boundary string */
+AP_DECLARE_DATA extern const char *ap_multipart_boundary;
+
+/* Init RNG at startup */
+AP_CORE_DECLARE(void) ap_init_rng(apr_pool_t *p);
+/* Update RNG state in parent after fork */
+AP_CORE_DECLARE(void) ap_random_parent_after_fork(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !MOD_CORE_H */
+/** @} */
diff --git a/include/mod_request.h b/include/mod_request.h
new file mode 100644
index 0000000..ed28c05
--- /dev/null
+++ b/include/mod_request.h
@@ -0,0 +1,64 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+/**
+ * @file mod_request.h
+ * @brief mod_request private header file
+ *
+ * @defgroup MOD_REQUEST mod_request
+ * @ingroup APACHE_MODS
+ * @{
+ */
+
+#ifndef MOD_REQUEST_H
+#define MOD_REQUEST_H
+
+#include "apr.h"
+#include "apr_buckets.h"
+#include "apr_optional.h"
+
+#include "httpd.h"
+#include "util_filter.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern module AP_MODULE_DECLARE_DATA request_module;
+
+#define KEEP_BODY_FILTER "KEEP_BODY"
+#define KEPT_BODY_FILTER "KEPT_BODY"
+
+/**
+ * Core per-directory configuration.
+ */
+typedef struct {
+ apr_off_t keep_body;
+ int keep_body_set;
+} request_dir_conf;
+
+APR_DECLARE_OPTIONAL_FN(void, ap_request_insert_filter, (request_rec * r));
+
+APR_DECLARE_OPTIONAL_FN(void, ap_request_remove_filter, (request_rec * r));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !MOD_REQUEST_H */
+/** @} */
diff --git a/include/mpm_common.h b/include/mpm_common.h
new file mode 100644
index 0000000..1284a7a
--- /dev/null
+++ b/include/mpm_common.h
@@ -0,0 +1,470 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* The purpose of this file is to store the code that MOST mpm's will need
+ * this does not mean a function only goes into this file if every MPM needs
+ * it. It means that if a function is needed by more than one MPM, and
+ * future maintenance would be served by making the code common, then the
+ * function belongs here.
+ *
+ * This is going in src/main because it is not platform specific, it is
+ * specific to multi-process servers, but NOT to Unix. Which is why it
+ * does not belong in src/os/unix
+ */
+
+/**
+ * @file mpm_common.h
+ * @brief Multi-Processing Modules functions
+ *
+ * @defgroup APACHE_MPM Multi-Processing Modules
+ * @ingroup APACHE
+ * @{
+ */
+
+#ifndef APACHE_MPM_COMMON_H
+#define APACHE_MPM_COMMON_H
+
+#include "ap_config.h"
+#include "ap_mpm.h"
+#include "scoreboard.h"
+
+#if APR_HAVE_NETINET_TCP_H
+#include <netinet/tcp.h> /* for TCP_NODELAY */
+#endif
+
+#include "apr_proc_mutex.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* The maximum length of the queue of pending connections, as defined
+ * by listen(2). Under some systems, it should be increased if you
+ * are experiencing a heavy TCP SYN flood attack.
+ *
+ * It defaults to 511 instead of 512 because some systems store it
+ * as an 8-bit datatype; 512 truncated to 8-bits is 0, while 511 is
+ * 255 when truncated.
+ */
+#ifndef DEFAULT_LISTENBACKLOG
+#define DEFAULT_LISTENBACKLOG 511
+#endif
+
+/* Signal used to gracefully restart */
+#define AP_SIG_GRACEFUL SIGUSR1
+
+/* Signal used to gracefully restart (without SIG prefix) */
+#define AP_SIG_GRACEFUL_SHORT USR1
+
+/* Signal used to gracefully restart (as a quoted string) */
+#define AP_SIG_GRACEFUL_STRING "SIGUSR1"
+
+/* Signal used to gracefully stop */
+#define AP_SIG_GRACEFUL_STOP SIGWINCH
+
+/* Signal used to gracefully stop (without SIG prefix) */
+#define AP_SIG_GRACEFUL_STOP_SHORT WINCH
+
+/* Signal used to gracefully stop (as a quoted string) */
+#define AP_SIG_GRACEFUL_STOP_STRING "SIGWINCH"
+
+/**
+ * Callback function used for ap_reclaim_child_processes() and
+ * ap_relieve_child_processes(). The callback function will be
+ * called for each terminated child process.
+ */
+typedef void ap_reclaim_callback_fn_t(int childnum, pid_t pid,
+ ap_generation_t gen);
+
+#if (!defined(WIN32) && !defined(NETWARE)) || defined(DOXYGEN)
+/**
+ * Make sure all child processes that have been spawned by the parent process
+ * have died. This includes process registered as "other_children".
+ *
+ * @param terminate Either 1 or 0. If 1, send the child processes SIGTERM
+ * each time through the loop. If 0, give the process time to die
+ * on its own before signalling it.
+ * @param mpm_callback Callback invoked for each dead child process
+ *
+ * @note The MPM child processes which are reclaimed are those listed
+ * in the scoreboard as well as those currently registered via
+ * ap_register_extra_mpm_process().
+ */
+AP_DECLARE(void) ap_reclaim_child_processes(int terminate,
+ ap_reclaim_callback_fn_t *mpm_callback);
+
+/**
+ * Catch any child processes that have been spawned by the parent process
+ * which have exited. This includes processes registered as "other_children".
+ *
+ * @param mpm_callback Callback invoked for each dead child process
+
+ * @note The MPM child processes which are relieved are those listed
+ * in the scoreboard as well as those currently registered via
+ * ap_register_extra_mpm_process().
+ */
+AP_DECLARE(void) ap_relieve_child_processes(ap_reclaim_callback_fn_t *mpm_callback);
+
+/**
+ * Tell ap_reclaim_child_processes() and ap_relieve_child_processes() about
+ * an MPM child process which has no entry in the scoreboard.
+ * @param pid The process id of an MPM child process which should be
+ * reclaimed when ap_reclaim_child_processes() is called.
+ * @param gen The generation of this MPM child process.
+ *
+ * @note If an extra MPM child process terminates prior to calling
+ * ap_reclaim_child_processes(), remove it from the list of such processes
+ * by calling ap_unregister_extra_mpm_process().
+ */
+AP_DECLARE(void) ap_register_extra_mpm_process(pid_t pid, ap_generation_t gen);
+
+/**
+ * Unregister an MPM child process which was previously registered by a
+ * call to ap_register_extra_mpm_process().
+ * @param pid The process id of an MPM child process which no longer needs to
+ * be reclaimed.
+ * @param old_gen Set to the server generation of the process, if found.
+ * @return 1 if the process was found and removed, 0 otherwise
+ */
+AP_DECLARE(int) ap_unregister_extra_mpm_process(pid_t pid, ap_generation_t *old_gen);
+
+/**
+ * Safely signal an MPM child process, if the process is in the
+ * current process group. Otherwise fail.
+ * @param pid the process id of a child process to signal
+ * @param sig the signal number to send
+ * @return APR_SUCCESS if signal is sent, otherwise an error as per kill(3);
+ * APR_EINVAL is returned if passed either an invalid (< 1) pid, or if
+ * the pid is not in the current process group
+ */
+AP_DECLARE(apr_status_t) ap_mpm_safe_kill(pid_t pid, int sig);
+
+/**
+ * Log why a child died to the error log, if the child died without the
+ * parent signalling it.
+ * @param pid The child that has died
+ * @param why The return code of the child process
+ * @param status The status returned from ap_wait_or_timeout
+ * @return 0 on success, APEXIT_CHILDFATAL if MPM should terminate
+ */
+AP_DECLARE(int) ap_process_child_status(apr_proc_t *pid, apr_exit_why_e why, int status);
+
+AP_DECLARE(apr_status_t) ap_fatal_signal_setup(server_rec *s, apr_pool_t *in_pconf);
+AP_DECLARE(apr_status_t) ap_fatal_signal_child_setup(server_rec *s);
+
+#endif /* (!WIN32 && !NETWARE) || DOXYGEN */
+
+/**
+ * Pool cleanup for end-generation hook implementation
+ * (core httpd function)
+ */
+apr_status_t ap_mpm_end_gen_helper(void *unused);
+
+/**
+ * Run the monitor hook (once every ten calls), determine if any child
+ * process has died and, if none died, sleep one second.
+ * @param status The return code if a process has died
+ * @param exitcode The returned exit status of the child, if a child process
+ * dies, or the signal that caused the child to die.
+ * @param ret The process id of the process that died
+ * @param p The pool to allocate out of
+ * @param s The server_rec to pass
+ */
+AP_DECLARE(void) ap_wait_or_timeout(apr_exit_why_e *status, int *exitcode,
+ apr_proc_t *ret, apr_pool_t *p,
+ server_rec *s);
+
+#if defined(TCP_NODELAY)
+/**
+ * Turn off the nagle algorithm for the specified socket. The nagle algorithm
+ * says that we should delay sending partial packets in the hopes of getting
+ * more data. There are bad interactions between persistent connections and
+ * Nagle's algorithm that have severe performance penalties.
+ * @param s The socket to disable nagle for.
+ */
+void ap_sock_disable_nagle(apr_socket_t *s);
+#else
+#define ap_sock_disable_nagle(s) /* NOOP */
+#endif
+
+#ifdef HAVE_GETPWNAM
+/**
+ * Convert a username to a numeric ID
+ * @param name The name to convert
+ * @return The user id corresponding to a name
+ * @fn uid_t ap_uname2id(const char *name)
+ */
+AP_DECLARE(uid_t) ap_uname2id(const char *name);
+#endif
+
+#ifdef HAVE_GETGRNAM
+/**
+ * Convert a group name to a numeric ID
+ * @param name The name to convert
+ * @return The group id corresponding to a name
+ * @fn gid_t ap_gname2id(const char *name)
+ */
+AP_DECLARE(gid_t) ap_gname2id(const char *name);
+#endif
+
+#ifndef HAVE_INITGROUPS
+/**
+ * The initgroups() function initializes the group access list by reading the
+ * group database /etc/group and using all groups of which user is a member.
+ * The additional group basegid is also added to the list.
+ * @param name The user name - must be non-NULL
+ * @param basegid The basegid to add
+ * @return returns 0 on success
+ * @fn int initgroups(const char *name, gid_t basegid)
+ */
+int initgroups(const char *name, gid_t basegid);
+#endif
+
+#if (!defined(WIN32) && !defined(NETWARE)) || defined(DOXYGEN)
+
+typedef struct ap_pod_t ap_pod_t;
+
+struct ap_pod_t {
+ apr_file_t *pod_in;
+ apr_file_t *pod_out;
+ apr_pool_t *p;
+};
+
+/**
+ * Open the pipe-of-death. The pipe of death is used to tell all child
+ * processes that it is time to die gracefully.
+ * @param p The pool to use for allocating the pipe
+ * @param pod the pipe-of-death that is created.
+ */
+AP_DECLARE(apr_status_t) ap_mpm_pod_open(apr_pool_t *p, ap_pod_t **pod);
+
+/**
+ * Check the pipe to determine if the process has been signalled to die.
+ */
+AP_DECLARE(apr_status_t) ap_mpm_pod_check(ap_pod_t *pod);
+
+/**
+ * Close the pipe-of-death
+ *
+ * @param pod the pipe-of-death to close.
+ */
+AP_DECLARE(apr_status_t) ap_mpm_pod_close(ap_pod_t *pod);
+
+/**
+ * Write data to the pipe-of-death, signalling that one child process
+ * should die.
+ * @param pod the pipe-of-death to write to.
+ */
+AP_DECLARE(apr_status_t) ap_mpm_pod_signal(ap_pod_t *pod);
+
+/**
+ * Write data to the pipe-of-death, signalling that all child process
+ * should die.
+ * @param pod The pipe-of-death to write to.
+ * @param num The number of child processes to kill
+ */
+AP_DECLARE(void) ap_mpm_pod_killpg(ap_pod_t *pod, int num);
+
+#define AP_MPM_PODX_RESTART_CHAR '$'
+#define AP_MPM_PODX_GRACEFUL_CHAR '!'
+
+typedef enum { AP_MPM_PODX_NORESTART, AP_MPM_PODX_RESTART, AP_MPM_PODX_GRACEFUL } ap_podx_restart_t;
+
+/**
+ * Open the extended pipe-of-death.
+ * @param p The pool to use for allocating the pipe
+ * @param pod The pipe-of-death that is created.
+ */
+AP_DECLARE(apr_status_t) ap_mpm_podx_open(apr_pool_t *p, ap_pod_t **pod);
+
+/**
+ * Check the extended pipe to determine if the process has been signalled to die.
+ */
+AP_DECLARE(int) ap_mpm_podx_check(ap_pod_t *pod);
+
+/**
+ * Close the pipe-of-death
+ *
+ * @param pod The pipe-of-death to close.
+ */
+AP_DECLARE(apr_status_t) ap_mpm_podx_close(ap_pod_t *pod);
+
+/**
+ * Write data to the extended pipe-of-death, signalling that one child process
+ * should die.
+ * @param pod the pipe-of-death to write to.
+ * @param graceful restart-type
+ */
+AP_DECLARE(apr_status_t) ap_mpm_podx_signal(ap_pod_t *pod,
+ ap_podx_restart_t graceful);
+
+/**
+ * Write data to the extended pipe-of-death, signalling that all child process
+ * should die.
+ * @param pod The pipe-of-death to write to.
+ * @param num The number of child processes to kill
+ * @param graceful restart-type
+ */
+AP_DECLARE(void) ap_mpm_podx_killpg(ap_pod_t *pod, int num,
+ ap_podx_restart_t graceful);
+
+#endif /* (!WIN32 && !NETWARE) || DOXYGEN */
+
+/**
+ * Check that exactly one MPM is loaded
+ * Returns NULL if yes, error string if not.
+ */
+AP_DECLARE(const char *) ap_check_mpm(void);
+
+/*
+ * These data members are common to all mpms. Each new mpm
+ * should either use the appropriate ap_mpm_set_* function
+ * in their command table or create their own for custom or
+ * OS specific needs. These should work for most.
+ */
+
+/**
+ * The maximum number of requests each child thread or
+ * process handles before dying off
+ */
+AP_DECLARE_DATA extern int ap_max_requests_per_child;
+const char *ap_mpm_set_max_requests(cmd_parms *cmd, void *dummy,
+ const char *arg);
+
+/**
+ * The filename used to store the process id.
+ */
+AP_DECLARE_DATA extern const char *ap_pid_fname;
+const char *ap_mpm_set_pidfile(cmd_parms *cmd, void *dummy,
+ const char *arg);
+void ap_mpm_dump_pidfile(apr_pool_t *p, apr_file_t *out);
+
+/*
+ * The directory that the server changes directory to dump core.
+ */
+AP_DECLARE_DATA extern char ap_coredump_dir[MAX_STRING_LEN];
+AP_DECLARE_DATA extern int ap_coredumpdir_configured;
+const char *ap_mpm_set_coredumpdir(cmd_parms *cmd, void *dummy,
+ const char *arg);
+
+/**
+ * Set the timeout period for a graceful shutdown.
+ */
+AP_DECLARE_DATA extern int ap_graceful_shutdown_timeout;
+AP_DECLARE(const char *)ap_mpm_set_graceful_shutdown(cmd_parms *cmd, void *dummy,
+ const char *arg);
+#define AP_GRACEFUL_SHUTDOWN_TIMEOUT_COMMAND \
+AP_INIT_TAKE1("GracefulShutdownTimeout", ap_mpm_set_graceful_shutdown, NULL, \
+ RSRC_CONF, "Maximum time in seconds to wait for child " \
+ "processes to complete transactions during shutdown")
+
+
+int ap_signal_server(int *, apr_pool_t *);
+void ap_mpm_rewrite_args(process_rec *);
+
+AP_DECLARE_DATA extern apr_uint32_t ap_max_mem_free;
+extern const char *ap_mpm_set_max_mem_free(cmd_parms *cmd, void *dummy,
+ const char *arg);
+
+AP_DECLARE_DATA extern apr_size_t ap_thread_stacksize;
+extern const char *ap_mpm_set_thread_stacksize(cmd_parms *cmd, void *dummy,
+ const char *arg);
+
+/* core's implementation of child_status hook */
+extern void ap_core_child_status(server_rec *s, pid_t pid, ap_generation_t gen,
+ int slot, mpm_child_status status);
+
+#if defined(AP_ENABLE_EXCEPTION_HOOK) && AP_ENABLE_EXCEPTION_HOOK
+extern const char *ap_mpm_set_exception_hook(cmd_parms *cmd, void *dummy,
+ const char *arg);
+#endif
+
+AP_DECLARE_HOOK(int,monitor,(apr_pool_t *p, server_rec *s))
+
+/* register modules that undertake to manage system security */
+AP_DECLARE(int) ap_sys_privileges_handlers(int inc);
+AP_DECLARE_HOOK(int, drop_privileges, (apr_pool_t * pchild, server_rec * s))
+
+/* implement the ap_mpm_query() function
+ * The MPM should return OK+APR_ENOTIMPL for any unimplemented query codes;
+ * modules which intercede for specific query codes should DECLINE for others.
+ */
+AP_DECLARE_HOOK(int, mpm_query, (int query_code, int *result, apr_status_t *rv))
+
+/* register the specified callback */
+AP_DECLARE_HOOK(apr_status_t, mpm_register_timed_callback,
+ (apr_time_t t, ap_mpm_callback_fn_t *cbfn, void *baton))
+
+/* get MPM name (e.g., "prefork" or "event") */
+AP_DECLARE_HOOK(const char *,mpm_get_name,(void))
+
+/**
+ * Notification that connection handling is suspending (disassociating from the
+ * current thread)
+ * @param c The current connection
+ * @param r The current request, or NULL if there is no active request
+ * @ingroup hooks
+ * @see ap_hook_resume_connection
+ * @note This hook is not implemented by MPMs like Prefork and Worker which
+ * handle all processing of a particular connection on the same thread.
+ * @note This hook will be called on the thread that was previously
+ * processing the connection.
+ * @note This hook is not called at the end of connection processing. This
+ * hook only notifies a module when processing of an active connection is
+ * suspended.
+ * @note Resumption and subsequent suspension of a connection solely to perform
+ * I/O by the MPM, with no execution of non-MPM code, may not necessarily result
+ * in a call to this hook.
+ */
+AP_DECLARE_HOOK(void, suspend_connection,
+ (conn_rec *c, request_rec *r))
+
+/**
+ * Notification that connection handling is resuming (associating with a thread)
+ * @param c The current connection
+ * @param r The current request, or NULL if there is no active request
+ * @ingroup hooks
+ * @see ap_hook_suspend_connection
+ * @note This hook is not implemented by MPMs like Prefork and Worker which
+ * handle all processing of a particular connection on the same thread.
+ * @note This hook will be called on the thread that will resume processing
+ * the connection.
+ * @note This hook is not called at the beginning of connection processing.
+ * This hook only notifies a module when processing resumes for a
+ * previously-suspended connection.
+ * @note Resumption and subsequent suspension of a connection solely to perform
+ * I/O by the MPM, with no execution of non-MPM code, may not necessarily result
+ * in a call to this hook.
+ */
+AP_DECLARE_HOOK(void, resume_connection,
+ (conn_rec *c, request_rec *r))
+
+/* mutex type string for accept mutex, if any; MPMs should use the
+ * same mutex type for ease of configuration
+ */
+#define AP_ACCEPT_MUTEX_TYPE "mpm-accept"
+
+/* internal pre-config logic for MPM-related settings, callable only from
+ * core's pre-config hook
+ */
+void mpm_common_pre_config(apr_pool_t *pconf);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !APACHE_MPM_COMMON_H */
+/** @} */
diff --git a/include/scoreboard.h b/include/scoreboard.h
new file mode 100644
index 0000000..9376da2
--- /dev/null
+++ b/include/scoreboard.h
@@ -0,0 +1,253 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file scoreboard.h
+ * @brief Apache scoreboard library
+ */
+
+#ifndef APACHE_SCOREBOARD_H
+#define APACHE_SCOREBOARD_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if APR_HAVE_SYS_TIME_H
+#include <sys/time.h>
+#include <sys/times.h>
+#endif
+
+#include "ap_config.h"
+#include "http_config.h"
+#include "apr_thread_proc.h"
+#include "apr_portable.h"
+#include "apr_shm.h"
+#include "apr_optional.h"
+
+/* Scoreboard file, if there is one */
+#ifndef DEFAULT_SCOREBOARD
+#define DEFAULT_SCOREBOARD "logs/apache_runtime_status"
+#endif
+
+/* Scoreboard info on a process is, for now, kept very brief ---
+ * just status value and pid (the latter so that the caretaker process
+ * can properly update the scoreboard when a process dies). We may want
+ * to eventually add a separate set of long_score structures which would
+ * give, for each process, the number of requests serviced, and info on
+ * the current, or most recent, request.
+ *
+ * Status values:
+ */
+
+#define SERVER_DEAD 0
+#define SERVER_STARTING 1 /* Server Starting up */
+#define SERVER_READY 2 /* Waiting for connection (or accept() lock) */
+#define SERVER_BUSY_READ 3 /* Reading a client request */
+#define SERVER_BUSY_WRITE 4 /* Processing a client request */
+#define SERVER_BUSY_KEEPALIVE 5 /* Waiting for more requests via keepalive */
+#define SERVER_BUSY_LOG 6 /* Logging the request */
+#define SERVER_BUSY_DNS 7 /* Looking up a hostname */
+#define SERVER_CLOSING 8 /* Closing the connection */
+#define SERVER_GRACEFUL 9 /* server is gracefully finishing request */
+#define SERVER_IDLE_KILL 10 /* Server is cleaning up idle children. */
+#define SERVER_NUM_STATUS 11 /* number of status settings */
+
+/* Type used for generation indicies. Startup and every restart cause a
+ * new generation of children to be spawned. Children within the same
+ * generation share the same configuration information -- pointers to stuff
+ * created at config time in the parent are valid across children. However,
+ * this can't work effectively with non-forked architectures. So while the
+ * arrays in the scoreboard never change between the parent and forked
+ * children, so they do not require shm storage, the contents of the shm
+ * may contain no pointers.
+ */
+typedef int ap_generation_t;
+
+/* Is the scoreboard shared between processes or not?
+ * Set by the MPM when the scoreboard is created.
+ */
+typedef enum {
+ SB_NOT_SHARED = 1,
+ SB_SHARED = 2
+} ap_scoreboard_e;
+
+/* stuff which is worker specific */
+typedef struct worker_score worker_score;
+struct worker_score {
+#if APR_HAS_THREADS
+ apr_os_thread_t tid;
+#endif
+ int thread_num;
+ /* With some MPMs (e.g., worker), a worker_score can represent
+ * a thread in a terminating process which is no longer
+ * represented by the corresponding process_score. These MPMs
+ * should set pid and generation fields in the worker_score.
+ */
+ pid_t pid;
+ ap_generation_t generation;
+ unsigned char status;
+ unsigned short conn_count;
+ apr_off_t conn_bytes;
+ unsigned long access_count;
+ apr_off_t bytes_served;
+ unsigned long my_access_count;
+ apr_off_t my_bytes_served;
+ apr_time_t start_time;
+ apr_time_t stop_time;
+ apr_time_t last_used;
+#ifdef HAVE_TIMES
+ struct tms times;
+#endif
+ char client[32]; /* DEPRECATED: Keep 'em small... */
+ char request[64]; /* We just want an idea... */
+ char vhost[32]; /* What virtual host is being accessed? */
+ char protocol[16]; /* What protocol is used on the connection? */
+ apr_time_t duration;
+ char client64[64];
+};
+
+typedef struct {
+ int server_limit;
+ int thread_limit;
+ ap_generation_t running_generation; /* the generation of children which
+ * should still be serving requests.
+ */
+ apr_time_t restart_time;
+#ifdef HAVE_TIMES
+ struct tms times;
+#endif
+} global_score;
+
+/* stuff which the parent generally writes and the children rarely read */
+typedef struct process_score process_score;
+struct process_score {
+ pid_t pid;
+ ap_generation_t generation; /* generation of this child */
+ char quiescing; /* the process whose pid is stored above is
+ * going down gracefully
+ */
+ char not_accepting; /* the process is busy and is not accepting more
+ * connections (for async MPMs)
+ */
+ apr_uint32_t connections; /* total connections (for async MPMs) */
+ apr_uint32_t write_completion; /* async connections doing write completion */
+ apr_uint32_t lingering_close; /* async connections in lingering close */
+ apr_uint32_t keep_alive; /* async connections in keep alive */
+ apr_uint32_t suspended; /* connections suspended by some module */
+ int bucket; /* Listener bucket used by this child */
+};
+
+/* Scoreboard is now in 'local' memory, since it isn't updated once created,
+ * even in forked architectures. Child created-processes (non-fork) will
+ * set up these indicies into the (possibly relocated) shmem records.
+ */
+typedef struct {
+ global_score *global;
+ process_score *parent;
+ worker_score **servers;
+} scoreboard;
+
+typedef struct ap_sb_handle_t ap_sb_handle_t;
+
+/*
+ * Creation and deletion (internal)
+ */
+int ap_create_scoreboard(apr_pool_t *p, ap_scoreboard_e t);
+apr_status_t ap_cleanup_scoreboard(void *d);
+
+/*
+ * APIs for MPMs and other modules
+ */
+AP_DECLARE(int) ap_exists_scoreboard_image(void);
+AP_DECLARE(void) ap_increment_counts(ap_sb_handle_t *sbh, request_rec *r);
+
+AP_DECLARE(apr_status_t) ap_reopen_scoreboard(apr_pool_t *p, apr_shm_t **shm, int detached);
+AP_DECLARE(void) ap_init_scoreboard(void *shared_score);
+AP_DECLARE(int) ap_calc_scoreboard_size(void);
+
+AP_DECLARE(void) ap_create_sb_handle(ap_sb_handle_t **new_sbh, apr_pool_t *p,
+ int child_num, int thread_num);
+AP_DECLARE(void) ap_update_sb_handle(ap_sb_handle_t *sbh,
+ int child_num, int thread_num);
+
+AP_DECLARE(int) ap_find_child_by_pid(apr_proc_t *pid);
+AP_DECLARE(int) ap_update_child_status(ap_sb_handle_t *sbh, int status, request_rec *r);
+AP_DECLARE(int) ap_update_child_status_from_indexes(int child_num, int thread_num,
+ int status, request_rec *r);
+AP_DECLARE(int) ap_update_child_status_from_conn(ap_sb_handle_t *sbh, int status, conn_rec *c);
+AP_DECLARE(int) ap_update_child_status_from_server(ap_sb_handle_t *sbh, int status,
+ conn_rec *c, server_rec *s);
+AP_DECLARE(int) ap_update_child_status_descr(ap_sb_handle_t *sbh, int status, const char *descr);
+
+AP_DECLARE(void) ap_time_process_request(ap_sb_handle_t *sbh, int status);
+
+AP_DECLARE(int) ap_update_global_status(void);
+
+AP_DECLARE(worker_score *) ap_get_scoreboard_worker(ap_sb_handle_t *sbh);
+
+/** Return a pointer to the worker_score for a given child, thread pair.
+ * @param child_num The child number.
+ * @param thread_num The thread number.
+ * @return A pointer to the worker_score structure.
+ * @deprecated This function is deprecated, use ap_copy_scoreboard_worker instead. */
+AP_DECLARE(worker_score *) ap_get_scoreboard_worker_from_indexes(int child_num,
+ int thread_num);
+
+/** Copy the contents of a worker scoreboard entry. The contents of
+ * the worker_score structure are copied verbatim into the dest
+ * structure.
+ * @param dest Output parameter.
+ * @param child_num The child number.
+ * @param thread_num The thread number.
+ */
+AP_DECLARE(void) ap_copy_scoreboard_worker(worker_score *dest,
+ int child_num, int thread_num);
+
+AP_DECLARE(process_score *) ap_get_scoreboard_process(int x);
+AP_DECLARE(global_score *) ap_get_scoreboard_global(void);
+
+AP_DECLARE_DATA extern scoreboard *ap_scoreboard_image;
+AP_DECLARE_DATA extern const char *ap_scoreboard_fname;
+AP_DECLARE_DATA extern int ap_extended_status;
+AP_DECLARE_DATA extern int ap_mod_status_reqtail;
+
+/*
+ * Command handlers [internal]
+ */
+const char *ap_set_scoreboard(cmd_parms *cmd, void *dummy, const char *arg);
+const char *ap_set_extended_status(cmd_parms *cmd, void *dummy, int arg);
+const char *ap_set_reqtail(cmd_parms *cmd, void *dummy, int arg);
+
+/* Hooks */
+/**
+ * Hook for post scoreboard creation, pre mpm.
+ * @param p Apache pool to allocate from.
+ * @param sb_type
+ * @ingroup hooks
+ * @return OK or DECLINE on success; anything else is a error
+ */
+AP_DECLARE_HOOK(int, pre_mpm, (apr_pool_t *p, ap_scoreboard_e sb_type))
+
+/* for time_process_request() in http_main.c */
+#define START_PREQUEST 1
+#define STOP_PREQUEST 2
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !APACHE_SCOREBOARD_H */
diff --git a/include/util_cfgtree.h b/include/util_cfgtree.h
new file mode 100644
index 0000000..c843639
--- /dev/null
+++ b/include/util_cfgtree.h
@@ -0,0 +1,98 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file util_cfgtree.h
+ * @brief Config Tree Package
+ *
+ * @defgroup APACHE_CORE_CONFIG_TREE Config Tree Package
+ * @ingroup APACHE_CORE_CONFIG
+ * @{
+ */
+
+#ifndef AP_CONFTREE_H
+#define AP_CONFTREE_H
+
+#include "ap_config.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct ap_directive_t ap_directive_t;
+
+/**
+ * @brief Structure used to build the config tree.
+ *
+ * The config tree only stores
+ * the directives that will be active in the running server. Directives
+ * that contain other directions, such as &lt;Directory ...&gt; cause a sub-level
+ * to be created, where the included directives are stored. The closing
+ * directive (&lt;/Directory&gt;) is not stored in the tree.
+ */
+struct ap_directive_t {
+ /** The current directive */
+ const char *directive;
+ /** The arguments for the current directive, stored as a space
+ * separated list */
+ const char *args;
+ /** The next directive node in the tree */
+ struct ap_directive_t *next;
+ /** The first child node of this directive */
+ struct ap_directive_t *first_child;
+ /** The parent node of this directive */
+ struct ap_directive_t *parent;
+
+ /** directive's module can store add'l data here */
+ void *data;
+
+ /* ### these may go away in the future, but are needed for now */
+ /** The name of the file this directive was found in */
+ const char *filename;
+ /** The line number the directive was on */
+ int line_num;
+
+ /** A short-cut towards the last directive node in the tree.
+ * The value may not always be up-to-date but it always points to
+ * somewhere in the tree, nearer to the tail.
+ * This value is only set in the first node
+ */
+ struct ap_directive_t *last;
+};
+
+/**
+ * The root of the configuration tree
+ */
+AP_DECLARE_DATA extern ap_directive_t *ap_conftree;
+
+/**
+ * Add a node to the configuration tree.
+ * @param parent The current parent node. If the added node is a first_child,
+ then this is changed to the current node
+ * @param current The current node
+ * @param toadd The node to add to the tree
+ * @param child Is the node to add a child node
+ * @return the added node
+ */
+ap_directive_t *ap_add_node(ap_directive_t **parent, ap_directive_t *current,
+ ap_directive_t *toadd, int child);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/** @} */
diff --git a/include/util_charset.h b/include/util_charset.h
new file mode 100644
index 0000000..9df000d
--- /dev/null
+++ b/include/util_charset.h
@@ -0,0 +1,72 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file util_charset.h
+ * @brief charset conversion
+ *
+ * @defgroup APACHE_CORE_CHARSET Charset Conversion
+ * @ingroup APACHE_CORE
+ *
+ * These are the translation handles used to translate between the network
+ * format of protocol headers and the local machine format.
+ *
+ * For an EBCDIC machine, these are valid handles which are set up at
+ * initialization to translate between ISO-8859-1 and the code page of
+ * the source code.\n
+ * For an ASCII machine, they are undefined.
+ *
+ * @see ap_init_ebcdic()
+ * @{
+ */
+
+#ifndef APACHE_UTIL_CHARSET_H
+#define APACHE_UTIL_CHARSET_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "apr.h"
+
+#if APR_CHARSET_EBCDIC || defined(DOXYGEN)
+
+#include "apr_xlate.h"
+
+/**
+ * On EBCDIC machine this is a translation handle used to translate the
+ * headers from the local machine format to ASCII for network transmission.
+ * @note On ASCII system, this variable does <b>not</b> exist.
+ * So, its use should be guarded by \#if APR_CHARSET_EBCDIC.
+ */
+extern apr_xlate_t *ap_hdrs_to_ascii;
+
+/**
+ * On EBCDIC machine this is a translation handle used to translate the
+ * headers from ASCII to the local machine format after network transmission.
+ * @note On ASCII system, this variable does <b>not</b> exist.
+ * So, its use should be guarded by \#if APR_CHARSET_EBCDIC.
+ */
+extern apr_xlate_t *ap_hdrs_from_ascii;
+
+#endif /* APR_CHARSET_EBCDIC */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !APACHE_UTIL_CHARSET_H */
+/** @} */
diff --git a/include/util_cookies.h b/include/util_cookies.h
new file mode 100644
index 0000000..51f8fac
--- /dev/null
+++ b/include/util_cookies.h
@@ -0,0 +1,146 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file util_cookies.h
+ * @brief Apache cookie library
+ */
+
+#ifndef UTIL_COOKIES_H
+#define UTIL_COOKIES_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup APACHE_CORE_COOKIE Cookies
+ * @ingroup APACHE_CORE
+ *
+ * RFC2109 and RFC2965 compliant HTTP cookies can be read from and written
+ * to using this set of functions.
+ *
+ * @{
+ *
+ */
+
+#include "apr_errno.h"
+#include "httpd.h"
+
+#define SET_COOKIE "Set-Cookie"
+#define SET_COOKIE2 "Set-Cookie2"
+#define DEFAULT_ATTRS "HttpOnly;Secure;Version=1"
+#define CLEAR_ATTRS "Version=1"
+
+typedef struct {
+ request_rec *r;
+ const char *name;
+ const char *encoded;
+ apr_table_t *new_cookies;
+ int duplicated;
+} ap_cookie_do;
+
+/**
+ * Write an RFC2109 compliant cookie.
+ *
+ * @param r The request
+ * @param name The name of the cookie.
+ * @param val The value to place in the cookie.
+ * @param attrs The string containing additional cookie attributes. If NULL, the
+ * DEFAULT_ATTRS will be used.
+ * @param maxage If non zero, a Max-Age header will be added to the cookie.
+ * @param ... A varargs array of zero or more (apr_table_t *) tables followed by NULL
+ * to which the cookies should be added.
+ */
+AP_DECLARE(apr_status_t) ap_cookie_write(request_rec * r, const char *name,
+ const char *val, const char *attrs,
+ long maxage, ...)
+ AP_FN_ATTR_SENTINEL;
+
+/**
+ * Write an RFC2965 compliant cookie.
+ *
+ * @param r The request
+ * @param name2 The name of the cookie.
+ * @param val The value to place in the cookie.
+ * @param attrs2 The string containing additional cookie attributes. If NULL, the
+ * DEFAULT_ATTRS will be used.
+ * @param maxage If non zero, a Max-Age header will be added to the cookie.
+ * @param ... A varargs array of zero or more (apr_table_t *) tables followed by NULL
+ * to which the cookies should be added.
+ */
+AP_DECLARE(apr_status_t) ap_cookie_write2(request_rec * r, const char *name2,
+ const char *val, const char *attrs2,
+ long maxage, ...)
+ AP_FN_ATTR_SENTINEL;
+
+/**
+ * Remove an RFC2109 compliant cookie.
+ *
+ * @param r The request
+ * @param name The name of the cookie.
+ * @param attrs The string containing additional cookie attributes. If NULL, the
+ * CLEAR_ATTRS will be used.
+ * @param ... A varargs array of zero or more (apr_table_t *) tables followed by NULL
+ * to which the cookies should be added.
+ */
+AP_DECLARE(apr_status_t) ap_cookie_remove(request_rec * r, const char *name,
+ const char *attrs, ...)
+ AP_FN_ATTR_SENTINEL;
+
+/**
+ * Remove an RFC2965 compliant cookie.
+ *
+ * @param r The request
+ * @param name2 The name of the cookie.
+ * @param attrs2 The string containing additional cookie attributes. If NULL, the
+ * CLEAR_ATTRS will be used.
+ * @param ... A varargs array of zero or more (apr_table_t *) tables followed by NULL
+ * to which the cookies should be added.
+ */
+AP_DECLARE(apr_status_t) ap_cookie_remove2(request_rec * r, const char *name2,
+ const char *attrs2, ...)
+ AP_FN_ATTR_SENTINEL;
+
+/**
+ * Read a cookie called name, placing its value in val.
+ *
+ * Both the Cookie and Cookie2 headers are scanned for the cookie.
+ *
+ * If the cookie is duplicated, this function returns APR_EGENERAL. If found,
+ * and if remove is non zero, the cookie will be removed from the headers, and
+ * thus kept private from the backend.
+ */
+AP_DECLARE(apr_status_t) ap_cookie_read(request_rec * r, const char *name, const char **val,
+ int remove);
+
+/**
+ * Sanity check a given string that it exists, is not empty,
+ * and does not contain the special characters '=', ';' and '&'.
+ *
+ * It is used to sanity check the cookie names.
+ */
+AP_DECLARE(apr_status_t) ap_cookie_check_string(const char *string);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !UTIL_COOKIES_H */
diff --git a/include/util_ebcdic.h b/include/util_ebcdic.h
new file mode 100644
index 0000000..1457605
--- /dev/null
+++ b/include/util_ebcdic.h
@@ -0,0 +1,92 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file util_ebcdic.h
+ * @brief Utilities for EBCDIC conversion
+ *
+ * @defgroup APACHE_CORE_EBCDIC Utilities for EBCDIC conversion
+ * @ingroup APACHE_CORE
+ * @{
+ */
+
+#ifndef APACHE_UTIL_EBCDIC_H
+#define APACHE_UTIL_EBCDIC_H
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "apr_xlate.h"
+#include "httpd.h"
+#include "util_charset.h"
+
+#if APR_CHARSET_EBCDIC || defined(DOXYGEN)
+
+/**
+ * Setup all of the global translation handlers.
+ * @param pool The pool to allocate out of.
+ * @note On non-EBCDIC system, this function does <b>not</b> exist.
+ * So, its use should be guarded by \#if APR_CHARSET_EBCDIC.
+ */
+apr_status_t ap_init_ebcdic(apr_pool_t *pool);
+
+/**
+ * Convert protocol data from the implementation character
+ * set to ASCII.
+ * @param buffer Buffer to translate.
+ * @param len Number of bytes to translate.
+ * @note On non-EBCDIC system, this function is replaced by an
+ * empty macro.
+ */
+void ap_xlate_proto_to_ascii(char *buffer, apr_size_t len);
+
+/**
+ * Convert protocol data to the implementation character
+ * set from ASCII.
+ * @param buffer Buffer to translate.
+ * @param len Number of bytes to translate.
+ * @note On non-EBCDIC system, this function is replaced by an
+ * empty macro.
+ */
+void ap_xlate_proto_from_ascii(char *buffer, apr_size_t len);
+
+/**
+ * Convert protocol data from the implementation character
+ * set to ASCII, then send it.
+ * @param r The current request.
+ * @param ... The strings to write, followed by a NULL pointer.
+ * @note On non-EBCDIC system, this function is replaced by a call to
+ * #ap_rvputs.
+ */
+int ap_rvputs_proto_in_ascii(request_rec *r, ...);
+
+#else /* APR_CHARSET_EBCDIC */
+
+#define ap_xlate_proto_to_ascii(x,y) /* NOOP */
+#define ap_xlate_proto_from_ascii(x,y) /* NOOP */
+
+#define ap_rvputs_proto_in_ascii ap_rvputs
+
+#endif /* APR_CHARSET_EBCDIC */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !APACHE_UTIL_EBCDIC_H */
+/** @} */
diff --git a/include/util_fcgi.h b/include/util_fcgi.h
new file mode 100644
index 0000000..849fdee
--- /dev/null
+++ b/include/util_fcgi.h
@@ -0,0 +1,280 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file util_fcgi.h
+ * @brief FastCGI protocol defitions and support routines
+ *
+ * @defgroup APACHE_CORE_FASTCGI FastCGI Tools
+ * @ingroup APACHE_CORE
+ * @{
+ */
+
+#ifndef APACHE_UTIL_FCGI_H
+#define APACHE_UTIL_FCGI_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "httpd.h"
+
+/**
+ * @brief A structure that represents the fixed header fields
+ * at the beginning of a "FastCGI record" (i.e., the data prior
+ * to content data and padding).
+ */
+typedef struct {
+ /** See values for version, below */
+ unsigned char version;
+ /** See values for type, below */
+ unsigned char type;
+ /** request id, in two parts */
+ unsigned char requestIdB1;
+ unsigned char requestIdB0;
+ /** content length, in two parts */
+ unsigned char contentLengthB1;
+ unsigned char contentLengthB0;
+ /** padding length */
+ unsigned char paddingLength;
+ /** 8-bit reserved field */
+ unsigned char reserved;
+} ap_fcgi_header;
+
+/*
+ * Number of bytes in the header portion of a FastCGI record
+ * (i.e., ap_fcgi_header structure). Future versions of the
+ * protocol may increase the size.
+ */
+#define AP_FCGI_HEADER_LEN 8
+
+/*
+ * Maximum number of bytes in the content portion of a FastCGI record.
+ */
+#define AP_FCGI_MAX_CONTENT_LEN 65535
+
+/**
+ * Possible values for the version field of ap_fcgi_header
+ */
+#define AP_FCGI_VERSION_1 1
+
+/**
+ * Possible values for the type field of ap_fcgi_header
+ */
+#define AP_FCGI_BEGIN_REQUEST 1
+#define AP_FCGI_ABORT_REQUEST 2
+#define AP_FCGI_END_REQUEST 3
+#define AP_FCGI_PARAMS 4
+#define AP_FCGI_STDIN 5
+#define AP_FCGI_STDOUT 6
+#define AP_FCGI_STDERR 7
+#define AP_FCGI_DATA 8
+#define AP_FCGI_GET_VALUES 9
+#define AP_FCGI_GET_VALUES_RESULT 10
+#define AP_FCGI_UNKNOWN_TYPE 11
+#define AP_FCGI_MAXTYPE (AP_FCGI_UNKNOWN_TYPE)
+
+/**
+ * Offsets of the various fields of ap_fcgi_header
+ */
+#define AP_FCGI_HDR_VERSION_OFFSET 0
+#define AP_FCGI_HDR_TYPE_OFFSET 1
+#define AP_FCGI_HDR_REQUEST_ID_B1_OFFSET 2
+#define AP_FCGI_HDR_REQUEST_ID_B0_OFFSET 3
+#define AP_FCGI_HDR_CONTENT_LEN_B1_OFFSET 4
+#define AP_FCGI_HDR_CONTENT_LEN_B0_OFFSET 5
+#define AP_FCGI_HDR_PADDING_LEN_OFFSET 6
+#define AP_FCGI_HDR_RESERVED_OFFSET 7
+
+/**
+ * @brief This represents the content data of the FastCGI record when
+ * the type is AP_FCGI_BEGIN_REQUEST.
+ */
+typedef struct {
+ /**
+ * role, in two parts
+ * See values for role, below
+ */
+ unsigned char roleB1;
+ unsigned char roleB0;
+ /**
+ * flags
+ * See values for flags bits, below
+ */
+ unsigned char flags;
+ /** reserved */
+ unsigned char reserved[5];
+} ap_fcgi_begin_request_body;
+
+/*
+ * Values for role component of ap_fcgi_begin_request_body
+ */
+#define AP_FCGI_RESPONDER 1
+#define AP_FCGI_AUTHORIZER 2
+#define AP_FCGI_FILTER 3
+
+/*
+ * Values for flags bits of ap_fcgi_begin_request_body
+ */
+#define AP_FCGI_KEEP_CONN 1 /* otherwise the application closes */
+
+/**
+ * Offsets of the various fields of ap_fcgi_begin_request_body
+ */
+#define AP_FCGI_BRB_ROLEB1_OFFSET 0
+#define AP_FCGI_BRB_ROLEB0_OFFSET 1
+#define AP_FCGI_BRB_FLAGS_OFFSET 2
+#define AP_FCGI_BRB_RESERVED0_OFFSET 3
+#define AP_FCGI_BRB_RESERVED1_OFFSET 4
+#define AP_FCGI_BRB_RESERVED2_OFFSET 5
+#define AP_FCGI_BRB_RESERVED3_OFFSET 6
+#define AP_FCGI_BRB_RESERVED4_OFFSET 7
+
+/**
+ * Pack ap_fcgi_header
+ * @param h The header to read from
+ * @param a The array to write to, of size AP_FCGI_HEADER_LEN
+ */
+AP_DECLARE(void) ap_fcgi_header_to_array(ap_fcgi_header *h,
+ unsigned char a[]);
+
+/**
+ * Unpack header of FastCGI record into ap_fcgi_header
+ * @param h The header to write to
+ * @param a The array to read from, of size AP_FCGI_HEADER_LEN
+ */
+AP_DECLARE(void) ap_fcgi_header_from_array(ap_fcgi_header *h,
+ unsigned char a[]);
+
+/**
+ * Unpack header of FastCGI record into individual fields
+ * @param version The version, on output
+ * @param type The type, on output
+ * @param request_id The request id, on output
+ * @param content_len The content length, on output
+ * @param padding_len The amount of padding following the content, on output
+ * @param a The array to read from, of size AP_FCGI_HEADER_LEN
+ */
+AP_DECLARE(void) ap_fcgi_header_fields_from_array(unsigned char *version,
+ unsigned char *type,
+ apr_uint16_t *request_id,
+ apr_uint16_t *content_len,
+ unsigned char *padding_len,
+ unsigned char a[]);
+
+/**
+ * Pack ap_fcgi_begin_request_body
+ * @param h The begin-request body to read from
+ * @param a The array to write to, of size AP_FCGI_HEADER_LEN
+ */
+AP_DECLARE(void) ap_fcgi_begin_request_body_to_array(ap_fcgi_begin_request_body *h,
+ unsigned char a[]);
+
+/**
+ * Fill in a FastCGI request header with the required field values.
+ * @param header The header to fill in
+ * @param type The type of record
+ * @param request_id The request id
+ * @param content_len The amount of content which follows the header
+ * @param padding_len The amount of padding which follows the content
+ *
+ * The header array must be at least AP_FCGI_HEADER_LEN bytes long.
+ */
+AP_DECLARE(void) ap_fcgi_fill_in_header(ap_fcgi_header *header,
+ unsigned char type,
+ apr_uint16_t request_id,
+ apr_uint16_t content_len,
+ unsigned char padding_len);
+
+/**
+ * Fill in a FastCGI begin request body with the required field values.
+ * @param brb The begin-request-body to fill in
+ * @param role AP_FCGI_RESPONDER or other roles
+ * @param flags 0 or a combination of flags like AP_FCGI_KEEP_CONN
+ */
+AP_DECLARE(void) ap_fcgi_fill_in_request_body(ap_fcgi_begin_request_body *brb,
+ int role,
+ unsigned char flags);
+
+/**
+ * Compute the buffer size needed to encode the next portion of
+ * the provided environment table.
+ * @param env The environment table
+ * @param maxlen The maximum buffer size allowable, capped at
+ * AP_FCGI_MAX_CONTENT_LEN.
+ * @param starting_elem On input, the next element of the table array
+ * to process in this FastCGI record. On output, the next element to
+ * process on the *next* FastCGI record.
+ * @return Size of buffer needed to encode the next part, or 0
+ * if no more can be encoded. When 0 is returned: If starting_elem
+ * has reached the end of the table array, all has been encoded;
+ * otherwise, the next envvar can't be encoded within the specified
+ * limit.
+ * @note If an envvar can't be encoded within the specified limit,
+ * the caller can log a warning and increment starting_elem and try
+ * again or increase the limit or fail, as appropriate for the module.
+ */
+AP_DECLARE(apr_size_t) ap_fcgi_encoded_env_len(apr_table_t *env,
+ apr_size_t maxlen,
+ int *starting_elem);
+
+/**
+ * Encode the next portion of the provided environment table using
+ * a buffer previously allocated.
+ * @param r The request, for logging
+ * @param env The environment table
+ * @param buffer A buffer to contain the encoded environment table
+ * @param buflen The length of the buffer, previously computed by
+ * ap_fcgi_encoded_env_len().
+ * @param starting_elem On input, the next element of the table array
+ * to process in this FastCGI record. On output, the next element to
+ * process on the *next* FastCGI record.
+ * @return APR_SUCCESS if a section could be encoded or APR_ENOSPC
+ * otherwise.
+ * @note The output starting_elem from ap_fcgi_encoded_env_len
+ * shouldn't be used as input to ap_fcgi_encode_env when building the
+ * same FastCGI record.
+ */
+AP_DECLARE(apr_status_t) ap_fcgi_encode_env(request_rec *r,
+ apr_table_t *env,
+ void *buffer,
+ apr_size_t buflen,
+ int *starting_elem);
+
+/**
+ * String forms for the value of the FCGI_ROLE envvar
+ */
+#define AP_FCGI_RESPONDER_STR "RESPONDER"
+#define AP_FCGI_AUTHORIZER_STR "AUTHORIZER"
+#define AP_FCGI_FILTER_STR "FILTER"
+
+/**
+ * FastCGI implementations that implement the AUTHORIZER role
+ * for Apache httpd and allow the application to participate in
+ * any of the Apache httpd AAA phases typically set the variable
+ * FCGI_APACHE_ROLE to one of these strings to indicate the
+ * specific AAA phase.
+ */
+#define AP_FCGI_APACHE_ROLE_AUTHENTICATOR_STR "AUTHENTICATOR"
+#define AP_FCGI_APACHE_ROLE_AUTHORIZER_STR "AUTHORIZER"
+#define AP_FCGI_APACHE_ROLE_ACCESS_CHECKER_STR "ACCESS_CHECKER"
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !APACHE_UTIL_FCGI_H */
+/** @} */
diff --git a/include/util_filter.h b/include/util_filter.h
new file mode 100644
index 0000000..5a96607
--- /dev/null
+++ b/include/util_filter.h
@@ -0,0 +1,639 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file util_filter.h
+ * @brief Apache filter library
+ */
+
+#ifndef AP_FILTER_H
+#define AP_FILTER_H
+
+#include "apr.h"
+#include "apr_buckets.h"
+
+#include "httpd.h"
+
+#if APR_HAVE_STDARG_H
+#include <stdarg.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief input filtering modes
+ */
+typedef enum {
+ /** The filter should return at most readbytes data. */
+ AP_MODE_READBYTES,
+ /** The filter should return at most one line of CRLF data.
+ * (If a potential line is too long or no CRLF is found, the
+ * filter may return partial data).
+ */
+ AP_MODE_GETLINE,
+ /** The filter should implicitly eat any CRLF pairs that it sees. */
+ AP_MODE_EATCRLF,
+ /** The filter read should be treated as speculative and any returned
+ * data should be stored for later retrieval in another mode. */
+ AP_MODE_SPECULATIVE,
+ /** The filter read should be exhaustive and read until it can not
+ * read any more.
+ * Use this mode with extreme caution.
+ */
+ AP_MODE_EXHAUSTIVE,
+ /** The filter should initialize the connection if needed,
+ * NNTP or FTP over SSL for example.
+ */
+ AP_MODE_INIT
+} ap_input_mode_t;
+
+/**
+ * @defgroup APACHE_CORE_FILTER Filter Chain
+ * @ingroup APACHE_CORE
+ *
+ * Filters operate using a "chaining" mechanism. The filters are chained
+ * together into a sequence. When output is generated, it is passed through
+ * each of the filters on this chain, until it reaches the end (or "bottom")
+ * and is placed onto the network.
+ *
+ * The top of the chain, the code generating the output, is typically called
+ * a "content generator." The content generator's output is fed into the
+ * filter chain using the standard Apache output mechanisms: ap_rputs(),
+ * ap_rprintf(), ap_rwrite(), etc.
+ *
+ * Each filter is defined by a callback. This callback takes the output from
+ * the previous filter (or the content generator if there is no previous
+ * filter), operates on it, and passes the result to the next filter in the
+ * chain. This pass-off is performed using the ap_fc_* functions, such as
+ * ap_fc_puts(), ap_fc_printf(), ap_fc_write(), etc.
+ *
+ * When content generation is complete, the system will pass an "end of
+ * stream" marker into the filter chain. The filters will use this to flush
+ * out any internal state and to detect incomplete syntax (for example, an
+ * unterminated SSI directive).
+ *
+ * @{
+ */
+
+/* forward declare the filter type */
+typedef struct ap_filter_t ap_filter_t;
+
+/**
+ * @name Filter callbacks
+ *
+ * This function type is used for filter callbacks. It will be passed a
+ * pointer to "this" filter, and a "bucket brigade" containing the content
+ * to be filtered.
+ *
+ * In filter->ctx, the callback will find its context. This context is
+ * provided here, so that a filter may be installed multiple times, each
+ * receiving its own per-install context pointer.
+ *
+ * Callbacks are associated with a filter definition, which is specified
+ * by name. See ap_register_input_filter() and ap_register_output_filter()
+ * for setting the association between a name for a filter and its
+ * associated callback (and other information).
+ *
+ * If the initialization function argument passed to the registration
+ * functions is non-NULL, it will be called iff the filter is in the input
+ * or output filter chains and before any data is generated to allow the
+ * filter to prepare for processing.
+ *
+ * The bucket brigade always belongs to the caller, but the filter
+ * is free to use the buckets within it as it sees fit. Normally,
+ * the brigade will be returned empty. Buckets *may not* be retained
+ * between successive calls to the filter unless they have been
+ * "set aside" with a call apr_bucket_setaside. Typically this will
+ * be done with ap_save_brigade(). Buckets removed from the brigade
+ * become the responsibility of the filter, which must arrange for
+ * them to be deleted, either by doing so directly or by inserting
+ * them in a brigade which will subsequently be destroyed.
+ *
+ * For the input and output filters, the return value of a filter should be
+ * an APR status value. For the init function, the return value should
+ * be an HTTP error code or OK if it was successful.
+ *
+ * @ingroup filter
+ * @{
+ */
+typedef apr_status_t (*ap_out_filter_func)(ap_filter_t *f,
+ apr_bucket_brigade *b);
+typedef apr_status_t (*ap_in_filter_func)(ap_filter_t *f,
+ apr_bucket_brigade *b,
+ ap_input_mode_t mode,
+ apr_read_type_e block,
+ apr_off_t readbytes);
+typedef int (*ap_init_filter_func)(ap_filter_t *f);
+
+typedef union ap_filter_func {
+ ap_out_filter_func out_func;
+ ap_in_filter_func in_func;
+} ap_filter_func;
+
+/** @} */
+
+/**
+ * Filters have different types/classifications. These are used to group
+ * and sort the filters to properly sequence their operation.
+ *
+ * The types have a particular sort order, which allows us to insert them
+ * into the filter chain in a determistic order. Within a particular grouping,
+ * the ordering is equivalent to the order of calls to ap_add_*_filter().
+ */
+typedef enum {
+ /** These filters are used to alter the content that is passed through
+ * them. Examples are SSI or PHP. */
+ AP_FTYPE_RESOURCE = 10,
+ /** These filters are used to alter the content as a whole, but after all
+ * AP_FTYPE_RESOURCE filters are executed. These filters should not
+ * change the content-type. An example is deflate. */
+ AP_FTYPE_CONTENT_SET = 20,
+ /** These filters are used to handle the protocol between server and
+ * client. Examples are HTTP and POP. */
+ AP_FTYPE_PROTOCOL = 30,
+ /** These filters implement transport encodings (e.g., chunking). */
+ AP_FTYPE_TRANSCODE = 40,
+ /** These filters will alter the content, but in ways that are
+ * more strongly associated with the connection. Examples are
+ * splitting an HTTP connection into multiple requests and
+ * buffering HTTP responses across multiple requests.
+ *
+ * It is important to note that these types of filters are not
+ * allowed in a sub-request. A sub-request's output can certainly
+ * be filtered by ::AP_FTYPE_RESOURCE filters, but all of the "final
+ * processing" is determined by the main request. */
+ AP_FTYPE_CONNECTION = 50,
+ /** These filters don't alter the content. They are responsible for
+ * sending/receiving data to/from the client. */
+ AP_FTYPE_NETWORK = 60
+} ap_filter_type;
+
+/**
+ * This is the request-time context structure for an installed filter (in
+ * the output filter chain). It provides the callback to use for filtering,
+ * the request this filter is associated with (which is important when
+ * an output chain also includes sub-request filters), the context for this
+ * installed filter, and the filter ordering/chaining fields.
+ *
+ * Filter callbacks are free to use ->ctx as they please, to store context
+ * during the filter process. Generally, this is superior over associating
+ * the state directly with the request. A callback should not change any of
+ * the other fields.
+ */
+
+typedef struct ap_filter_rec_t ap_filter_rec_t;
+typedef struct ap_filter_provider_t ap_filter_provider_t;
+
+/**
+ * @brief This structure is used for recording information about the
+ * registered filters. It associates a name with the filter's callback
+ * and filter type.
+ *
+ * At the moment, these are simply linked in a chain, so a ->next pointer
+ * is available.
+ *
+ * It is used for any filter that can be inserted in the filter chain.
+ * This may be either a httpd-2.0 filter or a mod_filter harness.
+ * In the latter case it contains dispatch, provider and protocol information.
+ * In the former case, the new fields (from dispatch) are ignored.
+ */
+struct ap_filter_rec_t {
+ /** The registered name for this filter */
+ const char *name;
+
+ /** The function to call when this filter is invoked. */
+ ap_filter_func filter_func;
+
+ /** The function to call directly before the handlers are invoked
+ * for a request. The init function is called once directly
+ * before running the handlers for a request or subrequest. The
+ * init function is never called for a connection filter (with
+ * ftype >= AP_FTYPE_CONNECTION). Any use of this function for
+ * filters for protocols other than HTTP is specified by the
+ * module supported that protocol.
+ */
+ ap_init_filter_func filter_init_func;
+
+ /** The next filter_rec in the list */
+ struct ap_filter_rec_t *next;
+
+ /** Providers for this filter */
+ ap_filter_provider_t *providers;
+
+ /** The type of filter, either AP_FTYPE_CONTENT or AP_FTYPE_CONNECTION.
+ * An AP_FTYPE_CONTENT filter modifies the data based on information
+ * found in the content. An AP_FTYPE_CONNECTION filter modifies the
+ * data based on the type of connection.
+ */
+ ap_filter_type ftype;
+
+ /** Trace level for this filter */
+ int debug;
+
+ /** Protocol flags for this filter */
+ unsigned int proto_flags;
+};
+
+/**
+ * @brief The representation of a filter chain.
+ *
+ * Each request has a list
+ * of these structures which are called in turn to filter the data. Sub
+ * requests get an exact copy of the main requests filter chain.
+ */
+struct ap_filter_t {
+ /** The internal representation of this filter. This includes
+ * the filter's name, type, and the actual function pointer.
+ */
+ ap_filter_rec_t *frec;
+
+ /** A place to store any data associated with the current filter */
+ void *ctx;
+
+ /** The next filter in the chain */
+ ap_filter_t *next;
+
+ /** The request_rec associated with the current filter. If a sub-request
+ * adds filters, then the sub-request is the request associated with the
+ * filter.
+ */
+ request_rec *r;
+
+ /** The conn_rec associated with the current filter. This is analogous
+ * to the request_rec, except that it is used for connection filters.
+ */
+ conn_rec *c;
+};
+
+/**
+ * Get the current bucket brigade from the next filter on the filter
+ * stack. The filter returns an apr_status_t value. If the bottom-most
+ * filter doesn't read from the network, then ::AP_NOBODY_READ is returned.
+ * The bucket brigade will be empty when there is nothing left to get.
+ * @param filter The next filter in the chain
+ * @param bucket The current bucket brigade. The original brigade passed
+ * to ap_get_brigade() must be empty.
+ * @param mode The way in which the data should be read
+ * @param block How the operations should be performed
+ * ::APR_BLOCK_READ, ::APR_NONBLOCK_READ
+ * @param readbytes How many bytes to read from the next filter.
+ */
+AP_DECLARE(apr_status_t) ap_get_brigade(ap_filter_t *filter,
+ apr_bucket_brigade *bucket,
+ ap_input_mode_t mode,
+ apr_read_type_e block,
+ apr_off_t readbytes);
+
+/**
+ * Pass the current bucket brigade down to the next filter on the filter
+ * stack. The filter returns an apr_status_t value. If the bottom-most
+ * filter doesn't write to the network, then ::AP_NOBODY_WROTE is returned.
+ * @param filter The next filter in the chain
+ * @param bucket The current bucket brigade
+ *
+ * @remark Ownership of the brigade is retained by the caller. On return,
+ * the contents of the brigade are UNDEFINED, and the caller must
+ * either call apr_brigade_cleanup or apr_brigade_destroy on
+ * the brigade.
+ */
+AP_DECLARE(apr_status_t) ap_pass_brigade(ap_filter_t *filter,
+ apr_bucket_brigade *bucket);
+
+/**
+ * Pass the current bucket brigade down to the next filter on the filter
+ * stack checking for filter errors. The filter returns an apr_status_t value.
+ * Returns ::OK if the brigade is successfully passed
+ * ::AP_FILTER_ERROR on a filter error
+ * ::HTTP_INTERNAL_SERVER_ERROR on all other errors
+ * @param r The request rec
+ * @param bucket The current bucket brigade
+ * @param fmt The format string. If NULL defaults to "ap_pass_brigade returned"
+ * @param ... The arguments to use to fill out the format string
+ * @remark Ownership of the brigade is retained by the caller. On return,
+ * the contents of the brigade are UNDEFINED, and the caller must
+ * either call apr_brigade_cleanup or apr_brigade_destroy on
+ * the brigade.
+ */
+AP_DECLARE(apr_status_t) ap_pass_brigade_fchk(request_rec *r,
+ apr_bucket_brigade *bucket,
+ const char *fmt,
+ ...)
+ __attribute__((format(printf,3,4)));
+
+/**
+ * This function is used to register an input filter with the system.
+ * After this registration is performed, then a filter may be added
+ * into the filter chain by using ap_add_input_filter() and simply
+ * specifying the name.
+ *
+ * @param name The name to attach to the filter function
+ * @param filter_func The filter function to name
+ * @param filter_init The function to call before the filter handlers
+ are invoked
+ * @param ftype The type of filter function, either ::AP_FTYPE_CONTENT_SET or
+ * ::AP_FTYPE_CONNECTION
+ * @see add_input_filter()
+ */
+AP_DECLARE(ap_filter_rec_t *) ap_register_input_filter(const char *name,
+ ap_in_filter_func filter_func,
+ ap_init_filter_func filter_init,
+ ap_filter_type ftype);
+
+/** @deprecated @see ap_register_output_filter_protocol */
+AP_DECLARE(ap_filter_rec_t *) ap_register_output_filter(const char *name,
+ ap_out_filter_func filter_func,
+ ap_init_filter_func filter_init,
+ ap_filter_type ftype);
+
+/* For httpd-?.? I suggest replacing the above with
+#define ap_register_output_filter(name,ffunc,init,ftype) \
+ ap_register_output_filter_protocol(name,ffunc,init,ftype,0)
+*/
+
+/**
+ * This function is used to register an output filter with the system.
+ * After this registration is performed, then a filter may be added
+ * directly to the filter chain by using ap_add_output_filter() and
+ * simply specifying the name, or as a provider under mod_filter.
+ *
+ * @param name The name to attach to the filter function
+ * @param filter_func The filter function to name
+ * @param filter_init The function to call before the filter handlers
+ * are invoked
+ * @param ftype The type of filter function, either ::AP_FTYPE_CONTENT_SET or
+ * ::AP_FTYPE_CONNECTION
+ * @param proto_flags Protocol flags: logical OR of AP_FILTER_PROTO_* bits
+ * @return the filter rec
+ * @see ap_add_output_filter()
+ */
+AP_DECLARE(ap_filter_rec_t *) ap_register_output_filter_protocol(
+ const char *name,
+ ap_out_filter_func filter_func,
+ ap_init_filter_func filter_init,
+ ap_filter_type ftype,
+ unsigned int proto_flags);
+
+/**
+ * Adds a named filter into the filter chain on the specified request record.
+ * The filter will be installed with the specified context pointer.
+ *
+ * Filters added in this way will always be placed at the end of the filters
+ * that have the same type (thus, the filters have the same order as the
+ * calls to ap_add_filter). If the current filter chain contains filters
+ * from another request, then this filter will be added before those other
+ * filters.
+ *
+ * To re-iterate that last comment. This function is building a FIFO
+ * list of filters. Take note of that when adding your filter to the chain.
+ *
+ * @param name The name of the filter to add
+ * @param ctx Context data to provide to the filter
+ * @param r The request to add this filter for (or NULL if it isn't associated with a request)
+ * @param c The connection to add the fillter for
+ */
+AP_DECLARE(ap_filter_t *) ap_add_input_filter(const char *name, void *ctx,
+ request_rec *r, conn_rec *c);
+
+/**
+ * Variant of ap_add_input_filter() that accepts a registered filter handle
+ * (as returned by ap_register_input_filter()) rather than a filter name
+ *
+ * @param f The filter handle to add
+ * @param ctx Context data to provide to the filter
+ * @param r The request to add this filter for (or NULL if it isn't associated with a request)
+ * @param c The connection to add the fillter for
+ */
+AP_DECLARE(ap_filter_t *) ap_add_input_filter_handle(ap_filter_rec_t *f,
+ void *ctx,
+ request_rec *r,
+ conn_rec *c);
+
+/**
+ * Returns the filter handle for use with ap_add_input_filter_handle.
+ *
+ * @param name The filter name to look up
+ */
+AP_DECLARE(ap_filter_rec_t *) ap_get_input_filter_handle(const char *name);
+
+/**
+ * Add a filter to the current request. Filters are added in a FIFO manner.
+ * The first filter added will be the first filter called.
+ * @param name The name of the filter to add
+ * @param ctx Context data to set in the filter
+ * @param r The request to add this filter for (or NULL if it isn't associated with a request)
+ * @param c The connection to add this filter for
+ * @note If adding a connection-level output filter (i.e. where the type
+ * is >= AP_FTYPE_CONNECTION) during processing of a request, the request
+ * object r must be passed in to ensure the filter chains are modified
+ * correctly. f->r will still be initialized as NULL in the new filter.
+ */
+AP_DECLARE(ap_filter_t *) ap_add_output_filter(const char *name, void *ctx,
+ request_rec *r, conn_rec *c);
+
+/**
+ * Variant of ap_add_output_filter() that accepts a registered filter handle
+ * (as returned by ap_register_output_filter()) rather than a filter name
+ *
+ * @param f The filter handle to add
+ * @param ctx Context data to set in the filter
+ * @param r The request to add this filter for (or NULL if it isn't associated with a request)
+ * @param c The connection to add the filter for
+ * @note If adding a connection-level output filter (i.e. where the type
+ * is >= AP_FTYPE_CONNECTION) during processing of a request, the request
+ * object r must be passed in to ensure the filter chains are modified
+ * correctly. f->r will still be initialized as NULL in the new filter.
+ */
+AP_DECLARE(ap_filter_t *) ap_add_output_filter_handle(ap_filter_rec_t *f,
+ void *ctx,
+ request_rec *r,
+ conn_rec *c);
+
+/**
+ * Returns the filter handle for use with ap_add_output_filter_handle.
+ *
+ * @param name The filter name to look up
+ */
+AP_DECLARE(ap_filter_rec_t *) ap_get_output_filter_handle(const char *name);
+
+/**
+ * Remove an input filter from either the request or connection stack
+ * it is associated with.
+ * @param f The filter to remove
+ */
+
+AP_DECLARE(void) ap_remove_input_filter(ap_filter_t *f);
+
+/**
+ * Remove an output filter from either the request or connection stack
+ * it is associated with.
+ * @param f The filter to remove
+ */
+
+AP_DECLARE(void) ap_remove_output_filter(ap_filter_t *f);
+
+/**
+ * Remove an input filter from either the request or connection stack
+ * it is associated with.
+ * @param next The filter stack to search
+ * @param handle The filter handle (name) to remove
+ * @return APR_SUCCESS on removal or error
+ */
+AP_DECLARE(apr_status_t) ap_remove_input_filter_byhandle(ap_filter_t *next,
+ const char *handle);
+/**
+ * Remove an output filter from either the request or connection stack
+ * it is associated with.
+ * @param next The filter stack to search
+ * @param handle The filter handle (name) to remove
+ * @return APR_SUCCESS on removal or error
+ */
+AP_DECLARE(apr_status_t) ap_remove_output_filter_byhandle(ap_filter_t *next,
+ const char *handle);
+
+/* The next two filters are for abstraction purposes only. They could be
+ * done away with, but that would require that we break modules if we ever
+ * want to change our filter registration method. The basic idea, is that
+ * all filters have a place to store data, the ctx pointer. These functions
+ * fill out that pointer with a bucket brigade, and retrieve that data on
+ * the next call. The nice thing about these functions, is that they
+ * automatically concatenate the bucket brigades together for you. This means
+ * that if you have already stored a brigade in the filters ctx pointer, then
+ * when you add more it will be tacked onto the end of that brigade. When
+ * you retrieve data, if you pass in a bucket brigade to the get function,
+ * it will append the current brigade onto the one that you are retrieving.
+ */
+
+/**
+ * prepare a bucket brigade to be setaside. If a different brigade was
+ * set-aside earlier, then the two brigades are concatenated together.
+ * @param f The current filter
+ * @param save_to The brigade that was previously set-aside. Regardless, the
+ * new bucket brigade is returned in this location.
+ * @param b The bucket brigade to save aside. This brigade is always empty
+ * on return
+ * @param p Ensure that all data in the brigade lives as long as this pool
+ */
+AP_DECLARE(apr_status_t) ap_save_brigade(ap_filter_t *f,
+ apr_bucket_brigade **save_to,
+ apr_bucket_brigade **b, apr_pool_t *p);
+
+/**
+ * Flush function for apr_brigade_* calls. This calls ap_pass_brigade
+ * to flush the brigade if the brigade buffer overflows.
+ * @param bb The brigade to flush
+ * @param ctx The filter to pass the brigade to
+ * @note this function has nothing to do with FLUSH buckets. It is simply
+ * a way to flush content out of a brigade and down a filter stack.
+ */
+AP_DECLARE_NONSTD(apr_status_t) ap_filter_flush(apr_bucket_brigade *bb,
+ void *ctx);
+
+/**
+ * Flush the current brigade down the filter stack.
+ * @param f The filter we are passing to
+ * @param bb The brigade to flush
+ */
+AP_DECLARE(apr_status_t) ap_fflush(ap_filter_t *f, apr_bucket_brigade *bb);
+
+/**
+ * Write a buffer for the current filter, buffering if possible.
+ * @param f the filter we are writing to
+ * @param bb The brigade to buffer into
+ * @param data The data to write
+ * @param nbyte The number of bytes in the data
+ */
+#define ap_fwrite(f, bb, data, nbyte) \
+ apr_brigade_write(bb, ap_filter_flush, f, data, nbyte)
+
+/**
+ * Write a buffer for the current filter, buffering if possible.
+ * @param f the filter we are writing to
+ * @param bb The brigade to buffer into
+ * @param str The string to write
+ */
+#define ap_fputs(f, bb, str) \
+ apr_brigade_write(bb, ap_filter_flush, f, str, strlen(str))
+
+/**
+ * Write a character for the current filter, buffering if possible.
+ * @param f the filter we are writing to
+ * @param bb The brigade to buffer into
+ * @param c The character to write
+ */
+#define ap_fputc(f, bb, c) \
+ apr_brigade_putc(bb, ap_filter_flush, f, c)
+
+/**
+ * Write an unspecified number of strings to the current filter
+ * @param f the filter we are writing to
+ * @param bb The brigade to buffer into
+ * @param ... The strings to write
+ */
+AP_DECLARE_NONSTD(apr_status_t) ap_fputstrs(ap_filter_t *f,
+ apr_bucket_brigade *bb,
+ ...)
+ AP_FN_ATTR_SENTINEL;
+
+/**
+ * Output data to the filter in printf format
+ * @param f the filter we are writing to
+ * @param bb The brigade to buffer into
+ * @param fmt The format string
+ * @param ... The arguments to use to fill out the format string
+ */
+AP_DECLARE_NONSTD(apr_status_t) ap_fprintf(ap_filter_t *f,
+ apr_bucket_brigade *bb,
+ const char *fmt,
+ ...)
+ __attribute__((format(printf,3,4)));
+
+/**
+ * set protocol requirements for an output content filter
+ * (only works with AP_FTYPE_RESOURCE and AP_FTYPE_CONTENT_SET)
+ * @param f the filter in question
+ * @param proto_flags Logical OR of AP_FILTER_PROTO_* bits
+ */
+AP_DECLARE(void) ap_filter_protocol(ap_filter_t* f, unsigned int proto_flags);
+
+/** Filter changes contents (so invalidating checksums/etc) */
+#define AP_FILTER_PROTO_CHANGE 0x1
+
+/** Filter changes length of contents (so invalidating content-length/etc) */
+#define AP_FILTER_PROTO_CHANGE_LENGTH 0x2
+
+/** Filter requires complete input and can't work on byteranges */
+#define AP_FILTER_PROTO_NO_BYTERANGE 0x4
+
+/** Filter should not run in a proxy */
+#define AP_FILTER_PROTO_NO_PROXY 0x8
+
+/** Filter makes output non-cacheable */
+#define AP_FILTER_PROTO_NO_CACHE 0x10
+
+/** Filter is incompatible with "Cache-Control: no-transform" */
+#define AP_FILTER_PROTO_TRANSFORM 0x20
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !AP_FILTER_H */
diff --git a/include/util_ldap.h b/include/util_ldap.h
new file mode 100644
index 0000000..f7cd736
--- /dev/null
+++ b/include/util_ldap.h
@@ -0,0 +1,398 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file util_ldap.h
+ * @brief Apache LDAP library
+ */
+
+#ifndef UTIL_LDAP_H
+#define UTIL_LDAP_H
+
+/* APR header files */
+#include "apr.h"
+#include "apr_thread_mutex.h"
+#include "apr_thread_rwlock.h"
+#include "apr_tables.h"
+#include "apr_time.h"
+#include "apr_version.h"
+#if APR_MAJOR_VERSION < 2
+/* The LDAP API is currently only present in APR 1.x */
+#include "apr_ldap.h"
+#include "apr_ldap_rebind.h"
+#else
+#define APR_HAS_LDAP 0
+#endif
+
+#if APR_HAS_SHARED_MEMORY
+#include "apr_rmm.h"
+#include "apr_shm.h"
+#endif
+
+/* this whole thing disappears if LDAP is not enabled */
+#if APR_HAS_LDAP
+
+#if defined(LDAP_UNAVAILABLE) || APR_HAS_MICROSOFT_LDAPSDK
+#define AP_LDAP_IS_SERVER_DOWN(s) ((s) == LDAP_SERVER_DOWN \
+ ||(s) == LDAP_UNAVAILABLE)
+#else
+#define AP_LDAP_IS_SERVER_DOWN(s) ((s) == LDAP_SERVER_DOWN)
+#endif
+
+/* Apache header files */
+#include "ap_config.h"
+#include "httpd.h"
+#include "http_config.h"
+#include "http_core.h"
+#include "http_log.h"
+#include "http_protocol.h"
+#include "http_request.h"
+#include "apr_optional.h"
+
+/* Create a set of LDAP_DECLARE macros with appropriate export
+ * and import tags for the platform
+ */
+#if !defined(WIN32)
+#define LDAP_DECLARE(type) type
+#define LDAP_DECLARE_NONSTD(type) type
+#define LDAP_DECLARE_DATA
+#elif defined(LDAP_DECLARE_STATIC)
+#define LDAP_DECLARE(type) type __stdcall
+#define LDAP_DECLARE_NONSTD(type) type
+#define LDAP_DECLARE_DATA
+#elif defined(LDAP_DECLARE_EXPORT)
+#define LDAP_DECLARE(type) __declspec(dllexport) type __stdcall
+#define LDAP_DECLARE_NONSTD(type) __declspec(dllexport) type
+#define LDAP_DECLARE_DATA __declspec(dllexport)
+#else
+#define LDAP_DECLARE(type) __declspec(dllimport) type __stdcall
+#define LDAP_DECLARE_NONSTD(type) __declspec(dllimport) type
+#define LDAP_DECLARE_DATA __declspec(dllimport)
+#endif
+
+#if APR_HAS_MICROSOFT_LDAPSDK
+#define timeval l_timeval
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * LDAP Connections
+ */
+
+/* Values that the deref member can have */
+typedef enum {
+ never=LDAP_DEREF_NEVER,
+ searching=LDAP_DEREF_SEARCHING,
+ finding=LDAP_DEREF_FINDING,
+ always=LDAP_DEREF_ALWAYS
+} deref_options;
+
+/* Structure representing an LDAP connection */
+typedef struct util_ldap_connection_t {
+ LDAP *ldap;
+ apr_pool_t *pool; /* Pool from which this connection is created */
+#if APR_HAS_THREADS
+ apr_thread_mutex_t *lock; /* Lock to indicate this connection is in use */
+#endif
+
+ const char *host; /* Name of the LDAP server (or space separated list) */
+ int port; /* Port of the LDAP server */
+ deref_options deref; /* how to handle alias dereferening */
+
+ const char *binddn; /* DN to bind to server (can be NULL) */
+ const char *bindpw; /* Password to bind to server (can be NULL) */
+
+ int bound; /* Flag to indicate whether this connection is bound yet */
+
+ int secure; /* SSL/TLS mode of the connection */
+ apr_array_header_t *client_certs; /* Client certificates on this connection */
+
+ const char *reason; /* Reason for an error failure */
+
+ struct util_ldap_connection_t *next;
+ struct util_ldap_state_t *st; /* The LDAP vhost config this connection belongs to */
+ int keep; /* Will this connection be kept when it's unlocked */
+
+ int ChaseReferrals; /* [on|off] (default = AP_LDAP_CHASEREFERRALS_ON)*/
+ int ReferralHopLimit; /* # of referral hops to follow (default = AP_LDAP_DEFAULT_HOPLIMIT) */
+ apr_time_t freed; /* the time this conn was placed back in the pool */
+ apr_pool_t *rebind_pool; /* frequently cleared pool for rebind data */
+ int must_rebind; /* The connection was last bound with other then binddn/bindpw */
+ request_rec *r; /* request_rec used to find this util_ldap_connection_t */
+ apr_time_t last_backend_conn; /* the approximate time of the last backend LDAP requst */
+} util_ldap_connection_t;
+
+typedef struct util_ldap_config_t {
+ int ChaseReferrals;
+ int ReferralHopLimit;
+ apr_array_header_t *client_certs; /* Client certificates */
+} util_ldap_config_t;
+
+/* LDAP cache state information */
+typedef struct util_ldap_state_t {
+ apr_pool_t *pool; /* pool from which this state is allocated */
+#if APR_HAS_THREADS
+ apr_thread_mutex_t *mutex; /* mutex lock for the connection list */
+#endif
+ apr_global_mutex_t *util_ldap_cache_lock;
+
+ apr_size_t cache_bytes; /* Size (in bytes) of shared memory cache */
+ char *cache_file; /* filename for shm */
+ long search_cache_ttl; /* TTL for search cache */
+ long search_cache_size; /* Size (in entries) of search cache */
+ long compare_cache_ttl; /* TTL for compare cache */
+ long compare_cache_size; /* Size (in entries) of compare cache */
+
+ struct util_ldap_connection_t *connections;
+ apr_array_header_t *global_certs; /* Global CA certificates */
+ int ssl_supported;
+ int secure;
+ int secure_set;
+ int verify_svr_cert;
+
+#if APR_HAS_SHARED_MEMORY
+ apr_shm_t *cache_shm;
+ apr_rmm_t *cache_rmm;
+#endif
+
+ /* cache ald */
+ void *util_ldap_cache;
+
+ long connectionTimeout;
+ struct timeval *opTimeout;
+
+ int debug_level; /* SDK debug level */
+ apr_interval_time_t connection_pool_ttl;
+ int retries; /* number of retries for failed bind/search/compare */
+ apr_interval_time_t retry_delay; /* delay between retries of failed bind/search/compare */
+} util_ldap_state_t;
+
+/* Used to store arrays of attribute labels/values. */
+struct mod_auth_ldap_groupattr_entry_t {
+ char *name;
+};
+
+/**
+ * Open a connection to an LDAP server
+ * @param ldc A structure containing the expanded details of the server
+ * to connect to. The handle to the LDAP connection is returned
+ * as ldc->ldap.
+ * @tip This function connects to the LDAP server and binds. It does not
+ * connect if already connected (ldc->ldap != NULL). Does not bind
+ * if already bound.
+ * @return If successful LDAP_SUCCESS is returned.
+ * @fn int util_ldap_connection_open(request_rec *r,
+ * util_ldap_connection_t *ldc)
+ */
+APR_DECLARE_OPTIONAL_FN(int,uldap_connection_open,(request_rec *r,
+ util_ldap_connection_t *ldc));
+
+/**
+ * Close a connection to an LDAP server
+ * @param ldc A structure containing the expanded details of the server
+ * that was connected.
+ * @tip This function unbinds from the LDAP server, and clears ldc->ldap.
+ * It is possible to rebind to this server again using the same ldc
+ * structure, using apr_ldap_open_connection().
+ * @fn util_ldap_close_connection(util_ldap_connection_t *ldc)
+ */
+APR_DECLARE_OPTIONAL_FN(void,uldap_connection_close,(util_ldap_connection_t *ldc));
+
+/**
+ * Unbind a connection to an LDAP server
+ * @param ldc A structure containing the expanded details of the server
+ * that was connected.
+ * @tip This function unbinds the LDAP connection, and disconnects from
+ * the server. It is used during error conditions, to bring the LDAP
+ * connection back to a known state.
+ * @fn apr_status_t util_ldap_connection_unbind(util_ldap_connection_t *ldc)
+ */
+APR_DECLARE_OPTIONAL_FN(apr_status_t,uldap_connection_unbind,(void *param));
+
+/**
+ * Find a connection in a list of connections
+ * @param r The request record
+ * @param host The hostname to connect to (multiple hosts space separated)
+ * @param port The port to connect to
+ * @param binddn The DN to bind with
+ * @param bindpw The password to bind with
+ * @param deref The dereferencing behavior
+ * @param secure use SSL on the connection
+ * @tip Once a connection is found and returned, a lock will be acquired to
+ * lock that particular connection, so that another thread does not try and
+ * use this connection while it is busy. Once you are finished with a connection,
+ * apr_ldap_connection_close() must be called to release this connection.
+ * @fn util_ldap_connection_t *util_ldap_connection_find(request_rec *r, const char *host, int port,
+ * const char *binddn, const char *bindpw, deref_options deref,
+ * int netscapessl, int starttls)
+ */
+APR_DECLARE_OPTIONAL_FN(util_ldap_connection_t *,uldap_connection_find,(request_rec *r, const char *host, int port,
+ const char *binddn, const char *bindpw, deref_options deref,
+ int secure));
+
+/**
+ * Compare two DNs for sameness
+ * @param r The request record
+ * @param ldc The LDAP connection being used.
+ * @param url The URL of the LDAP connection - used for deciding which cache to use.
+ * @param dn The first DN to compare.
+ * @param reqdn The DN to compare the first DN to.
+ * @param compare_dn_on_server Flag to determine whether the DNs should be checked using
+ * LDAP calls or with a direct string comparison. A direct
+ * string comparison is faster, but not as accurate - false
+ * negative comparisons are possible.
+ * @tip Two DNs can be equal and still fail a string comparison. Eg "dc=example,dc=com"
+ * and "dc=example, dc=com". Use the compare_dn_on_server unless there are serious
+ * performance issues.
+ * @fn int util_ldap_cache_comparedn(request_rec *r, util_ldap_connection_t *ldc,
+ * const char *url, const char *dn, const char *reqdn,
+ * int compare_dn_on_server)
+ */
+APR_DECLARE_OPTIONAL_FN(int,uldap_cache_comparedn,(request_rec *r, util_ldap_connection_t *ldc,
+ const char *url, const char *dn, const char *reqdn,
+ int compare_dn_on_server));
+
+/**
+ * A generic LDAP compare function
+ * @param r The request record
+ * @param ldc The LDAP connection being used.
+ * @param url The URL of the LDAP connection - used for deciding which cache to use.
+ * @param dn The DN of the object in which we do the compare.
+ * @param attrib The attribute within the object we are comparing for.
+ * @param value The value of the attribute we are trying to compare for.
+ * @tip Use this function to determine whether an attribute/value pair exists within an
+ * object. Typically this would be used to determine LDAP top-level group
+ * membership.
+ * @fn int util_ldap_cache_compare(request_rec *r, util_ldap_connection_t *ldc,
+ * const char *url, const char *dn, const char *attrib, const char *value)
+ */
+APR_DECLARE_OPTIONAL_FN(int,uldap_cache_compare,(request_rec *r, util_ldap_connection_t *ldc,
+ const char *url, const char *dn, const char *attrib, const char *value));
+
+/**
+ * An LDAP function that checks if the specified user is a member of a subgroup.
+ * @param r The request record
+ * @param ldc The LDAP connection being used.
+ * @param url The URL of the LDAP connection - used for deciding which cache to use.
+ * @param dn The DN of the object in which we find subgroups to search within.
+ * @param attrib The attribute within group objects that identify users.
+ * @param value The user attribute value we are trying to compare for.
+ * @param subgroupAttrs The attributes within group objects that identify subgroups.
+ * Array of strings.
+ * @param subgroupclasses The objectClass values used to identify groups (and
+ * subgroups). apr_array_header_t *.
+ * @param cur_subgroup_depth Current recursive depth during subgroup processing.
+ * @param max_subgroup_depth Maximum depth of recursion allowed during subgroup
+ * processing.
+ * @tip Use this function to determine whether an attribute/value pair exists within a
+ * starting group object or one of its nested subgroups. Typically this would be
+ * used to determine LDAP nested group membership.
+ * @deffunc int util_ldap_cache_check_subgroups(request_rec *r, util_ldap_connection_t
+ * *ldc, const char *url, const char *dn,
+ * const char *attrib, const char value,
+ * char **subgroupAttrs, apr_array_header_t
+ * *subgroupclasses, int cur_subgroup_depth, int
+ * max_subgroup_depth )
+ */
+APR_DECLARE_OPTIONAL_FN(int,uldap_cache_check_subgroups,(request_rec *r, util_ldap_connection_t *ldc,
+ const char *url, const char *dn, const char *attrib, const char *value,
+ char **subgroupAttrs, apr_array_header_t *subgroupclasses,
+ int cur_subgroup_depth, int max_subgroup_depth));
+
+/**
+ * Checks a username/password combination by binding to the LDAP server
+ * @param r The request record
+ * @param ldc The LDAP connection being used.
+ * @param url The URL of the LDAP connection - used for deciding which cache to use.
+ * @param basedn The Base DN to search for the user in.
+ * @param scope LDAP scope of the search.
+ * @param attrs LDAP attributes to return in search.
+ * @param filter The user to search for in the form of an LDAP filter. This filter must return
+ * exactly one user for the check to be successful.
+ * @param bindpw The user password to bind as.
+ * @param binddn The DN of the user will be returned in this variable.
+ * @param retvals The values corresponding to the attributes requested in the attrs array.
+ * @tip The filter supplied will be searched for. If a single entry is returned, an attempt
+ * is made to bind as that user. If this bind succeeds, the user is not validated.
+ * @fn int util_ldap_cache_checkuserid(request_rec *r, util_ldap_connection_t *ldc,
+ * char *url, const char *basedn, int scope, char **attrs,
+ * char *filter, char *bindpw, char **binddn, char ***retvals)
+ */
+APR_DECLARE_OPTIONAL_FN(int,uldap_cache_checkuserid,(request_rec *r, util_ldap_connection_t *ldc,
+ const char *url, const char *basedn, int scope, char **attrs,
+ const char *filter, const char *bindpw, const char **binddn, const char ***retvals));
+
+/**
+ * Searches for a specified user object in an LDAP directory
+ * @param r The request record
+ * @param ldc The LDAP connection being used.
+ * @param url The URL of the LDAP connection - used for deciding which cache to use.
+ * @param basedn The Base DN to search for the user in.
+ * @param scope LDAP scope of the search.
+ * @param attrs LDAP attributes to return in search.
+ * @param filter The user to search for in the form of an LDAP filter. This filter must return
+ * exactly one user for the check to be successful.
+ * @param binddn The DN of the user will be returned in this variable.
+ * @param retvals The values corresponding to the attributes requested in the attrs array.
+ * @tip The filter supplied will be searched for. If a single entry is returned, an attempt
+ * is made to bind as that user. If this bind succeeds, the user is not validated.
+ * @fn int util_ldap_cache_getuserdn(request_rec *r, util_ldap_connection_t *ldc,
+ * char *url, const char *basedn, int scope, char **attrs,
+ * char *filter, char **binddn, char ***retvals)
+ */
+APR_DECLARE_OPTIONAL_FN(int,uldap_cache_getuserdn,(request_rec *r, util_ldap_connection_t *ldc,
+ const char *url, const char *basedn, int scope, char **attrs,
+ const char *filter, const char **binddn, const char ***retvals));
+
+/**
+ * Checks if SSL support is available in mod_ldap
+ * @fn int util_ldap_ssl_supported(request_rec *r)
+ */
+APR_DECLARE_OPTIONAL_FN(int,uldap_ssl_supported,(request_rec *r));
+
+/* from apr_ldap_cache.c */
+
+/**
+ * Init the LDAP cache
+ * @param pool The pool to use to initialise the cache
+ * @param reqsize The size of the shared memory segment to request. A size
+ * of zero requests the max size possible from
+ * apr_shmem_init()
+ * @fn void util_ldap_cache_init(apr_pool_t *p, util_ldap_state_t *st)
+ * @return The status code returned is the status code of the
+ * apr_smmem_init() call. Regardless of the status, the cache
+ * will be set up at least for in-process or in-thread operation.
+ */
+apr_status_t util_ldap_cache_init(apr_pool_t *pool, util_ldap_state_t *st);
+
+/* from apr_ldap_cache_mgr.c */
+
+/**
+ * Display formatted stats for cache
+ * @param The pool to allocate the returned string from
+ * @tip This function returns a string allocated from the provided pool that describes
+ * various stats about the cache.
+ * @fn char *util_ald_cache_display(apr_pool_t *pool, util_ldap_state_t *st)
+ */
+char *util_ald_cache_display(request_rec *r, util_ldap_state_t *st);
+#ifdef __cplusplus
+}
+#endif
+#endif /* APR_HAS_LDAP */
+#endif /* UTIL_LDAP_H */
diff --git a/include/util_md5.h b/include/util_md5.h
new file mode 100644
index 0000000..0287ef9
--- /dev/null
+++ b/include/util_md5.h
@@ -0,0 +1,72 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file util_md5.h
+ * @brief Apache MD5 library
+ *
+ * @defgroup APACHE_CORE_MD5 MD5 Package Library
+ * @ingroup APACHE_CORE
+ * @{
+ */
+
+#ifndef APACHE_UTIL_MD5_H
+#define APACHE_UTIL_MD5_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "apr_md5.h"
+
+/**
+ * Create an MD5 checksum of a given string.
+ * @param a Pool to allocate out of
+ * @param string String to get the checksum of
+ * @return The checksum
+ */
+AP_DECLARE(char *) ap_md5(apr_pool_t *a, const unsigned char *string);
+
+/**
+ * Create an MD5 checksum of a string of binary data.
+ * @param a Pool to allocate out of
+ * @param buf Buffer to generate checksum for
+ * @param len The length of the buffer
+ * @return The checksum
+ */
+AP_DECLARE(char *) ap_md5_binary(apr_pool_t *a, const unsigned char *buf, int len);
+
+/**
+ * Convert an MD5 checksum into a base64 encoding.
+ * @param p The pool to allocate out of
+ * @param context The context to convert
+ * @return The converted encoding
+ */
+AP_DECLARE(char *) ap_md5contextTo64(apr_pool_t *p, apr_md5_ctx_t *context);
+
+/**
+ * Create an MD5 Digest for a given file.
+ * @param p The pool to allocate out of
+ * @param infile The file to create the digest for
+ */
+AP_DECLARE(char *) ap_md5digest(apr_pool_t *p, apr_file_t *infile);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !APACHE_UTIL_MD5_H */
+/** @} */
diff --git a/include/util_mutex.h b/include/util_mutex.h
new file mode 100644
index 0000000..1cb89c8
--- /dev/null
+++ b/include/util_mutex.h
@@ -0,0 +1,223 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file util_mutex.h
+ * @brief Apache Mutex support library
+ *
+ * @defgroup APACHE_CORE_MUTEX Mutex Library
+ * @ingroup APACHE_CORE
+ * @{
+ */
+
+#ifndef UTIL_MUTEX_H
+#define UTIL_MUTEX_H
+
+#include "httpd.h"
+#include "http_config.h"
+#include "apr_global_mutex.h"
+
+#if APR_HAS_FLOCK_SERIALIZE
+# define AP_LIST_FLOCK_SERIALIZE ", 'flock:/path/to/file'"
+#else
+# define AP_LIST_FLOCK_SERIALIZE
+#endif
+#if APR_HAS_FCNTL_SERIALIZE
+# define AP_LIST_FCNTL_SERIALIZE ", 'fcntl:/path/to/file'"
+#else
+# define AP_LIST_FCNTL_SERIALIZE
+#endif
+#if APR_HAS_SYSVSEM_SERIALIZE
+# define AP_LIST_SYSVSEM_SERIALIZE ", 'sysvsem'"
+#else
+# define AP_LIST_SYSVSEM_SERIALIZE
+#endif
+#if APR_HAS_POSIXSEM_SERIALIZE
+# define AP_LIST_POSIXSEM_SERIALIZE ", 'posixsem'"
+#else
+# define AP_LIST_POSIXSEM_SERIALIZE
+#endif
+#if APR_HAS_PROC_PTHREAD_SERIALIZE
+# define AP_LIST_PTHREAD_SERIALIZE ", 'pthread'"
+#else
+# define AP_LIST_PTHREAD_SERIALIZE
+#endif
+#if APR_HAS_FLOCK_SERIALIZE || APR_HAS_FCNTL_SERIALIZE
+# define AP_LIST_FILE_SERIALIZE ", 'file:/path/to/file'"
+#else
+# define AP_LIST_FILE_SERIALIZE
+#endif
+#if APR_HAS_SYSVSEM_SERIALIZE || APR_HAS_POSIXSEM_SERIALIZE
+# define AP_LIST_SEM_SERIALIZE ", 'sem'"
+#else
+# define AP_LIST_SEM_SERIALIZE
+#endif
+
+#define AP_ALL_AVAILABLE_MUTEXES_STRING \
+ "Mutex mechanisms are: 'none', 'default'" \
+ AP_LIST_FLOCK_SERIALIZE AP_LIST_FCNTL_SERIALIZE \
+ AP_LIST_FILE_SERIALIZE AP_LIST_PTHREAD_SERIALIZE \
+ AP_LIST_SYSVSEM_SERIALIZE AP_LIST_POSIXSEM_SERIALIZE \
+ AP_LIST_SEM_SERIALIZE
+
+#define AP_AVAILABLE_MUTEXES_STRING \
+ "Mutex mechanisms are: 'default'" \
+ AP_LIST_FLOCK_SERIALIZE AP_LIST_FCNTL_SERIALIZE \
+ AP_LIST_FILE_SERIALIZE AP_LIST_PTHREAD_SERIALIZE \
+ AP_LIST_SYSVSEM_SERIALIZE AP_LIST_POSIXSEM_SERIALIZE \
+ AP_LIST_SEM_SERIALIZE
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Get Mutex config data and parse it
+ * @param arg The mutex config string
+ * @param pool The allocation pool
+ * @param mutexmech The APR mutex locking mechanism
+ * @param mutexfile The lockfile to use as required
+ * @return APR status code
+ * @fn apr_status_t ap_parse_mutex(const char *arg, apr_pool_t *pool,
+ apr_lockmech_e *mutexmech,
+ const char **mutexfile)
+ */
+AP_DECLARE(apr_status_t) ap_parse_mutex(const char *arg, apr_pool_t *pool,
+ apr_lockmech_e *mutexmech,
+ const char **mutexfile);
+
+/* private function to process the Mutex directive */
+AP_DECLARE_NONSTD(const char *) ap_set_mutex(cmd_parms *cmd, void *dummy,
+ const char *arg);
+
+/* private function to initialize Mutex infrastructure */
+AP_DECLARE_NONSTD(void) ap_mutex_init(apr_pool_t *p);
+
+/**
+ * option flags for ap_mutex_register(), ap_global_mutex_create(), and
+ * ap_proc_mutex_create()
+ */
+#define AP_MUTEX_ALLOW_NONE 1 /* allow "none" as mutex implementation;
+ * respected only on ap_mutex_register()
+ */
+#define AP_MUTEX_DEFAULT_NONE 2 /* default to "none" for this mutex;
+ * respected only on ap_mutex_register()
+ */
+
+/**
+ * Register a module's mutex type with core to allow configuration
+ * with the Mutex directive. This must be called in the pre_config
+ * hook; otherwise, configuration directives referencing this mutex
+ * type will be rejected.
+ *
+ * The default_dir and default_mech parameters allow a module to set
+ * defaults for the lock file directory and mechanism. These could
+ * be based on compile-time settings. These aren't required except
+ * in special circumstances.
+ *
+ * The order of precedence for the choice of mechanism and lock file
+ * directory is:
+ *
+ * 1. Mutex directive specifically for this mutex
+ * e.g., Mutex mpm-default flock:/tmp/mpmlocks
+ * 2. Mutex directive for global default
+ * e.g., Mutex default flock:/tmp/httpdlocks
+ * 3. Defaults for this mutex provided on the ap_mutex_register()
+ * 4. Built-in defaults for all mutexes, which are
+ * APR_LOCK_DEFAULT and DEFAULT_REL_RUNTIMEDIR.
+ *
+ * @param pconf The pconf pool
+ * @param type The type name of the mutex, used as the basename of the
+ * file associated with the mutex, if any. This must be unique among
+ * all mutex types (mutex creation accommodates multi-instance mutex
+ * types); mod_foo might have mutex types "foo-pipe" and "foo-shm"
+ * @param default_dir Default dir for any lock file required for this
+ * lock, to override built-in defaults; should be NULL for most
+ * modules, to respect built-in defaults
+ * @param default_mech Default mechanism for this lock, to override
+ * built-in defaults; should be APR_LOCK_DEFAULT for most modules, to
+ * respect built-in defaults
+ * or NULL if there are no defaults for this mutex.
+ * @param options combination of AP_MUTEX_* constants, or 0 for defaults
+ */
+AP_DECLARE(apr_status_t) ap_mutex_register(apr_pool_t *pconf,
+ const char *type,
+ const char *default_dir,
+ apr_lockmech_e default_mech,
+ apr_int32_t options);
+
+/**
+ * Create an APR global mutex that has been registered previously with
+ * ap_mutex_register(). Mutex files, permissions, and error logging will
+ * be handled internally.
+ * @param mutex The memory address where the newly created mutex will be
+ * stored. If this mutex is disabled, mutex will be set to NULL on
+ * output. (That is allowed only if the AP_MUTEX_ALLOW_NONE flag is
+ * passed to ap_mutex_register().)
+ * @param name The generated filename of the created mutex, or NULL if
+ * no file was created. Pass NULL if this result is not needed.
+ * @param type The type name of the mutex, matching the type name passed
+ * to ap_mutex_register().
+ * @param instance_id A unique string to be used in the lock filename IFF
+ * this mutex type is multi-instance, NULL otherwise.
+ * @param server server_rec of main server
+ * @param pool pool lifetime of the mutex
+ * @param options combination of AP_MUTEX_* constants, or 0 for defaults
+ * (currently none are defined for this function)
+ */
+AP_DECLARE(apr_status_t) ap_global_mutex_create(apr_global_mutex_t **mutex,
+ const char **name,
+ const char *type,
+ const char *instance_id,
+ server_rec *server,
+ apr_pool_t *pool,
+ apr_int32_t options);
+
+/**
+ * Create an APR proc mutex that has been registered previously with
+ * ap_mutex_register(). Mutex files, permissions, and error logging will
+ * be handled internally.
+ * @param mutex The memory address where the newly created mutex will be
+ * stored. If this mutex is disabled, mutex will be set to NULL on
+ * output. (That is allowed only if the AP_MUTEX_ALLOW_NONE flag is
+ * passed to ap_mutex_register().)
+ * @param name The generated filename of the created mutex, or NULL if
+ * no file was created. Pass NULL if this result is not needed.
+ * @param type The type name of the mutex, matching the type name passed
+ * to ap_mutex_register().
+ * @param instance_id A unique string to be used in the lock filename IFF
+ * this mutex type is multi-instance, NULL otherwise.
+ * @param server server_rec of main server
+ * @param pool pool lifetime of the mutex
+ * @param options combination of AP_MUTEX_* constants, or 0 for defaults
+ * (currently none are defined for this function)
+ */
+AP_DECLARE(apr_status_t) ap_proc_mutex_create(apr_proc_mutex_t **mutex,
+ const char **name,
+ const char *type,
+ const char *instance_id,
+ server_rec *server,
+ apr_pool_t *pool,
+ apr_int32_t options);
+
+AP_CORE_DECLARE(void) ap_dump_mutexes(apr_pool_t *p, server_rec *s, apr_file_t *out);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* UTIL_MUTEX_H */
+/** @} */
diff --git a/include/util_script.h b/include/util_script.h
new file mode 100644
index 0000000..3566bd3
--- /dev/null
+++ b/include/util_script.h
@@ -0,0 +1,233 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file util_script.h
+ * @brief Apache script tools
+ *
+ * @defgroup APACHE_CORE_SCRIPT Script Tools
+ * @ingroup APACHE_CORE
+ * @{
+ */
+
+#ifndef APACHE_UTIL_SCRIPT_H
+#define APACHE_UTIL_SCRIPT_H
+
+#include "apr_buckets.h"
+#include "ap_config.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef APACHE_ARG_MAX
+#ifdef _POSIX_ARG_MAX
+#define APACHE_ARG_MAX _POSIX_ARG_MAX
+#else
+#define APACHE_ARG_MAX 512
+#endif
+#endif
+
+/**
+ * Create an environment variable out of an Apache table of key-value pairs
+ * @param p pool to allocate out of
+ * @param t Apache table of key-value pairs
+ * @return An array containing the same key-value pairs suitable for
+ * use with an exec call.
+ * @fn char **ap_create_environment(apr_pool_t *p, apr_table_t *t)
+ */
+AP_DECLARE(char **) ap_create_environment(apr_pool_t *p, apr_table_t *t);
+
+/**
+ * This "cute" little function comes about because the path info on
+ * filenames and URLs aren't always the same. So we take the two,
+ * and find as much of the two that match as possible.
+ * @param uri The uri we are currently parsing
+ * @param path_info The current path info
+ * @return The length of the path info
+ * @fn int ap_find_path_info(const char *uri, const char *path_info)
+ */
+AP_DECLARE(int) ap_find_path_info(const char *uri, const char *path_info);
+
+/**
+ * Add CGI environment variables required by HTTP/1.1 to the request's
+ * environment table
+ * @param r the current request
+ * @fn void ap_add_cgi_vars(request_rec *r)
+ */
+AP_DECLARE(void) ap_add_cgi_vars(request_rec *r);
+
+/**
+ * Add common CGI environment variables to the requests environment table
+ * @param r The current request
+ * @fn void ap_add_common_vars(request_rec *r)
+ */
+AP_DECLARE(void) ap_add_common_vars(request_rec *r);
+
+/**
+ * Read headers output from a script, ensuring that the output is valid. If
+ * the output is valid, then the headers are added to the headers out of the
+ * current request
+ * @param r The current request
+ * @param f The file to read from
+ * @param buffer Empty when calling the function. On output, if there was an
+ * error, the string that cause the error is stored here.
+ * @return HTTP_OK on success, HTTP_INTERNAL_SERVER_ERROR otherwise
+ * @fn int ap_scan_script_header_err(request_rec *r, apr_file_t *f, char *buffer)
+ */
+AP_DECLARE(int) ap_scan_script_header_err(request_rec *r, apr_file_t *f, char *buffer);
+
+/**
+ * Read headers output from a script, ensuring that the output is valid. If
+ * the output is valid, then the headers are added to the headers out of the
+ * current request
+ * @param r The current request
+ * @param f The file to read from
+ * @param buffer Empty when calling the function. On output, if there was an
+ * error, the string that cause the error is stored here.
+ * @param module_index The module index to be used for logging
+ * @return HTTP_OK on success, HTTP_INTERNAL_SERVER_ERROR otherwise
+ */
+AP_DECLARE(int) ap_scan_script_header_err_ex(request_rec *r, apr_file_t *f,
+ char *buffer, int module_index);
+
+
+/**
+ * Read headers output from a script, ensuring that the output is valid. If
+ * the output is valid, then the headers are added to the headers out of the
+ * current request
+ * @param r The current request
+ * @param bb The brigade from which to read
+ * @param buffer Empty when calling the function. On output, if there was an
+ * error, the string that cause the error is stored here.
+ * @return HTTP_OK on success, HTTP_INTERNAL_SERVER_ERROR otherwise
+ * @fn int ap_scan_script_header_err_brigade(request_rec *r, apr_bucket_brigade *bb, char *buffer)
+ */
+AP_DECLARE(int) ap_scan_script_header_err_brigade(request_rec *r,
+ apr_bucket_brigade *bb,
+ char *buffer);
+
+/**
+ * Read headers output from a script, ensuring that the output is valid. If
+ * the output is valid, then the headers are added to the headers out of the
+ * current request
+ * @param r The current request
+ * @param bb The brigade from which to read
+ * @param buffer Empty when calling the function. On output, if there was an
+ * error, the string that cause the error is stored here.
+ * @param module_index The module index to be used for logging
+ * @return HTTP_OK on success, HTTP_INTERNAL_SERVER_ERROR otherwise
+ */
+AP_DECLARE(int) ap_scan_script_header_err_brigade_ex(request_rec *r,
+ apr_bucket_brigade *bb,
+ char *buffer,
+ int module_index);
+
+/**
+ * Read headers strings from a script, ensuring that the output is valid. If
+ * the output is valid, then the headers are added to the headers out of the
+ * current request
+ * @param r The current request
+ * @param buffer Empty when calling the function. On output, if there was an
+ * error, the string that cause the error is stored here.
+ * @param termch Pointer to the last character parsed.
+ * @param termarg Pointer to an int to capture the last argument parsed.
+ *
+ * The varargs are string arguments to parse consecutively for headers,
+ * with a NULL argument to terminate the list.
+ *
+ * @return HTTP_OK on success, HTTP_INTERNAL_SERVER_ERROR otherwise
+ */
+AP_DECLARE_NONSTD(int) ap_scan_script_header_err_strs(request_rec *r,
+ char *buffer,
+ const char **termch,
+ int *termarg, ...)
+ AP_FN_ATTR_SENTINEL;
+
+/**
+ * Read headers strings from a script, ensuring that the output is valid. If
+ * the output is valid, then the headers are added to the headers out of the
+ * current request
+ * @param r The current request
+ * @param buffer Empty when calling the function. On output, if there was an
+ * error, the string that cause the error is stored here.
+ * @param module_index The module index to be used for logging
+ * @param termch Pointer to the last character parsed.
+ * @param termarg Pointer to an int to capture the last argument parsed.
+ *
+ * The varargs are string arguments to parse consecutively for headers,
+ * with a NULL argument to terminate the list.
+ *
+ * @return HTTP_OK on success, HTTP_INTERNAL_SERVER_ERROR otherwise
+ */
+AP_DECLARE_NONSTD(int) ap_scan_script_header_err_strs_ex(request_rec *r,
+ char *buffer,
+ int module_index,
+ const char **termch,
+ int *termarg, ...)
+ AP_FN_ATTR_SENTINEL;
+
+
+/**
+ * Read headers output from a script, ensuring that the output is valid. If
+ * the output is valid, then the headers are added to the headers out of the
+ * current request
+ * @param r The current request
+ * @param buffer Empty when calling the function. On output, if there was an
+ * error, the string that cause the error is stored here.
+ * @param getsfunc Function to read the headers from. This function should
+ act like gets()
+ * @param getsfunc_data The place to read from
+ * @return HTTP_OK on success, HTTP_INTERNAL_SERVER_ERROR otherwise
+ */
+AP_DECLARE(int) ap_scan_script_header_err_core(request_rec *r, char *buffer,
+ int (*getsfunc) (char *, int, void *),
+ void *getsfunc_data);
+
+/**
+ * Read headers output from a script, ensuring that the output is valid. If
+ * the output is valid, then the headers are added to the headers out of the
+ * current request
+ * @param r The current request
+ * @param buffer Empty when calling the function. On output, if there was an
+ * error, the string that cause the error is stored here.
+ * @param getsfunc Function to read the headers from. This function should
+ act like gets()
+ * @param getsfunc_data The place to read from
+ * @param module_index The module index to be used for logging
+ * @return HTTP_OK on success, HTTP_INTERNAL_SERVER_ERROR otherwise
+ */
+AP_DECLARE(int) ap_scan_script_header_err_core_ex(request_rec *r, char *buffer,
+ int (*getsfunc) (char *, int, void *),
+ void *getsfunc_data, int module_index);
+
+
+/**
+ * Parse query args for the request and store in a new table allocated
+ * from the request pool.
+ * For args with no value, "1" will be used instead.
+ * If no query args were specified, the table will be empty.
+ * @param r The current request
+ * @param table A new table on output.
+ */
+AP_DECLARE(void) ap_args_to_table(request_rec *r, apr_table_t **table);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !APACHE_UTIL_SCRIPT_H */
+/** @} */
diff --git a/include/util_time.h b/include/util_time.h
new file mode 100644
index 0000000..2cd2833
--- /dev/null
+++ b/include/util_time.h
@@ -0,0 +1,117 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file util_time.h
+ * @brief Apache date-time handling functions
+ *
+ * @defgroup APACHE_CORE_TIME Date-time handling functions
+ * @ingroup APACHE_CORE
+ * @{
+ */
+
+#ifndef APACHE_UTIL_TIME_H
+#define APACHE_UTIL_TIME_H
+
+#include "apr.h"
+#include "apr_time.h"
+#include "httpd.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Maximum delta from the current time, in seconds, for a past time
+ * to qualify as "recent" for use in the ap_explode_recent_*() functions:
+ * (Must be a power of two minus one!)
+ */
+#define AP_TIME_RECENT_THRESHOLD 15
+
+/* Options for ap_recent_ctime_ex */
+/* No extension */
+#define AP_CTIME_OPTION_NONE 0x0
+/* Add sub second timestamps with micro second resolution */
+#define AP_CTIME_OPTION_USEC 0x1
+/* Use more compact ISO 8601 format */
+#define AP_CTIME_OPTION_COMPACT 0x2
+
+
+/**
+ * convert a recent time to its human readable components in local timezone
+ * @param tm the exploded time
+ * @param t the time to explode: MUST be within the last
+ * AP_TIME_RECENT_THRESHOLD seconds
+ * @note This is a faster alternative to apr_time_exp_lt that uses
+ * a cache of pre-exploded time structures. It is useful for things
+ * that need to explode the current time multiple times per second,
+ * like loggers.
+ * @return APR_SUCCESS iff successful
+ */
+AP_DECLARE(apr_status_t) ap_explode_recent_localtime(apr_time_exp_t *tm,
+ apr_time_t t);
+
+/**
+ * convert a recent time to its human readable components in GMT timezone
+ * @param tm the exploded time
+ * @param t the time to explode: MUST be within the last
+ * AP_TIME_RECENT_THRESHOLD seconds
+ * @note This is a faster alternative to apr_time_exp_gmt that uses
+ * a cache of pre-exploded time structures. It is useful for things
+ * that need to explode the current time multiple times per second,
+ * like loggers.
+ * @return APR_SUCCESS iff successful
+ */
+AP_DECLARE(apr_status_t) ap_explode_recent_gmt(apr_time_exp_t *tm,
+ apr_time_t t);
+
+
+/**
+ * format a recent timestamp in the ctime() format.
+ * @param date_str String to write to.
+ * @param t the time to convert
+ * @note Consider using ap_recent_ctime_ex instead.
+ * @return APR_SUCCESS iff successful
+ */
+AP_DECLARE(apr_status_t) ap_recent_ctime(char *date_str, apr_time_t t);
+
+
+/**
+ * format a recent timestamp in an extended ctime() format.
+ * @param date_str String to write to.
+ * @param t the time to convert
+ * @param option Additional formatting options (AP_CTIME_OPTION_*).
+ * @param len Pointer to an int containing the length of the provided buffer.
+ * On successful return it contains the number of bytes written to the
+ * buffer.
+ * @return APR_SUCCESS iff successful, APR_ENOMEM if buffer was to short.
+ */
+AP_DECLARE(apr_status_t) ap_recent_ctime_ex(char *date_str, apr_time_t t,
+ int option, int *len);
+
+
+/**
+ * format a recent timestamp in the RFC822 format
+ * @param date_str String to write to (must have length >= APR_RFC822_DATE_LEN)
+ * @param t the time to convert
+ */
+AP_DECLARE(apr_status_t) ap_recent_rfc822_date(char *date_str, apr_time_t t);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !APACHE_UTIL_TIME_H */
+/** @} */
diff --git a/include/util_varbuf.h b/include/util_varbuf.h
new file mode 100644
index 0000000..8e45578
--- /dev/null
+++ b/include/util_varbuf.h
@@ -0,0 +1,197 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file util_varbuf.h
+ * @brief Apache resizable variable length buffer library
+ *
+ * @defgroup APACHE_CORE_VARBUF Variable length buffer library
+ * @ingroup APACHE_CORE
+ *
+ * This set of functions provides resizable buffers. While the primary
+ * usage is with NUL-terminated strings, most functions also work with
+ * arbitrary binary data.
+ *
+ * @{
+ */
+
+#ifndef AP_VARBUF_H
+#define AP_VARBUF_H
+
+#include "apr.h"
+#include "apr_allocator.h"
+
+#include "httpd.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define AP_VARBUF_UNKNOWN APR_SIZE_MAX
+struct ap_varbuf_info;
+
+/** A resizable buffer. */
+struct ap_varbuf {
+ /** The actual buffer; will point to a const '\\0' if avail == 0 and
+ * to memory of the same lifetime as the pool otherwise. */
+ char *buf;
+
+ /** Allocated size of the buffer (minus one for the final \\0);
+ * must only be changed using ap_varbuf_grow(). */
+ apr_size_t avail;
+
+ /** Length of string in buffer, or AP_VARBUF_UNKNOWN. This determines how
+ * much memory is copied by ap_varbuf_grow() and where
+ * ap_varbuf_strmemcat() will append to the buffer. */
+ apr_size_t strlen;
+
+ /** The pool for memory allocations and for registering the cleanup;
+ * the buffer memory will be released when this pool is cleared. */
+ apr_pool_t *pool;
+
+ /** Opaque info for memory allocation. */
+ struct ap_varbuf_info *info;
+};
+
+/**
+ * Initialize a resizable buffer. It is safe to re-initialize a previously
+ * used ap_varbuf. The old buffer will be released when the corresponding
+ * pool is cleared. The buffer remains usable until the pool is cleared,
+ * even if the ap_varbuf was located on the stack and has gone out of scope.
+ * @param pool The pool to allocate small buffers from and to register
+ * the cleanup with
+ * @param vb Pointer to the ap_varbuf struct
+ * @param init_size The initial size of the buffer (see ap_varbuf_grow() for
+ * details)
+ */
+AP_DECLARE(void) ap_varbuf_init(apr_pool_t *pool, struct ap_varbuf *vb,
+ apr_size_t init_size);
+
+/**
+ * Grow a resizable buffer. If the vb->buf cannot be grown in place, it will
+ * be reallocated and the first vb->strlen + 1 bytes of memory will be copied
+ * to the new location. If vb->strlen == AP_VARBUF_UNKNOWN, the whole buffer
+ * is copied.
+ * @param vb Pointer to the ap_varbuf struct
+ * @param new_size The minimum new size of the buffer
+ * @note ap_varbuf_grow() will usually at least double vb->buf's size with
+ * every invocation in order to reduce reallocations.
+ * @note ap_varbuf_grow() will use pool memory for small and allocator
+ * mem nodes for larger allocations.
+ * @note ap_varbuf_grow() will call vb->pool's abort function if out of memory.
+ */
+AP_DECLARE(void) ap_varbuf_grow(struct ap_varbuf *vb, apr_size_t new_size);
+
+/**
+ * Release memory from a ap_varbuf immediately, if possible.
+ * This allows to free large buffers before the corresponding pool is
+ * cleared. Only larger allocations using mem nodes will be freed.
+ * @param vb Pointer to the ap_varbuf struct
+ * @note After ap_varbuf_free(), vb must not be used unless ap_varbuf_init()
+ * is called again.
+ */
+AP_DECLARE(void) ap_varbuf_free(struct ap_varbuf *vb);
+
+/**
+ * Concatenate a string to an ap_varbuf. vb->strlen determines where
+ * the string is appended in the buffer. If vb->strlen == AP_VARBUF_UNKNOWN,
+ * the string will be appended at the first NUL byte in the buffer.
+ * If len == 0, ap_varbuf_strmemcat() does nothing.
+ * @param vb Pointer to the ap_varbuf struct
+ * @param str The string to append; must be at least len bytes long
+ * @param len The number of characters of *str to concatenate to the buf
+ * @note vb->strlen will be set to the length of the new string
+ * @note if len != 0, vb->buf will always be NUL-terminated
+ */
+AP_DECLARE(void) ap_varbuf_strmemcat(struct ap_varbuf *vb, const char *str,
+ int len);
+
+/**
+ * Duplicate an ap_varbuf's content into pool memory.
+ * @param p The pool to allocate from
+ * @param vb The ap_varbuf to copy from
+ * @param prepend An optional buffer to prepend (may be NULL)
+ * @param prepend_len Length of prepend
+ * @param append An optional buffer to append (may be NULL)
+ * @param append_len Length of append
+ * @param new_len Where to store the length of the resulting string
+ * (may be NULL)
+ * @return The new string
+ * @note ap_varbuf_pdup() uses vb->strlen to determine how much memory to
+ * copy. It works even if 0-bytes are embedded in vb->buf, prepend, or
+ * append.
+ * @note If vb->strlen equals AP_VARBUF_UNKNOWN, it will be set to
+ * strlen(vb->buf).
+ */
+AP_DECLARE(char *) ap_varbuf_pdup(apr_pool_t *p, struct ap_varbuf *vb,
+ const char *prepend, apr_size_t prepend_len,
+ const char *append, apr_size_t append_len,
+ apr_size_t *new_len);
+
+
+/**
+ * Concatenate a string to an ap_varbuf.
+ * @param vb Pointer to the ap_varbuf struct
+ * @param str The string to append
+ * @note vb->strlen will be set to the length of the new string
+ */
+#define ap_varbuf_strcat(vb, str) ap_varbuf_strmemcat(vb, str, strlen(str))
+
+/**
+ * Perform string substitutions based on regexp match, using an ap_varbuf.
+ * This function behaves like ap_pregsub(), but appends to an ap_varbuf
+ * instead of allocating the result from a pool.
+ * @param vb The ap_varbuf to which the string will be appended
+ * @param input An arbitrary string containing $1 through $9. These are
+ * replaced with the corresponding matched sub-expressions
+ * @param source The string that was originally matched to the regex
+ * @param nmatch The nmatch returned from ap_pregex
+ * @param pmatch The pmatch array returned from ap_pregex
+ * @param maxlen The maximum string length to append to vb, 0 for unlimited
+ * @return APR_SUCCESS if successful
+ * @note Just like ap_pregsub(), this function does not copy the part of
+ * *source before the matching part (i.e. the first pmatch[0].rm_so
+ * characters).
+ * @note If vb->strlen equals AP_VARBUF_UNKNOWN, it will be set to
+ * strlen(vb->buf) first.
+ */
+AP_DECLARE(apr_status_t) ap_varbuf_regsub(struct ap_varbuf *vb,
+ const char *input,
+ const char *source,
+ apr_size_t nmatch,
+ ap_regmatch_t pmatch[],
+ apr_size_t maxlen);
+
+/**
+ * Read a line from an ap_configfile_t and append it to an ap_varbuf.
+ * @param vb Pointer to the ap_varbuf struct
+ * @param cfp Pointer to the ap_configfile_t
+ * @param max_len Maximum line length, including leading/trailing whitespace
+ * @return See ap_cfg_getline()
+ * @note vb->strlen will be set to the length of the line
+ * @note If vb->strlen equals AP_VARBUF_UNKNOWN, it will be set to
+ * strlen(vb->buf) first.
+ */
+AP_DECLARE(apr_status_t) ap_varbuf_cfg_getline(struct ap_varbuf *vb,
+ ap_configfile_t *cfp,
+ apr_size_t max_len);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !AP_VARBUF_H */
+/** @} */
diff --git a/include/util_xml.h b/include/util_xml.h
new file mode 100644
index 0000000..9faaed1
--- /dev/null
+++ b/include/util_xml.h
@@ -0,0 +1,51 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file util_xml.h
+ * @brief Apache XML library
+ *
+ * @defgroup APACHE_CORE_XML XML Library
+ * @ingroup APACHE_CORE
+ * @{
+ */
+
+#ifndef UTIL_XML_H
+#define UTIL_XML_H
+
+#include "apr_xml.h"
+
+#include "httpd.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Get XML post data and parse it.
+ * @param r The current request
+ * @param pdoc The XML post data
+ * @return HTTP status code
+ */
+AP_DECLARE(int) ap_xml_parse_input(request_rec *r, apr_xml_doc **pdoc);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* UTIL_XML_H */
+/** @} */