从 2.2 开始的 Apache HTTP Server 2.4 中的 API 更改

本文档介绍了 Apache HTTPD API 从 2.2 版到 2.4 版的更改,这些更改可能是模块/应用程序开发人员和核心黑客所感兴趣的。从 2.4 分支的第一个 GA 版本开始,API 的兼容性一直保留到 2.4 分支的生命周期中。 (2.4 版的VERSIONING描述提供了有关 API 兼容性的更多信息。)

API 更改分为两类:全新的 API 和已扩展或更改的现有 API。后者又分为所有更改都是向后兼容的(因此现有模块可以忽略它们),以及可能需要维护人员注意的更改。与从 HTTPD 2.0 到 2.2 的过渡一样,现有的模块和应用程序将需要重新编译,并且可能需要引起注意,但是大多数模块和应用程序都不需要进行任何实质性的更新(尽管某些组件和应用程序可以利用 API 的更改来提供显着的改进)。

就本文档而言,API 是根据公共头文件拆分的。这些 Headers 本身就是参考文档,可用于生成带有make docs的可浏览 HTML 参考。

Changed APIs

ap_expr (NEW!)

引入了一种新的 API,用于解析和评估布尔表达式和代数表达式,包括提供标准语法和自定义变体。

ap_listen(已更改;向后兼容)

引入了一个新的 API,以使 httpd 子进程能够满足不同的目的。

ap_mpm (changed)

ap_mpm_run替换为新的mpm钩子。 ap_graceful_stop_signalled也丢失了,ap_mpm_register_timed_callback是新的。

ap_regex (changed)

除了现有的 regexp 包装器之外,现在还提供了新的更高级别的 API ap_rxplus。这提供了编译 Perl 样式的表达式(如s/regexp/replacement/flags)并针对任意字符串执行它们的功能。还添加了对正则表达式反向引用的支持。

ap_slotmem (NEW!)

为模块分配和 Management 内存插槽(通常用于共享内存)引入 API。

ap_socache (NEW!)

用于 Management 共享对象缓存的 API。

heartbeat (NEW!)

心跳模块的通用结构

ap_parse_htaccess (changed)

ap_parse_htaccess的功能签名已更改。现在必须传递apr_table_t允许覆盖的各个指令(保留覆盖)。

http_config (changed)

  • 介绍每个模块,每个目录的日志级别,包括宏包装程序。

  • 新的AP_DECLARE_MODULE宏用于声明所有模块。

  • 多文件模块中每个模块日志级别所需的新APLOG_USE_MODULE宏。

  • 新的 API 可在模块卸载/加载过程中保留数据

  • 新的check_config钩子

  • 新的ap_process_fnmatch_configs()函数可处理通配符

  • 更改ap_configfile_tap_cfg_getline()ap_cfg_getc()以返回错误代码,并添加ap_pcfg_strerror()以检索错误描述。

  • 现在,ACCESS_CONF 上下文中允许的任何配置指令都必须正确处理通过新的AllowOverrideList指令从.htaccess 文件中调用的配置。 ap_check_cmd_context()接受新的标志 NOT_IN_HTACCESS 来检测这种情况。

http_core (changed)

  • 删除了ap_default_typeap_requires,所有 2.2 身份验证 API

  • 介绍用于 logio 和 authnz 的可选功能

  • 新功能ap_get_server_name_for_url支持 IPv6 Literals。

  • 新功能ap_register_errorlog_handler用于注册错误日志格式字符串处理程序。

  • error_log钩子的参数已更改。声明已移至http_core.h

  • 新功能ap_state_query确定服务器是否处于初始配置预检阶段。与在过程池中创建池用户数据条目的旧方法相比,这既易于使用,又更正确。

  • 新函数ap_get_conn_socket获取连接的套接字 Descriptors。应该使用它代替直接访问核心连接配置。

