Apache HTTP Server 版本 2.4
可用语言: en
警告 - 这是一个第一版(快速)草稿,需要进一步修订!
2.0 及更高版本中的几个更改影响了内部请求处理机制。模块作者需要了解这些更改,以便他们可以利用优化和安全增强功能。
第一个主要变化是子请求和重定向机制。Apache HTTP Server 1.3 中有许多不同的代码路径来尝试优化子请求或重定向行为。随着补丁被引入 2.0,这些优化(以及服务器行为)由于代码的重复而很快被破坏。所有重复的代码都已折叠回 ap_process_request_internal()
,以防止代码再次不同步。
这意味着许多现有代码是“未优化的”。Apache HTTP 项目的首要目标是创建 HTTP 服务器 RFC 的健壮且正确的实现。其他目标包括安全性、可扩展性和优化。人们一直在寻找新的方法来优化服务器(超越 1.3 的性能),而不会引入脆弱或不安全的代码。
所有请求都通过 server/request.c
中的 ap_process_request_internal()
传递,包括子请求和重定向。如果模块没有通过此代码传递生成的请求,则警告作者该模块可能会被对请求处理的未来更改破坏。
为了简化请求,模块作者可以利用提供的 钩子 提前退出请求周期,或绕过不相关的核心钩子(在 CPU 方面成本很高)。
请求的 parsed_uri
路径在内部请求处理开始时仅反转义一次。
如果设置了 proxyreq 标志或 parsed_uri.path
元素未设置,则会绕过此步骤。模块无法进一步控制此一次性反转义操作,无论是未能反转义还是多次反转义 URL 都会导致安全问题。
所有 /../
和 /./
元素都将被 ap_getparents()
删除,以及任何尾随的 /.
或 /..
元素。这有助于确保在请求处理继续之前路径(几乎)是绝对的。(有关更多讨论,请参阅 RFC 1808 第 4 节。)
此步骤无法绕过。
每个请求都将进行 ap_location_walk()
调用。这确保了 <Location>
部分对所有请求都始终强制执行。如果请求是内部重定向或子请求,它可能会借用来自先前或父请求的 ap_location_walk
的部分或全部处理,因此此步骤在处理主请求后通常非常有效。
模块可以在此步骤中确定文件名或更改给定的 URI。例如,mod_vhost_alias
将 URI 的路径转换为配置的虚拟主机,mod_alias
将路径转换为别名路径,如果请求回退到核心,则 DocumentRoot
将附加到请求资源。
如果所有模块在此阶段都 DECLINE
,则会向浏览器返回错误 500,并且会自动记录“无法转换名称”错误。
确定文件或正确 URI 后,将合并相应的每个目录配置。例如,mod_proxy
会比较并合并相应的 <Proxy>
部分。如果 URI 只是一个本地(非代理)TRACE
请求,则核心会处理请求并返回 DONE
。如果没有任何模块以 OK
或 DONE
响应此钩子,则核心会针对 <Directory>
和 <Files>
部分运行请求文件名。如果请求“文件名”不是绝对的合法文件名,则会设置一个注释以供以后终止。
每个请求都会通过第二次 ap_location_walk()
调用进行强化。这确保了已转换的请求仍然受配置的 <Location>
部分的约束。请求再次借用来自其上面先前 location_walk
的部分或全部处理,因此此步骤几乎总是非常有效,除非已转换的 URI 映射到一个完全不同的路径或虚拟主机。
然后,主请求会解析客户端的标头。这将为剩余的请求处理步骤做好准备,以便更好地满足客户端的请求。
需要文档。代码是
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); }
模块有机会针对目标资源测试 URI 或文件名,并为请求设置 mime 信息。mod_mime
和 mod_mime_magic
都使用此阶段将文件名或内容与管理员的配置进行比较,并设置内容类型、语言、字符集和请求处理程序。一些模块可能会在此阶段设置其过滤器或其他请求处理参数。
如果所有模块在此阶段都 DECLINE
,则会向浏览器返回错误 500,并且会自动记录“找不到类型”错误。
许多模块在上面的某个阶段被“击败”。fixups 阶段由模块用来“重新断言”其所有权或强制请求字段为其适当的值。它并不总是最干净的机制,但有时它是唯一的选择。
此阶段**不是** ap_process_request_internal()
中处理的一部分。许多模块在创建任何内容之前都会准备一个或多个子请求。在核心或模块调用 ap_process_request_internal()
后,它会调用 ap_invoke_handler()
来生成请求。
以某种方式转换内容的模块可以插入其值并覆盖现有过滤器,这样,如果用户以错误的顺序配置了更高级的过滤器,则模块可以根据需要移动其顺序。没有结果代码,因此此钩子中的操作最好被认为始终成功。
模块终于有机会在其处理程序钩子中处理请求。请注意,并非所有准备好的请求都会发送到处理程序钩子。许多模块(例如 mod_autoindex
)会为给定的 URI 创建子请求,然后永远不会处理子请求,而只是将其列出给用户。请记住,不要将来自上面钩子的必需拆卸放入此模块,而是针对请求池注册池清理,以便根据需要释放资源。
可用语言: en