<-
Apache > HTTP 服务器 > 文档 > 版本 2.4 > 开发者文档

Apache HTTP Server 2.x 中的请求处理

可用语言:  en 

警告

警告 - 这是一个第一版(快速)草稿,需要进一步修订!

2.0 及更高版本中的几个更改影响了内部请求处理机制。模块作者需要了解这些更改,以便他们可以利用优化和安全增强功能。

第一个主要变化是子请求和重定向机制。Apache HTTP Server 1.3 中有许多不同的代码路径来尝试优化子请求或重定向行为。随着补丁被引入 2.0,这些优化(以及服务器行为)由于代码的重复而很快被破坏。所有重复的代码都已折叠回 ap_process_request_internal(),以防止代码再次不同步。

这意味着许多现有代码是“未优化的”。Apache HTTP 项目的首要目标是创建 HTTP 服务器 RFC 的健壮且正确的实现。其他目标包括安全性、可扩展性和优化。人们一直在寻找新的方法来优化服务器(超越 1.3 的性能),而不会引入脆弱或不安全的代码。

Support Apache!

另请参阅

top

请求处理周期

所有请求都通过 server/request.c 中的 ap_process_request_internal() 传递,包括子请求和重定向。如果模块没有通过此代码传递生成的请求,则警告作者该模块可能会被对请求处理的未来更改破坏。

为了简化请求,模块作者可以利用提供的 钩子 提前退出请求周期,或绕过不相关的核心钩子(在 CPU 方面成本很高)。

top

请求解析阶段

对 URL 进行反转义

请求的 parsed_uri 路径在内部请求处理开始时仅反转义一次。

如果设置了 proxyreq 标志或 parsed_uri.path 元素未设置,则会绕过此步骤。模块无法进一步控制此一次性反转义操作,无论是未能反转义还是多次反转义 URL 都会导致安全问题。

从 URI 中剥离父级和当前元素

所有 /..//./ 元素都将被 ap_getparents() 删除,以及任何尾随的 /./.. 元素。这有助于确保在请求处理继续之前路径(几乎)是绝对的。(有关更多讨论,请参阅 RFC 1808 第 4 节。)

此步骤无法绕过。

初始 URI 位置遍历

每个请求都将进行 ap_location_walk() 调用。这确保了 <Location> 部分对所有请求都始终强制执行。如果请求是内部重定向或子请求,它可能会借用来自先前或父请求的 ap_location_walk 的部分或全部处理,因此此步骤在处理主请求后通常非常有效。

translate_name

模块可以在此步骤中确定文件名或更改给定的 URI。例如,mod_vhost_alias 将 URI 的路径转换为配置的虚拟主机,mod_alias 将路径转换为别名路径,如果请求回退到核心,则 DocumentRoot 将附加到请求资源。

如果所有模块在此阶段都 DECLINE,则会向浏览器返回错误 500,并且会自动记录“无法转换名称”错误。

钩子: map_to_storage

确定文件或正确 URI 后,将合并相应的每个目录配置。例如,mod_proxy 会比较并合并相应的 <Proxy> 部分。如果 URI 只是一个本地(非代理)TRACE 请求,则核心会处理请求并返回 DONE。如果没有任何模块以 OKDONE 响应此钩子,则核心会针对 <Directory><Files> 部分运行请求文件名。如果请求“文件名”不是绝对的合法文件名,则会设置一个注释以供以后终止。

URI 位置遍历

每个请求都会通过第二次 ap_location_walk() 调用进行强化。这确保了已转换的请求仍然受配置的 <Location> 部分的约束。请求再次借用来自其上面先前 location_walk 的部分或全部处理,因此此步骤几乎总是非常有效,除非已转换的 URI 映射到一个完全不同的路径或虚拟主机。

钩子: header_parser

然后,主请求会解析客户端的标头。这将为剩余的请求处理步骤做好准备,以便更好地满足客户端的请求。

top

安全阶段

需要文档。代码是

if ((access_status = ap_run_access_checker(r)) != 0) {
    return decl_die(access_status, "check access", r);
}

if ((access_status = ap_run_check_user_id(r)) != 0) {
    return decl_die(access_status, "check user", r);
}

if ((access_status = ap_run_auth_checker(r)) != 0) {
    return decl_die(access_status, "check authorization", r);
}
top

准备阶段

钩子: type_checker

模块有机会针对目标资源测试 URI 或文件名,并为请求设置 mime 信息。mod_mimemod_mime_magic 都使用此阶段将文件名或内容与管理员的配置进行比较,并设置内容类型、语言、字符集和请求处理程序。一些模块可能会在此阶段设置其过滤器或其他请求处理参数。

如果所有模块在此阶段都 DECLINE,则会向浏览器返回错误 500,并且会自动记录“找不到类型”错误。

钩子: fixups

许多模块在上面的某个阶段被“击败”。fixups 阶段由模块用来“重新断言”其所有权或强制请求字段为其适当的值。它并不总是最干净的机制,但有时它是唯一的选择。

top

处理程序阶段

此阶段**不是** ap_process_request_internal() 中处理的一部分。许多模块在创建任何内容之前都会准备一个或多个子请求。在核心或模块调用 ap_process_request_internal() 后,它会调用 ap_invoke_handler() 来生成请求。

钩子: insert_filter

以某种方式转换内容的模块可以插入其值并覆盖现有过滤器,这样,如果用户以错误的顺序配置了更高级的过滤器,则模块可以根据需要移动其顺序。没有结果代码,因此此钩子中的操作最好被认为始终成功。

钩子: handler

模块终于有机会在其处理程序钩子中处理请求。请注意,并非所有准备好的请求都会发送到处理程序钩子。许多模块(例如 mod_autoindex)会为给定的 URI 创建子请求,然后永远不会处理子请求,而只是将其列出给用户。请记住,不要将来自上面钩子的必需拆卸放入此模块,而是针对请求池注册池清理,以便根据需要释放资源。

可用语言:  en 

top

评论

注意
这不是问答部分。此处放置的评论应指向有关改进文档或服务器的建议,如果它们被实施或被认为无效/偏离主题,则我们的版主可能会将其删除。有关如何管理 Apache HTTP Server 的问题应直接发送到我们的 IRC 频道 #httpd(在 Libera.chat 上),或发送到我们的 邮件列表