httpd (changed)

  • 介绍每个目录,每个模块的日志级别

  • 新的日志级别APLOG_TRACEn

  • 介绍请求和连接的错误日志 ID

  • 支持 mod_request keep_body

  • 支持为异步请求缓冲过滤器数据

  • 新的CONN_STATE

  • 功能更改:ap_escape_html更新; ap_unescape_allap_escape_path_segment_buffer

  • EXEC_ON_READ config 读取阶段之后加载其他模块的模块需要在pre_config hook中调用ap_reserve_module_slots()ap_reserve_module_slots_directive()

  • 现在可以独立于连接的 Client 端 IP 地址来跟踪每个请求的 useragent IP 地址,以支持使用负载均衡器进行的部署。

http_log (changed)

  • 介绍每个目录,每个模块的日志级别

  • 新的日志级别APLOG_TRACEn

  • ap_log_*error成为宏包装器(如果使用APLOG_MARK宏,则向后兼容,但不再可以在参数列表中使用#ifdef)

  • 管道测井改造

  • module_index已添加到 error_log 钩子

  • 新功能:ap_log_command_line

http_request (changed)

  • 新的 auth_internal API 和 auth_provider API

  • 新的EOR铲斗类型

  • 新功能ap_process_async_request

  • 新标志AP_AUTH_INTERNAL_PER_CONFAP_AUTH_INTERNAL_PER_URI

  • 新的access_checker_ex钩子可应用其他访问控制和/或绕过身份验证。

  • 接受AP_AUTH_INTERNAL_PER_*标志的新功能ap_hook_check_access_exap_hook_check_accessap_hook_check_authnap_hook_check_authz

  • 不再直接使用ap_hook_access_checkeraccess_checker_exap_hook_check_user_idap_hook_auth_checker

如果可能,建议使用AP_AUTH_INTERNAL_PER_CONF注册所有访问控制钩子(包括身份验证和授权钩子)。如果所有模块的访问控制钩都使用此标志注册,则每当服务器处理与初始请求相同的访问控制配置指令集匹配的内部子请求时(这是常见的情况),就可以避免调用访问控制钩另一个时间。

如果您的模块要求使用旧行为,并且必须使用与初始请求不同的 URI 对每个子请求执行访问控制检查,即使该 URI 与相同的访问控制配置指令集匹配,也请使用AP_AUTH_INTERNAL_PER_URI

mod_auth (NEW!)

介绍用于 authn 和 authz 的新提供程序框架

mod_cache (changed)

向缓存提供程序接口引入commit_entity()函数,从而允许对缓存进行原子写入。添加一个cache_status()钩子以报告缓存决定。所有私有结构和功能均被删除。

mod_core (NEW!)

这引入了低级 API 来发送任意 Headers,并公开了用于处理 HTTP OPTIONS 和 TRACE 的函数。

mod_cache_disk (changed)

更改磁盘高速缓存的磁盘格式,以支持原子高速缓存更新而不进行锁定。主体文件的设备/节点对嵌入在头文件中,从而允许确认头和主体属于彼此。

mod_disk_cache (renamed)

为了与服务器中其他模块的命名保持一致,已将 mod_disk_cache 模块重命名为 mod_cache_disk。

mod_request (NEW!)

mod_request的 API,可在需要时使 Importing 数据可用于多个应用程序/处理程序模块,并解析 HTML 表单数据。

mpm_common (changed)

  • 删除:acceptlockfilelock_mechset_scoreboard(锁定使用新的 ap_mutex API)

  • 放弃特权的新 API(将与平台相关的功能委托给模块)

  • 新钩子:mpm_querytimed_callbackget_name

  • 更改的接口:monitor钩子,ap_reclaim_child_processesap_relieve_child_processes

scoreboard (changed)

引入了替代版本后,ap_get_scoreboard_worker已向后兼容。额外的 proxy_balancer 支持。child 状态的东西进行了修改。

util_cookies (NEW!)

引入了用于 Management HTTP Cookies 的新 API。

util_ldap (changed)

没有可用的描述

util_mutex (NEW!)

httpd 中的 APR proc 和全局互斥的包装,为底层机制和锁定文件的位置提供通用配置。

util_script (changed)

新:ap_args_to_table

util_time (changed)

新:ap_recent_ctime_ex

有关从 2.2 升级模块的特定信息

Logging

为了利用按模块日志级别的配置,任何调用ap_log_*函数的源文件都应声明其属于哪个模块。如果模块的 module_struct 称为foo_module,则可以使用以下代码保持与 HTTPD 2.0 和 2.2 的向后兼容性:

#include <http_log.h> #ifdef APLOG_USE_MODULE APLOG_USE_MODULE(foo); #endif

注意:这对于 C 语言模块是绝对必需的。可以跳过 C 语言模块,尽管这样会破坏没有该模块的文件的特定于日志级别的支持。

ap_log_*函数的参数数量和APLOG_MARK的定义已更改。通常,更改是完全透明的。但是,如果模块使用APLOG_MARK作为其自身功能的参数,或者模块在不传递APLOG_MARK的情况下调用ap_log_*,则需要进行更改。在ap_log_*周围使用包装器的模块通常同时使用这两种构造。

更改将APLOG_MARK传递到其自身函数的代码的最简单方法是定义并使用另一个扩展为这些函数所需参数的宏,因为APLOG_MARK仅应在直接调用ap_log_*时使用。这样,代码将保持与 HTTPD 2.0 和 2.2 的兼容性。

在 2.4 和早期发行版之间,调用ap_log_*而不传递APLOG_MARK的代码必然有所不同,因为 2.4 需要新的第三个参数APLOG_MODULE_INDEX

/* code for httpd 2.0/2.2 */ ap_log_perror(file, line, APLOG_ERR, 0, p, "Failed to allocate dynamic lock structure"); /* code for httpd 2.4 */ ap_log_perror(file, line, APLOG_MODULE_INDEX, APLOG_ERR, 0, p, "Failed to allocate dynamic lock structure");

ap_log_*error现在被实现为宏。这意味着不再可以在ap_log_*error的参数列表中使用#ifdef,因为根据 C99,这将导致不确定的行为。

启动后调用时,必须将server_rec指针传递给ap_log_error()。这总是很合适,但是 2.4 中NULL server_rec的限制比以前的版本还要多。从 2.3.12 开始,全局变量ap_server_conf始终可以用作server_rec参数,因为只有在将NULL传递给ap_log_error()时才是NULL。仅当没有更合适的server_rec时才应使用ap_server_conf

考虑以下更改以利用新的APLOG_TRACE1..8日志级别:

  • 检查APLOG_DEBUG的当前使用情况,并考虑APLOG_TRACEn之一是否更合适。

  • 如果您的模块当前具有用于配置所执行的调试日志记录数量的机制,请考虑消除该机制并依靠使用不同的APLOG_TRACEn级别。如果根据配置的日志级别需要绕开昂贵的跟踪处理,请使用APLOGtracenAPLOGrtracen宏首先检查是否启用了跟踪。

模块有时会在其日志消息中添加进程 ID 和/或线程 ID。现在默认情况下会记录这些 ID,因此模块可能无需显式记录它们。 (用户可以将其从错误日志格式中删除,但是可以指示他们在必要时将其重新添加以进行问题诊断.)

如果您的模块使用这些现有的 API ...

  • ap_default_type()

    • 不再可用; Content-Type 必须显式配置或由应用程序添加。
  • ap_get_server_name()

    • 如果在 URL 中使用了返回的服务器名称,请改用ap_get_server_name_for_url()。此新功能处理服务器名称是 IPv6 Literals 地址的奇怪情况。
  • ap_get_server_version()

    • 为了便于记录,在需要详细信息的地方,请使用ap_get_server_description()。生成输出时,应由 ServerTokens 配置信息量,请使用ap_get_server_banner()
  • ap_graceful_stop_signalled()

    • 替换为对ap_mpm_query(AP_MPMQ_MPM_STATE)的调用并检查状态AP_MPMQ_STOPPING
  • ap_max_daemons_limitap_my_generationap_threads_per_child

    • 分别使用ap_mpm_query()个查询代码AP_MPMQ_MAX_DAEMON_USEDAP_MPMQ_GENERATIONAP_MPMQ_MAX_THREADS
  • ap_mpm_query()

    • 确保在完成注册钩之后才使用它。否则,作为 DSO 构建的 MPM 将没有机会启用对此功能的支持。
  • ap_requires()

    • 现在,核心服务器为处理Require配置提供了更好的基础结构。使用ap_register_auth_provider()为每个受支持的实体注册一个身份验证提供程序功能。 Require处理期间将根据需要调用该函数。 (有关详细示例,请咨询 Binding 的模块.)
  • ap_server_conf->process->pool个用户数据

    • Optional:
  • 如果您的模块使用它来确定正在运行哪个启动钩子,请使用ap_state_query(AP_SQ_MAIN_STATE)

  • 如果您的模块使用它来维护模块卸载和重新加载期间的数据,请使用ap_retained_data_create()ap_retained_data_get()

  • apr_global_mutex_create() , apr_proc_mutex_create()

    • 可选:参见ap_mutex_register()ap_global_mutex_create()ap_proc_mutex_create();这些使您可以使用Mutex指令配置 Mutex;您也可以在模块中删除此类互斥锁的任何配置机制
  • CORE_PRIVATE

    • 现在这是不必要的,可以忽略。
  • dav_new_error()dav_new_error_tag()

    • 以前,这些假设errno包含描述故障的信息。现在,必须提供apr_status_t参数。如果没有此类错误信息,则传递 0/APR_SUCCESS,否则传递一个有效的apr_status_t值。
  • mpm_default.hDEFAULT_LOCKFILEDEFAULT_THREAD_LIMITDEFAULT_PIDLOG等。

    • 头文件和其中设置的大多数默认配置值不再对模块可见。 (大多数仍然可以在构建时被覆盖.)DEFAULT_PIDLOGDEFAULT_REL_RUNTIMEDIR现在可以通过ap_config.h普遍使用。
  • unixd_config

    • 它已重命名为 ap_unixd_config。
  • unixd_setup_child()

    • 该名称已重命名为 ap_unixd_setup_child(),但大多数调用者应调用添加的 ap_run_drop_privileges()钩子。
  • conn_rec->remote_ipconn_rec->remote_addr

    • 这些字段已重命名,以区分连接的 Client 端 IP 地址和请求的用户代理 IP 地址(可能被负载平衡器或代理覆盖)。必须使用适用于模块的以下选项之一来更新对这两个字段之一的引用:
  • 当您需要用户代理的 IP 地址(可以直接连接到服务器,或者可以选择通过透明的负载均衡器或代理与服务器分开)时,请使用request_rec->useragent_iprequest_rec->useragent_addr

  • 如果您需要直接连接到服务器的 Client 端的 IP 地址(可能是用户代理,也可能是负载平衡器或代理本身),请使用conn_rec->client_ipconn_rec->client_addr

如果您的模块具有此功能,则...

  • suEXEC

    • 可选:如果当ap_unixd_config.suexec_enabled为 0 时模块记录错误,则还要记录新字段suexec_disabled_reason的值,该字段包含为什么不可用的说明。
  • 计分板上的扩展状态数据

    • 在以前的版本中,必须将ExtendedStatus设置为On,这又需要加载 mod_status。在 2.4 中,只需在预配置钩子中将ap_extended_status设置为1即可使用扩展状态数据。

您的模块是否...

  • 解析查询参数

    • 考虑ap_args_to_table()是否会有所帮助。
  • 解析表单数据...

    • 使用ap_parse_form_data()
  • 检查请求 Headers 字段Content-LengthTransfer-Encoding以查看是否指定了正文

    • 使用ap_request_has_body()
  • 实现清除指针变量的清理

    • 使用ap_pool_cleanup_set_null()
  • 创建运行时文件,例如共享内存文件,PID 文件等。

    • 使用ap_runtime_dir_relative(),以便遵循DEFAULT_REL_RUNTIMEDIR编译设置或DefaultRuntimeDir指令对此类文件位置进行的全局配置。 * Apache httpd 2.4.2 及更高版本.*