diff options
Diffstat (limited to 'include')
46 files changed, 16052 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..8db09b2 --- /dev/null +++ b/include/ap_config_auto.h.in @@ -0,0 +1,407 @@ +/* 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 <minix/config.h> header file. */ +#undef HAVE_MINIX_CONFIG_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_option_set_no_closed_streams' + function. */ +#undef HAVE_NGHTTP2_OPTION_SET_NO_CLOSED_STREAMS + +/* Define to 1 if you have the + `nghttp2_option_set_no_rfc9113_leading_and_trailing_ws_validation' + function. */ +#undef HAVE_NGHTTP2_OPTION_SET_NO_RFC9113_LEADING_AND_TRAILING_WS_VALIDATION + +/* 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 `OPENSSL_init_ssl' function. */ +#undef HAVE_OPENSSL_INIT_SSL + +/* Detected PCRE2 */ +#undef HAVE_PCRE2 + +/* 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 if rustls is available */ +#undef HAVE_RUSTLS + +/* 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 <stdio.h> header file. */ +#undef HAVE_STDIO_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 if systemd is supported */ +#undef HAVE_SYSTEMD + +/* Define to 1 if you have the <systemd/sd-daemon.h> header file. */ +#undef HAVE_SYSTEMD_SD_DAEMON_H + +/* 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 + +/* Define to 1 if you have the <wchar.h> header file. */ +#undef HAVE_WCHAR_H + +/* 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 all of the C90 standard headers exist (not just the ones + required in a freestanding environment). This macro is provided for + backward compatibility; new code need not use it. */ +#undef STDC_HEADERS + +/* Path to suexec binary */ +#undef SUEXEC_BIN + +/* Enable extensions on AIX 3, Interix. */ +#ifndef _ALL_SOURCE +# undef _ALL_SOURCE +#endif +/* Enable general extensions on macOS. */ +#ifndef _DARWIN_C_SOURCE +# undef _DARWIN_C_SOURCE +#endif +/* Enable general extensions on Solaris. */ +#ifndef __EXTENSIONS__ +# undef __EXTENSIONS__ +#endif +/* Enable GNU extensions on systems that have them. */ +#ifndef _GNU_SOURCE +# undef _GNU_SOURCE +#endif +/* Enable X/Open compliant socket functions that do not require linking + with -lxnet on HP-UX 11.11. */ +#ifndef _HPUX_ALT_XOPEN_SOCKET_API +# undef _HPUX_ALT_XOPEN_SOCKET_API +#endif +/* Identify the host operating system as Minix. + This macro does not affect the system headers' behavior. + A future release of Autoconf may stop defining this macro. */ +#ifndef _MINIX +# undef _MINIX +#endif +/* Enable general extensions on NetBSD. + Enable NetBSD compatibility extensions on Minix. */ +#ifndef _NETBSD_SOURCE +# undef _NETBSD_SOURCE +#endif +/* Enable OpenBSD compatibility extensions on NetBSD. + Oddly enough, this does nothing on OpenBSD. */ +#ifndef _OPENBSD_SOURCE +# undef _OPENBSD_SOURCE +#endif +/* Define to 1 if needed for POSIX-compatible behavior. */ +#ifndef _POSIX_SOURCE +# undef _POSIX_SOURCE +#endif +/* Define to 2 if needed for POSIX-compatible behavior. */ +#ifndef _POSIX_1_SOURCE +# undef _POSIX_1_SOURCE +#endif +/* Enable POSIX-compatible threading on Solaris. */ +#ifndef _POSIX_PTHREAD_SEMANTICS +# undef _POSIX_PTHREAD_SEMANTICS +#endif +/* Enable extensions specified by ISO/IEC TS 18661-5:2014. */ +#ifndef __STDC_WANT_IEC_60559_ATTRIBS_EXT__ +# undef __STDC_WANT_IEC_60559_ATTRIBS_EXT__ +#endif +/* Enable extensions specified by ISO/IEC TS 18661-1:2014. */ +#ifndef __STDC_WANT_IEC_60559_BFP_EXT__ +# undef __STDC_WANT_IEC_60559_BFP_EXT__ +#endif +/* Enable extensions specified by ISO/IEC TS 18661-2:2015. */ +#ifndef __STDC_WANT_IEC_60559_DFP_EXT__ +# undef __STDC_WANT_IEC_60559_DFP_EXT__ +#endif +/* Enable extensions specified by ISO/IEC TS 18661-4:2015. */ +#ifndef __STDC_WANT_IEC_60559_FUNCS_EXT__ +# undef __STDC_WANT_IEC_60559_FUNCS_EXT__ +#endif +/* Enable extensions specified by ISO/IEC TS 18661-3:2015. */ +#ifndef __STDC_WANT_IEC_60559_TYPES_EXT__ +# undef __STDC_WANT_IEC_60559_TYPES_EXT__ +#endif +/* Enable extensions specified by ISO/IEC TR 24731-2:2010. */ +#ifndef __STDC_WANT_LIB_EXT2__ +# undef __STDC_WANT_LIB_EXT2__ +#endif +/* Enable extensions specified by ISO/IEC 24747:2009. */ +#ifndef __STDC_WANT_MATH_SPEC_FUNCS__ +# undef __STDC_WANT_MATH_SPEC_FUNCS__ +#endif +/* Enable extensions on HP NonStop. */ +#ifndef _TANDEM_SOURCE +# undef _TANDEM_SOURCE +#endif +/* Enable X/Open extensions. Define to 500 only if necessary + to make mbstate_t available. */ +#ifndef _XOPEN_SOURCE +# undef _XOPEN_SOURCE +#endif + + +/* 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..8e57fcd --- /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 significant 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 determines 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..ace7c43 --- /dev/null +++ b/include/ap_mmn.h @@ -0,0 +1,637 @@ +/* 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 + * 20120211.84 (2.4.35-dev) Add ap_no2slash_ex() and merge_slashes to + * core_server_conf. + * 20120211.85 (2.4.40-dev) add ap_set_conn_count(). + * 20120211.86 (2.4.40-dev) Add forward_100_continue{,_set} to proxy_dir_conf + * 20120211.87 (2.4.40-dev) Add dav_popen_propdb + * 20120211.88 (2.4.40-dev) Add ap_dir_nofnmatch() and ap_dir_fnmatch(). + * 20120211.89 (2.4.42-dev) Add add dns_pool to proxy_conn_pool and define + * AP_VOLATILIZE_T. + * 20120211.90 (2.4.42-dev) AP_REG_DEFAULT macro in ap_regex.h + * 20120211.91 (2.4.42-dev) Add ap_is_chunked() in httpd.h + * 20120211.92 (2.4.42-dev) AP_REG_NO_DEFAULT macro in ap_regex.h + * 20120211.93 (2.4.44-dev) Add ap_parse_strict_length() + * 20120211.94 (2.4.47-dev) Add ap_proxy_define_match_worker() + * 20120211.95 (2.4.47-dev) Add proxy check_trans hook + * 20120211.96 (2.4.47-dev) Add ap_get_status_line_ex() + * 20120211.97 (2.4.47-dev) Add read_buf_size member to core_dir_config, + * flush_max_threshold and flush_max_pipelined to + * core_server_config, and ap_get_read_buf_size(). + * 20120211.98 (2.4.47-dev) Add ap_proxy_should_override to mod_proxy.h + * 20120211.99 (2.4.47-dev) Add proxy_tunnel_rec, ap_proxy_tunnel_create() + * and ap_proxy_tunnel_run() to proxy_util. + * 20120211.99 (2.4.47-dev) Add ap_proxy_worker_can_upgrade() + * 20120211.100 (2.4.47-dev) Add ap_proxy_prefetch_input(), + * ap_proxy_spool_input() and + * ap_proxy_read_input(). + * 20120211.101 (2.4.47-dev) ETAG_DIGEST in http_core.h. struct etag_rec, + * ap_make_etag_ex() and ap_set_etag_fd() in + * http_protocol.h. ap_request_bnotes_t, + * AP_REQUEST_STRONG_ETAG, AP_REQUEST_GET_BNOTE, + * AP_REQUEST_SET_BNOTE and AP_REQUEST_IS_STRONG_ETAG + * in httpd.h. + * 20120211.102 (2.4.47-dev) Add ap_ssl_conn_is_ssl()/ap_ssl_var_lookup() and hooks + * 20120211.103 (2.4.47-dev) Add ap_ssl_add_cert_files, ap_ssl_add_fallback_cert_files + * and ap_ssl_answer_challenge and hooks. + * 20120211.104 (2.4.47-dev) Move ap_ssl_* into new http_ssl.h header file + * 20120211.105 (2.4.47-dev) Add ap_ssl_ocsp* hooks and functions to http_ssl.h. + * 20120211.106 (2.4.49-dev) Add ap_create_request(). + * 20120211.107 (2.4.49-dev) Add ap_parse_request_line() and + * ap_check_request_header() + * 20120211.108 (2.4.49-dev) Add ajp_handle_cping_cpong + * 20120211.109 (2.4.49-dev) Add ap_normalize_path(), + * pre_translate_name hook and + * Add map_encoded_one and map_encoded_all bits to + * proxy_server_conf. + * 20120211.110 (2.4.49-dev) Add hook child_stopping to get informed that a child + * is being shut down. + * 20120211.111 (2.4.49-dev) Add dav_get_provider(), dav_open_lockdb(), + * dav_close_lockdb() and dav_get_resource() to + * mod_dav.h. + * 20120211.112 (2.4.49-dev) Add deliver_report and gather_reports hooks. + * 20120211.113 (2.4.49-dev) Add method_precondition hook. + * 20120211.114 (2.4.49-dev) Add optional balancer_manage function. + * 20120211.115 (2.4.49-dev) Add ap_proxy_get_worker_ex() and + * ap_proxy_define_worker_ex() to mod_proxy.h + * 20120211.116 (2.4.49-dev) add conn_rec->outgoing and ap_ssl_bind_outgoing() + * 20120211.117 (2.4.50-dev) Add ap_pre_connection + * 20120211.118 (2.4.51-dev) Add ap_unescape_url_ex() and deprecate + * AP_NORMALIZE_DROP_PARAMETERS + * 20120211.119 (2.4.51-dev) Add dav_validate_root_ns(), dav_find_child_ns(), + * dav_find_next_ns(), dav_find_attr_ns() and + * dav_find_attr(). + * 20120211.120 (2.4.51-dev) Add dav_liveprop_elem structure and + * dav_get_liveprop_element(). + * 20120211.121 (2.4.51-dev) Add ap_post_read_request() + * 20120211.122 (2.4.51-dev) Add ap_thread_create(), ap_thread_main_create() + * and ap_thread_current() + * 20120211.123 (2.4.51-dev) Added ap_pcre_version_string(), AP_REG_PCRE_COMPILED + * and AP_REG_PCRE_LOADED to ap_regex.h. + * 20120211.124 (2.4.51-dev) Add name_ex to struct proxy_worker_shared + * 20120211.125 (2.4.55-dev) Export mod_http2.h as public header + * 20120211.126 (2.4.55-dev) Add additional hcmethod_t enums and PROXY_WORKER_IS_ERROR + * 20120211.127 (2.4.56-dev) Add ap_proxy_canonenc_ex + */ + +#define MODULE_MAGIC_COOKIE 0x41503234UL /* "AP24" */ + +#ifndef MODULE_MAGIC_NUMBER_MAJOR +#define MODULE_MAGIC_NUMBER_MAJOR 20120211 +#endif +#define MODULE_MAGIC_NUMBER_MINOR 127 /* 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..e3a58aa --- /dev/null +++ b/include/ap_mpm.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 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. + * @ingroup hooks + */ +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); + +/** @defgroup mpmq MPM query + * @{ + */ + +/** @defgroup thrdfrk Subtypes/Values returned for AP_MPMQ_IS_THREADED and AP_MPMQ_IS_FORKED + * @ingroup mpmq + * @{ + */ +#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 */ +/** @} */ + +/** @defgroup qstate Values returned for AP_MPMQ_MPM_STATE + * @ingroup mpmq + * @{ + */ +#define AP_MPMQ_STARTING 0 +#define AP_MPMQ_RUNNING 1 +#define AP_MPMQ_STOPPING 2 +/** @} */ + +/** @defgroup qcodes Query codes for ap_mpm_query() + * @ingroup mpmq + * @{ + */ +/** Max # of daemons used so far */ +#define AP_MPMQ_MAX_DAEMON_USED 1 +/** MPM can do threading */ +#define AP_MPMQ_IS_THREADED 2 +/** MPM can do forking */ +#define AP_MPMQ_IS_FORKED 3 +/** The compiled max # daemons */ +#define AP_MPMQ_HARD_LIMIT_DAEMONS 4 +/** The compiled max # threads */ +#define AP_MPMQ_HARD_LIMIT_THREADS 5 +/** \# of threads/child by config */ +#define AP_MPMQ_MAX_THREADS 6 +/** Min # of spare daemons */ +#define AP_MPMQ_MIN_SPARE_DAEMONS 7 +/** Min # of spare threads */ +#define AP_MPMQ_MIN_SPARE_THREADS 8 +/** Max # of spare daemons */ +#define AP_MPMQ_MAX_SPARE_DAEMONS 9 +/** Max # of spare threads */ +#define AP_MPMQ_MAX_SPARE_THREADS 10 +/** Max # of requests per daemon */ +#define AP_MPMQ_MAX_REQUESTS_DAEMON 11 +/** Max # of daemons by config */ +#define AP_MPMQ_MAX_DAEMONS 12 +/** starting, running, stopping */ +#define AP_MPMQ_MPM_STATE 13 +/** MPM can process async connections */ +#define AP_MPMQ_IS_ASYNC 14 +/** MPM generation */ +#define AP_MPMQ_GENERATION 15 +/** MPM can drive serf internally */ +#define AP_MPMQ_HAS_SERF 16 +/** @} */ + +/** + * Query a property of the current MPM. + * @param query_code One of AP_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. + * @ingroup hooks + */ +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. + * @ingroup hooks + */ +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; + +/** + * Run the fatal_exception hook for each module; this hook is run + * from some MPMs in the event of a child process crash, if the + * server was built with --enable-exception-hook and the + * EnableExceptionHook directive is On. + * @param ei information about the exception + * @ingroup hooks + */ +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..50d5aba --- /dev/null +++ b/include/ap_regex.h @@ -0,0 +1,296 @@ +/* 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_NO_DEFAULT 0x400 /**< Don't implicitely add AP_REG_DEFAULT options */ + +#define AP_REG_MATCH "MATCH_" /**< suggested prefix for ap_regname */ + +#define AP_REG_DEFAULT (AP_REG_DOTALL|AP_REG_DOLLAR_ENDONLY) + +/* Arguments for ap_pcre_version_string */ +enum { + AP_REG_PCRE_COMPILED = 0, /** PCRE version used during program compilation */ + AP_REG_PCRE_LOADED /** PCRE version loaded at runtime */ +}; + +/* 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 */ + +/** + * Return PCRE version string. + * @param which Either AP_REG_PCRE_COMPILED (PCRE version used + * during program compilation) or AP_REG_PCRE_LOADED + * (PCRE version used at runtime) + * @return The PCRE version string + */ +AP_DECLARE(const char *) ap_pcre_version_string(int which); + +/** + * 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 prefix An optional prefix to add to the returned names. AP_REG_MATCH + * is the recommended prefix. + * @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..a5f511a --- /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 2021 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 57 +#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..8359eb1 --- /dev/null +++ b/include/http_config.h @@ -0,0 +1,1451 @@ +/* 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. </Directory> */ + 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 <Directory> or <Location> + 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 <Directory> or <Location> + 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 <Directory> or <Location> */ +#define RSRC_CONF 128 /**< *.conf outside <Directory> or <Location> */ +#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 <Proxy> 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 <Limit>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 <Files>, + * <Location> 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 <Limit> container, or by *not* being listed in a <LimitExcept> + * 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 from the 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 <foo> and the matching </foo>. 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 <foo> and the matching </foo> 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 error, 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); + +/** + * Convenience function to create a ap_dir_match_t structure from a cmd_parms. + * + * @param cmd The command. + * @param flags Flags to indicate whether optional or recursive. + * @param cb Callback for each file found that matches the wildcard. Return NULL on + * success, an error string on error. + * @param ctx Context for the callback. + * @return Structure ap_dir_match_t with fields populated, allocated from the + * cmd->temp_pool. + */ +AP_DECLARE(ap_dir_match_t *)ap_dir_cfgmatch(cmd_parms *cmd, int flags, + const char *(*cb)(ap_dir_match_t *w, const char *fname), void *ctx) + __attribute__((nonnull(1,3))); + +/** + * @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 <VirtualHost> */ +#define NOT_IN_LIMIT 0x02 /**< Forbidden in <Limit> */ +#define NOT_IN_DIRECTORY 0x04 /**< Forbidden in <Directory> */ +#define NOT_IN_LOCATION 0x08 /**< Forbidden in <Location> */ +#define NOT_IN_FILES 0x10 /**< Forbidden in <Files> or <If>*/ +#define NOT_IN_HTACCESS 0x20 /**< Forbidden in .htaccess files */ +#define NOT_IN_PROXY 0x40 /**< Forbidden in <Proxy> */ +/** Forbidden in <Directory>/<Location>/<Files><If>*/ +#define NOT_IN_DIR_LOC_FILE (NOT_IN_DIRECTORY|NOT_IN_LOCATION|NOT_IN_FILES) +/** Forbidden in <Directory>/<Location>/<Files><If><Proxy>*/ +#define NOT_IN_DIR_CONTEXT (NOT_IN_LIMIT|NOT_IN_DIR_LOC_FILE|NOT_IN_PROXY) +/** Forbidden in <VirtualHost>/<Limit>/<Directory>/<Location>/<Files>/<If><Proxy>*/ +#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 from + * @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... (<Directory> 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 + * @ingroup hooks + */ +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 + * @ingroup hooks + */ +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 + * @ingroup hooks + */ +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(). + * @ingroup hooks + */ +AP_DECLARE_HOOK(void,test_config,(apr_pool_t *pconf, server_rec *s)) + +/** + * Run the post_config function for each module + * + * The function might be called multiple times. @a pconf, @a plog, and + * @a ptemp may be cleared and/or destroyed between calls. + * + * The function will be called zero or one times with the server's state being + * #AP_SQ_MS_CREATE_PRE_CONFIG, and will be called one or more times with + * the server's state being #AP_SQ_MS_CREATE_CONFIG. + * + * @see ap_state_query(), #AP_SQ_MAIN_STATE + * + * @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 + * @ingroup hooks + */ +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 + * @ingroup hooks + */ +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 + * @ingroup hooks + */ +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 + * @ingroup hooks + */ +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() + * @ingroup hooks + */ +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. + * @ingroup hooks + */ +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. + * @ingroup hooks + */ +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..71f02bd --- /dev/null +++ b/include/http_connection.h @@ -0,0 +1,183 @@ +/* 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)) + +/** + * This is a wrapper around ap_run_pre_connection. In case that + * ap_run_pre_connection returns an error it marks the connection as + * aborted and ensures that the basic connection setup normally done + * by the core module is done in case it was not done so far. + * @param c The connection on which the request has been received. + * Same as for the pre_connection hook. + * @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. + * Same as for the pre_connection hook. + * @return The result of ap_run_pre_connection + */ +AP_DECLARE(int) ap_pre_connection(conn_rec *c, void *csd); + +/** 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..15c9bac --- /dev/null +++ b/include/http_core.h @@ -0,0 +1,1068 @@ +/* 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_host + * @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); + +/** + * Get the size of read buffers + * @param r The current request + * @return The read buffers size + */ +AP_DECLARE(apr_size_t) ap_get_read_buf_size(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_DIGEST (1 << 4) +#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; + + apr_size_t read_buf_size; +} 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; + unsigned int merge_slashes; + + apr_size_t flush_max_threshold; + apr_int32_t flush_max_pipelined; + unsigned int strict_host_check; +} 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; + +struct core_filter_ctx { + apr_bucket_brigade *b; + apr_bucket_brigade *tmpbb; +}; + +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..94c481e --- /dev/null +++ b/include/http_protocol.h @@ -0,0 +1,1119 @@ +/* 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 an empty request and set reasonable defaults. + * @param c The current connection + * @return The new request_rec + */ +AP_DECLARE(request_rec *) ap_create_request(conn_rec *c); + +/** + * 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); + +/** + * Parse and validate the request line. + * @param r The current request + * @return 1 on success, 0 on failure + */ +AP_DECLARE(int) ap_parse_request_line(request_rec *r); + +/** + * Validate the request header and select vhost. + * @param r The current request + * @return 1 on success, 0 on failure + */ +AP_DECLARE(int) ap_check_request_header(request_rec *r); + +/** + * 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); + +/** + * Run post_read_request hook and validate. + * @param r The current request + * @return OK or HTTP_... + */ +AP_DECLARE(int) ap_post_read_request(request_rec *r); + +/* 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); + +/** A structure with the ingredients for a file based etag */ +typedef struct etag_rec etag_rec; + +/** + * @brief A structure with the ingredients for a file based etag + */ +struct etag_rec { + /** Optional vary list validator */ + const char *vlist_validator; + /** Time when the request started */ + apr_time_t request_time; + /** finfo.protection (st_mode) set to zero if no such file */ + apr_finfo_t *finfo; + /** File pathname used when generating a digest */ + const char *pathname; + /** File descriptor used when generating a digest */ + apr_file_t *fd; + /** Force a non-digest etag to be weak */ + int force_weak; +}; + +/** + * 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); + +/** + * Construct an entity tag from information provided in the etag_rec + * structure. + * @param r The current request + * @param er The etag record, containing ingredients for the etag. + */ +AP_DECLARE(char *) ap_make_etag_ex(request_rec *r, etag_rec *er); + +/** + * Set the E-tag outgoing header + * @param r The current request + */ +AP_DECLARE(void) ap_set_etag(request_rec *r); + +/** + * Set the E-tag outgoing header, with the option of forcing a strong ETag. + * @param r The current request + * @param fd The file descriptor + */ +AP_DECLARE(void) ap_set_etag_fd(request_rec *r, apr_file_t *fd); + +/** + * 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) +{ + apr_size_t len; + + len = strlen(str); + + for (;;) { + if (len <= INT_MAX) { + return ap_rwrite(str, (int)len, r); + } + else { + int rc; + + rc = ap_rwrite(str, INT_MAX, r); + if (rc < 0) { + return rc; + } + else { + str += INT_MAX; + len -= INT_MAX; + } + } + } +} + +/** + * 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); + +/** + * Return the Status-Line for a given status code (excluding the + * HTTP-Version field). If an invalid status code is passed, + * "500 Internal Server Error" will be returned, whereas an unknown + * status will be returned like "xxx Status xxx". + * @param p The pool to allocate from when status is unknown + * @param status The HTTP status code + * @return The Status-Line + */ +AP_DECLARE(const char *) ap_get_status_line_ex(apr_pool_t *p, 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 protocol The protocol identifier we try to switch to + * @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..7e8bfad --- /dev/null +++ b/include/http_request.h @@ -0,0 +1,642 @@ +/* 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 dying + * @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, + * optionally 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, before URL decoding happens. + * @param r The current request + * @return DECLINED to let other modules handle the pre-translation, + * OK if it was handled and no other module should process it, + * DONE if no further transformation should happen on the URI, + * HTTP_... in case of error. + * @ingroup hooks + */ +AP_DECLARE_HOOK(int,pre_translate_name,(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 access), 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 access), 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_ssl.h b/include/http_ssl.h new file mode 100644 index 0000000..2e052c5 --- /dev/null +++ b/include/http_ssl.h @@ -0,0 +1,317 @@ +/* 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_ssl.h + * @brief SSL protocol handling + * + * @defgroup APACHE_CORE_PROTO SSL Protocol Handling + * @ingroup APACHE_CORE + * @{ + */ + +#ifndef APACHE_HTTP_SSL_H +#define APACHE_HTTP_SSL_H + +#include "httpd.h" +#include "apr_portable.h" +#include "apr_mmap.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct ap_conf_vector_t; + +/** + * This hook allows modules that manage SSL connection to register their + * inquiry function for checking if a connection is using SSL from them. + * @param c The current connection + * @return OK if the connection is using SSL, DECLINED if not. + * @ingroup hooks + */ +AP_DECLARE_HOOK(int,ssl_conn_is_ssl,(conn_rec *c)) + +/** + * Return != 0 iff the connection is encrypted with SSL. + * @param c the connection + */ +AP_DECLARE(int) ap_ssl_conn_is_ssl(conn_rec *c); + +/** + * This hook declares a connection to be outgoing and the configuration that applies to it. + * This hook can be called several times in the lifetime of an outgoing connection, e.g. + * when it is re-used in different request contexts. It will at least be called after the + * connection was created and before the pre-connection hooks is invoked. + * All outgoing-connection hooks are run until one returns something other than DECLINE. + * if enable_ssl != 0, a hook that sets up SSL for the connection needs to return OK + * to prevent subsequent hooks from doing the same. + * + * @param c The connection on which requests/data are to be sent. + * @param dir_conf The directory configuration in which this connection is being used. + * @param enable_ssl If != 0, the SSL protocol should be enabled for this connection. + * @return DECLINED, OK when ssl was enabled + */ +AP_DECLARE_HOOK(int, ssl_bind_outgoing, + (conn_rec *c, struct ap_conf_vector_t *dir_conf, int enable_ssl)) + +/** + * Assures the connection is marked as outgoing and invokes the ssl_bind_outgoing hook. + * This may be called several times on an outgoing connection with varying dir_conf + * values. require_ssl is not allowed to change on the same connection. + * + * @param c The connection on which requests/data are to be sent. + * @param dir_conf The directory configuration in which this connection is being used. + * @param require_ssl != 0 iff this connection needs to be secured by SSL/TLS protocol. + * @return OK iff ssl was required and is enabled, DECLINED otherwise + */ +AP_DECLARE(int) ap_ssl_bind_outgoing(conn_rec *c, struct ap_conf_vector_t *dir_conf, + int require_ssl); + +/** + * Return != 0 iff handlers/hooks for outgoing connections are registered. + */ +AP_DECLARE(int) ap_ssl_has_outgoing_handlers(void); + +/** + * This hook allows modules to look up SSL related variables for a + * server/connection/request, depending on what they inquire. Some + * variables will only be available for a connection/request, for example. + * @param p The pool to allocate a returned value in, MUST be provided + * @param s The server to inquire a value for, maybe NULL + * @param c The current connection, maybe NULL + * @param r The current request, maybe NULL + * @param name The name of the variable to retrieve, MUST be provided + * @return value or the variable or NULL if not provided/available + * @ingroup hooks + */ +AP_DECLARE_HOOK(const char *,ssl_var_lookup, + (apr_pool_t *p, server_rec *s, conn_rec *c, request_rec *r, const char *name)) + +/** + * Lookup an SSL related variable for the server/connection/request or a global + * value when all those parameters are set to NULL. Pool and name must always be + * provided and the returned value (if not NULL) will be allocated from the pool. + * @param p The pool to allocate a returned value in, MUST be provided + * @param s The server to inquire a value for, maybe NULL + * @param c The current connection, maybe NULL + * @param r The current request, maybe NULL + * @param name The name of the variable to retrieve, MUST be provided + * @return value or the variable or NULL if not provided/available + */ +AP_DECLARE(const char *) ap_ssl_var_lookup(apr_pool_t *p, server_rec *s, + conn_rec *c, request_rec *r, + const char *name); + +/** + * Register to provide certificate/key files for servers. Certificate files are + * expected to contain the certificate chain, beginning with the server's certificate, + * excluding the trust anchor, in PEM format. + * They must be accompanied by a private key file, also in PEM format. + * + * @param s the server certificates are collected for + * @param p the pool to use for allocations + * @param cert_files an array of const char* with the path to the certificate chain + * @param key_files an array of const char* with the path to the private key file + * @return OK if files were added, DECLINED if not, or other for error. + */ + +AP_DECLARE_HOOK(int, ssl_add_cert_files, (server_rec *s, apr_pool_t *p, + apr_array_header_t *cert_files, + apr_array_header_t *key_files)) + +/** + * Collect certificate/key files from all providers registered. This includes + * providers registered at the global 'ssl_add_cert_files', as well as those + * installed in the OPTIONAL 'ssl_add_cert_files' hook as may be provided by + * ssl modules. + * + * @param s the server certificates are collected for + * @param p the pool to use for allocations + * @param cert_files an array of const char* with the path to the certificate chain + * @param key_files an array of const char* with the path to the private key file + */ +AP_DECLARE(apr_status_t) ap_ssl_add_cert_files(server_rec *s, apr_pool_t *p, + apr_array_header_t *cert_files, + apr_array_header_t *key_files); + + +/** + * Register to provide 'fallback' certificates in case no 'real' certificates + * have been configured/added by other providers. Modules using these certificates + * are encouraged to answer requests to this server with a 503 response code. + * + * @param s the server certificates are collected for + * @param p the pool to use for allocations + * @param cert_files an array of const char* with the path to the certificate chain + * @param key_files an array of const char* with the path to the private key file + * @return OK if files were added, DECLINED if not, or other for error. + */ +AP_DECLARE_HOOK(int, ssl_add_fallback_cert_files, (server_rec *s, apr_pool_t *p, + apr_array_header_t *cert_files, + apr_array_header_t *key_files)) + +/** + * Collect 'fallback' certificate/key files from all registered providers, either + * in the global 'ssl_add_fallback_cert_files' hook or the optional one of similar + * name as provided by mod_ssl and sorts. + * Certificates obtained this way are commonly self signed, temporary crutches. + * To be used to the time it takes to retrieve a 'read', trusted certificate. + * A module using fallbacks is encouraged to answer all requests with a 503. + * + * @param s the server certificates are collected for + * @param p the pool to use for allocations + * @param cert_files an array of const char* with the path to the certificate chain + * @param key_files an array of const char* with the path to the private key file + */ +AP_DECLARE(apr_status_t) ap_ssl_add_fallback_cert_files(server_rec *s, apr_pool_t *p, + apr_array_header_t *cert_files, + apr_array_header_t *key_files); + + +/** + * On TLS connections that do not relate to a configured virtual host + * allow modules to provide a certificate and key to be used on the connection. + * + * A Certificate PEM added must be accompanied by a private key PEM. The private + * key PEM may be given by a NULL pointer, in which case it is expected to be found in + * the certificate PEM string. + */ +AP_DECLARE_HOOK(int, ssl_answer_challenge, (conn_rec *c, const char *server_name, + const char **pcert_pem, const char **pkey_pem)) + +/** + * Returns != 0 iff the connection is a challenge to the server, for example + * as defined in RFC 8555 for the 'tls-alpn-01' domain verification, and needs + * a specific certificate as answer in the handshake. + * + * ALPN protocol negotiation via the hooks 'protocol_propose' and 'protocol_switch' + * need to have run before this call is made. + * + * Certificate PEMs added must be accompanied by a private key PEM. The private + * key PEM may be given by a NULL pointer, in which case it is expected to be found in + * the certificate PEM string. + * + * A certificate provided this way needs to replace any other certificates selected + * by configuration or 'ssl_add_cert_pems` on this connection. + */ +AP_DECLARE(int) ap_ssl_answer_challenge(conn_rec *c, const char *server_name, + const char **pcert_pem, const char **pkey_pem); + + +/** + * Setup optional functions for ssl related queries so that functions + * registered by old-style SSL module functions are interrogated by the + * the new ap_is_ssl() and friends. Installs own optional functions, so that + * old modules looking for these find one and get the correct results (shadowing). + * + * Needs to run in core's very early POST_CONFIG hook. + * Modules providing such functions register their own optionals during + * register_hooks(). Modules using such functions retrieve them often + * in their own post-config or in the even later retrieval hook. When shadowing + * other modules functions, core's early post-config is a good time. + * @param pool The pool to use for allocations + */ +AP_DECLARE(void) ap_setup_ssl_optional_fns(apr_pool_t *pool); + +/** + * Providers of OCSP status responses register at this hook. Installed hooks returning OK + * are expected to provide later OCSP responses via a 'ap_ssl_ocsp_get_resp_hook'. + * @param s the server being configured + * @params p a memory pool to use + * @param id opaque data uniquely identifying the certificate, provided by caller + * @param pem PEM data of certificate first, followed by PEM of issuer cert + * @return OK iff stapling is being provided + */ +AP_DECLARE_HOOK(int, ssl_ocsp_prime_hook, (server_rec *s, apr_pool_t *p, + const char *id, apr_size_t id_len, + const char *pem)) + +/** + * Registering a certificate for Provisioning of OCSP responses. It is the caller's + * responsibility to provide a global (apache instance) unique id for the certificate + * that is then used later in retrieving the OCSP response. + * A certificate can be primed this way more than once, however the same identifier + * has to be provided each time (byte-wise same, not pointer same). + * The memory pointed to by `id` and `pem` is only valid for the duration of the call. + * + * @param s the server being configured + * @params p a memory pool to use + * @param id opaque data uniquely identifying the certificate, provided by caller + * @param pem PEM data of certificate first, followed by chain certs, at least the issuer + * @return APR_SUCCESS iff OCSP responses will be provided. + * APR_ENOENT when no provided was found or took responsibility. + */ +AP_DECLARE(apr_status_t) ap_ssl_ocsp_prime(server_rec *s, apr_pool_t *p, + const char *id, apr_size_t id_len, + const char *pem); + +/** + * Callback to copy over the OCSP response data. If OCSP response data is not + * available, this will be called with NULL, 0 parameters! + * + * Memory allocation methods and lifetime of data will vary per module and + * SSL library used. The caller requesting OCSP data will need to make a copy + * for his own use. + * Any passed data may only be valid for the duration of the call. + */ +typedef void ap_ssl_ocsp_copy_resp(const unsigned char *der, apr_size_t der_len, void *userdata); + +/** + * Asking for OCSP response DER data for a certificate formerly primed. + * @param s the (SNI selected) server of the connection + * @param c the connection + * @param id identifier for the certifate, as used in ocsp_stapling_prime() + * @param cb callback to invoke when response data is available + * @param userdata caller supplied data passed to callback + * @return OK iff response data has been provided, DECLINED otherwise + */ +AP_DECLARE_HOOK(int, ssl_ocsp_get_resp_hook, + (server_rec *s, conn_rec *c, const char *id, apr_size_t id_len, + ap_ssl_ocsp_copy_resp *cb, void *userdata)) + +/** + * Retrieve the OCSP response data for a previously primed certificate. The id needs + * to be byte-wise identical to the one used on priming. If the call return ARP_SUCCESS, + * the callback has been invoked with the OCSP response DER data. + * Otherwise, a different status code must be returned. Callers in SSL connection + * handshakes are encouraged to continue the handshake without OCSP data for + * server reliability. The decision to accept or reject a handshake with missing + * OCSP stapling data needs to be done by the client. + * For similar reasons, providers of responses might return seemingly expired ones + * if they were unable to refresh a response in time. + * + * The memory pointed to by `id` is only valid for the duration of the call. + * Also, the DER data passed to the callback is only valid for the duration + * of the call. + * + * @param s the (SNI selected) server of the connection + * @param c the connection + * @param id identifier for the certifate, as used in ocsp_stapling_prime() + * @param cb callback to invoke when response data is available + * @param userdata caller supplied data passed to callback + * @return APR_SUCCESS iff data has been provided + */ +AP_DECLARE(apr_status_t) ap_ssl_ocsp_get_resp(server_rec *s, conn_rec *c, + const char *id, apr_size_t id_len, + ap_ssl_ocsp_copy_resp *cb, void *userdata); + +#ifdef __cplusplus +} +#endif + +#endif /* !APACHE_HTTP_SSL_H */ +/** @} */ diff --git a/include/http_vhost.h b/include/http_vhost.h new file mode 100644 index 0000000..d2d9c97 --- /dev/null +++ b/include/http_vhost.h @@ -0,0 +1,132 @@ +/* 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); + +/** + * Updates r->server with the best name-based virtual host match, within + * the chain of matching virtual hosts selected by ap_update_vhost_given_ip. + * @param r The current request + * @param require_match 1 to return an HTTP error if the requested hostname is + * not explicitly matched to a VirtualHost. + * @return return HTTP_OK unless require_match was specified and the requested + * hostname did not match any ServerName, ServerAlias, or VirtualHost + * address-spec. + */ +AP_DECLARE(int) ap_update_vhost_from_headers_ex(request_rec *r, int require_match); + + +/** + * 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..799cf97 --- /dev/null +++ b/include/httpd.h @@ -0,0 +1,2668 @@ +/* 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_version.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 splitting 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 /** RFC 5789: PATCH Method for HTTP */ +#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 bnotes Binary notes recognized by the server + * @ingroup APACHE_CORE_DAEMON + * @{ + * + * @brief Binary notes recognized by the server. + */ + +/** + * The type used for request binary notes. + */ +typedef apr_uint64_t ap_request_bnotes_t; + +/** + * These constants represent bitmasks for notes associated with this + * request. There are space for 64 bits in the apr_uint64_t. + * + */ +#define AP_REQUEST_STRONG_ETAG 1 >> 0 + +/** + * This is a convenience macro to ease with getting specific request + * binary notes. + */ +#define AP_REQUEST_GET_BNOTE(r, mask) \ + ((mask) & ((r)->bnotes)) + +/** + * This is a convenience macro to ease with setting specific request + * binary notes. + */ +#define AP_REQUEST_SET_BNOTE(r, mask, val) \ + (r)->bnotes = (((r)->bnotes & ~(mask)) | (val)) + +/** + * Returns true if the strong etag flag is set for this request. + */ +#define AP_REQUEST_IS_STRONG_ETAG(r) \ + AP_REQUEST_GET_BNOTE((r), AP_REQUEST_STRONG_ETAG) +/** @} */ + + +/** + * @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 +/** carriage return */ +#define CR 13 +/** carriage 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 have 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: header. + * For literal IPv6 addresses, this does NOT include the surrounding [ ] + */ + 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; + /** Request flags associated with this request. Use + * AP_REQUEST_GET_FLAGS() and AP_REQUEST_SET_FLAGS() to access + * the elements of this field. + */ + ap_request_bnotes_t bnotes; +}; + +/** + * @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; + + int outgoing; +}; + +/** + * 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 path to the config file that the server was defined in */ + 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); + +#define AP_UNESCAPE_URL_KEEP_UNRESERVED (1u << 0) +#define AP_UNESCAPE_URL_FORBID_SLASHES (1u << 1) +#define AP_UNESCAPE_URL_KEEP_SLASHES (1u << 2) + +/** + * Unescape a URL, with options + * @param url The url to unescape + * @param flags Bitmask of AP_UNESCAPE_URL_* flags + * @return 0 on success, non-zero otherwise + */ +AP_DECLARE(int) ap_unescape_url_ex(char *url, unsigned int flags); + +/** + * 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, except where significant + * to the filesystem on the current platform. + * @param name The string to convert, assumed to be a filesystem path + */ +AP_DECLARE(void) ap_no2slash(char *name); + +/** + * Convert all double slashes to single slashes, except where significant + * to the filesystem on the current platform. + * @param name The string to convert + * @param is_fs_path if set to 0, the significance of any double-slashes is + * ignored. + */ +AP_DECLARE(void) ap_no2slash_ex(char *name, int is_fs_path); + +#define AP_NORMALIZE_ALLOW_RELATIVE (1u << 0) +#define AP_NORMALIZE_NOT_ABOVE_ROOT (1u << 1) +#define AP_NORMALIZE_DECODE_UNRESERVED (1u << 2) +#define AP_NORMALIZE_MERGE_SLASHES (1u << 3) +#define AP_NORMALIZE_DROP_PARAMETERS (0) /* deprecated */ + +/** + * Remove all ////, /./ and /xx/../ substrings from a path, and more + * depending on passed in flags. + * @param path The path to normalize + * @param flags bitmask of AP_NORMALIZE_* flags + * @return non-zero on success + */ +AP_DECLARE(int) ap_normalize_path(char *path, unsigned int flags); + +/** + * 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 " with \\" . + * @param p The pool to allocate memory from + * @param instring The string to search for " + * @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 length string with decimal characters only, no leading sign nor + * trailing character, like Content-Length or (Content-)Range headers. + * @param len The parsed length (apr_off_t) + * @param str The string to parse + * @return 1 (success), 0 (failure) + */ +AP_DECLARE(int) ap_parse_strict_length(apr_off_t *len, const char *str); + +/** + * 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); + +#if APR_HAS_THREADS + +#if APR_VERSION_AT_LEAST(1,8,0) && !defined(AP_NO_THREAD_LOCAL) + +/** + * APR 1.8+ implement those already. + */ +#if APR_HAS_THREAD_LOCAL +#define AP_HAS_THREAD_LOCAL 1 +#define AP_THREAD_LOCAL APR_THREAD_LOCAL +#else +#define AP_HAS_THREAD_LOCAL 0 +#endif +#define ap_thread_create apr_thread_create +#define ap_thread_current apr_thread_current +#define ap_thread_current_create apr_thread_current_create +#define ap_thread_current_after_fork apr_thread_current_after_fork + +#else /* APR_VERSION_AT_LEAST(1,8,0) && !defined(AP_NO_THREAD_LOCAL) */ + +#ifndef AP_NO_THREAD_LOCAL +/** + * AP_THREAD_LOCAL keyword mapping the compiler's. + */ +#if defined(__cplusplus) && __cplusplus >= 201103L +#define AP_THREAD_LOCAL thread_local +#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112 && \ + (!defined(__GNUC__) || \ + __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9)) +#define AP_THREAD_LOCAL _Thread_local +#elif defined(__GNUC__) /* works for clang too */ +#define AP_THREAD_LOCAL __thread +#elif defined(WIN32) && defined(_MSC_VER) +#define AP_THREAD_LOCAL __declspec(thread) +#endif +#endif /* ndef AP_NO_THREAD_LOCAL */ + +#ifndef AP_THREAD_LOCAL +#define AP_HAS_THREAD_LOCAL 0 +#define ap_thread_create apr_thread_create +#else /* AP_THREAD_LOCAL */ +#define AP_HAS_THREAD_LOCAL 1 +AP_DECLARE(apr_status_t) ap_thread_create(apr_thread_t **thread, + apr_threadattr_t *attr, + apr_thread_start_t func, + void *data, apr_pool_t *pool); +#endif /* AP_THREAD_LOCAL */ + +AP_DECLARE(apr_status_t) ap_thread_current_create(apr_thread_t **current, + apr_threadattr_t *attr, + apr_pool_t *pool); +AP_DECLARE(void) ap_thread_current_after_fork(void); +AP_DECLARE(apr_thread_t *) ap_thread_current(void); + +#endif /* APR_VERSION_AT_LEAST(1,8,0) && !defined(AP_NO_THREAD_LOCAL) */ + +AP_DECLARE(apr_status_t) ap_thread_main_create(apr_thread_t **thread, + apr_pool_t *pool); + +#else /* APR_HAS_THREADS */ + +#define AP_HAS_THREAD_LOCAL 0 + +#endif /* APR_HAS_THREADS */ + +/** + * 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); + +/** + * Default flags for ap_dir_*fnmatch(). + */ +#define AP_DIR_FLAG_NONE 0 + +/** + * If set, wildcards that match no files or directories will be ignored, otherwise + * an error is triggered. + */ +#define AP_DIR_FLAG_OPTIONAL 1 + +/** + * If set, and the wildcard resolves to a directory, recursively find all files + * below that directory, otherwise return the directory. + */ +#define AP_DIR_FLAG_RECURSIVE 2 + +/** + * Structure to provide the state of a directory match. + */ +typedef struct ap_dir_match_t ap_dir_match_t; + +/** + * Concrete structure to provide the state of a directory match. + */ +struct ap_dir_match_t { + /** Pool to use for allocating the result */ + apr_pool_t *p; + /** Temporary pool used for directory traversal */ + apr_pool_t *ptemp; + /** Prefix for log messages */ + const char *prefix; + /** Callback for each file found that matches the wildcard. Return NULL on success, an error string on error. */ + const char *(*cb)(ap_dir_match_t *w, const char *fname); + /** Context for the callback */ + void *ctx; + /** Flags to indicate whether optional or recursive */ + int flags; + /** Recursion depth safety check */ + unsigned int depth; +}; + +/** + * Search for files given a non wildcard filename with non native separators. + * + * If the provided filename points at a file, the callback within ap_dir_match_t is + * triggered for that file, and this function returns the result of the callback. + * + * If the provided filename points at a directory, and recursive within ap_dir_match_t + * is true, the callback will be triggered for every file found recursively beneath + * that directory, otherwise the callback is triggered once for the directory itself. + * This function returns the result of the callback. + * + * If the provided path points to neither a file nor a directory, and optional within + * ap_dir_match_t is true, this function returns NULL. If optional within ap_dir_match_t + * is false, this function will return an error string indicating that the path does not + * exist. + * + * @param w Directory match structure containing callback and context. + * @param fname The name of the file or directory, with non native separators. + * @return NULL on success, or a string describing the error. + */ +AP_DECLARE(const char *)ap_dir_nofnmatch(ap_dir_match_t *w, const char *fname) + __attribute__((nonnull(1,2))); + +/** + * Search for files given a wildcard filename with non native separators. + * + * If the filename contains a wildcard, all files and directories that match the wildcard + * will be returned. + * + * ap_dir_nofnmatch() is called for each directory and file found, and the callback + * within ap_dir_match_t triggered as described above. + * + * Wildcards may appear in both directory and file components in the path, and + * wildcards may appear more than once. + * + * @param w Directory match structure containing callback and context. + * @param path Path prefix for search, with non native separators and no wildcards. + * @param fname The name of the file or directory, with non native separators and + * optional wildcards. + * @return NULL on success, or a string describing the error. + */ +AP_DECLARE(const char *)ap_dir_fnmatch(ap_dir_match_t *w, const char *path, + const char *fname) __attribute__((nonnull(1,3))); + +/** + * Determine if the final Transfer-Encoding is "chunked". + * + * @param p The pool to allocate from + * @param line the header field-value to scan + * @return 1 if the last Transfer-Encoding is "chunked", else 0 + */ +AP_DECLARE(int) ap_is_chunked(apr_pool_t *p, const char *line); + +#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..639b97f --- /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 caching 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..539d640 --- /dev/null +++ b/include/mpm_common.h @@ -0,0 +1,479 @@ +/* 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)) + +/** + * Notification that the child is stopping. If graceful, ongoing + * requests will be served. + * @param pchild The child pool + * @param graceful != 0 iff this is a graceful shutdown. + */ +AP_DECLARE_HOOK(void, child_stopping, + (apr_pool_t *pchild, int graceful)) + +/* 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..0142aa9 --- /dev/null +++ b/include/scoreboard.h @@ -0,0 +1,256 @@ +/* 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 indices. 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; this field is DEPRECATED + * and no longer updated by the MPMs (i.e. always zero). + */ +}; + +/* 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 indices 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(void) ap_set_conn_count(ap_sb_handle_t *sb, request_rec *r, unsigned short conn_count); + +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 <Directory ...> cause a sub-level + * to be created, where the included directives are stored. The closing + * directive (</Directory>) 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..66af75a --- /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 definitions 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..28e0760 --- /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 request */ +} 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 */ +/** @} */ |