【问题标题】:Apache Modules: Implementing 100-ContinueApache 模块:实现 100-Continue
【发布时间】:2016-02-17 11:59:39
【问题描述】:

Supporting HTTP 100 Continue with PHP 早在 2010 年就提出了这个问题,但关注点略有不同(它寻求的是 PHP 解决方案而不是 Apache 解决方案),但从未得到解决。

上下文

HTTP/1.1 规范创建了具有一个定义值的请求标头“Expect”;即“100-继续”。 2014 年 6 月发布的经修订的 HTTP/1.1 RFC(参见 RFC 7231 Section 5.1.1)声明如下:

100-continue 期望通知接收者客户即将 在这个请求和愿望中发送一个(可能很大的)消息体 如果请求行和 标头字段不足以立即成功, 重定向或错误响应。这允许客户端等待 表明值得在之前发送消息正文 实际上是这样做的,这样可以提高消息正文时的效率 很大或当客户预计可能出现错误时(例如, 第一次发送状态改变方法时,没有 以前验证过的身份验证凭据)。

这也是一种普遍接受的说法,即规范的这一部分在服务器和客户端都没有完美地实现。修订后的规范甚至暗示了这一点:

...但是,客户端并没有使用扩展机制许多服务器没有实现必须理解的要求...

重点是我的,不是来自规范

即使不包括此标头的扩展机制,100-continue 值似乎也没有很好地实现。如果我们考虑一个标准的 PHP/Apache 堆栈,Apache 确实会在客户端请求时提供 100-continue 临时响应。

但是,它仅根据自己对请求的处理来执行此操作,即不咨询 PHP 资源。这似乎违背了标头的目的,因为大多数请求将由于无效的请求参数或权限而失败;不是由于格式错误的 HTTP 请求。所以,即使客户端声明了 100-continue 的期望,收到了 100-continue 的响应,也不代表请求头是有效的。

意图

作为更全面实施 HTTP 规范的更广泛意图的一部分(为了提高网络效率、安全性和清晰度),我打算在发送 100-continue 响应之前更正确地验证请求标头。

这意味着在发送 100-continue 响应之前,必须将请求传递给我的 PHP 资源控制器进行验证。这允许在客户端浪​​费时间和资源发送大型消息体之前识别无效参数和不适当的权限。

我希望交换看起来像这样:

Client                    Apache                      Resource
->|                         |                            |
  |------Request Head------>|                            |
  |                         |-[Parse]                    |
  |<-----400 bad request----|                            |
  |                         |-[Route]                    |
  |                         |-------Request Head-------->|
  |                         |                            |-[Validate]
  |                         |<---Error / 100 Continue----|
  |<--Error / 100 Continue--|                            |
<-|[End or...]              |                            |
  |------Request Body------>|                            |
  |                         |--------Full Request------->|
  |                         |                            |-[Process]
  |                         |<---------Response----------|
  |<--------Response--------|                            |
<-|                         |                            |

显然,这需要 PHP 应用程序和 apache Web 服务器之间进行更多的交互操作。

策略

由于所需的集成程度,唯一的解决方案似乎是一个 Apache 模块/扩展,旨在在发送 100-continue 响应之前立即挂钩请求,并执行将请求头传递给用于解析的 PHP 资源。

从那里,可以恢复正常的 Apache 处理,发送 100-continue 响应,Apache 等待消息正文,然后将完成的请求传递给 PHP 资源。

问题

  1. 上述的 Apache 模块会是对当前实现的改进吗?

  2. 过去是否有任何模块试图解决这个问题?

另外,关于开发 Apache 模块的技术细节:

  1. 有哪些可用的 Apache 挂钩?我找不到标识可用挂钩及其处理顺序的资源。 找到了 Apache2: Apache Hooks

  2. Apache 模块应该如何与 PHP 交互? 我知道这取决于安装方法(例如,Apache 进程中的多个线程或每次执行的单个进程等)。但我不确定 Apache 如何准确地管理与 PHP 进程的其他交互。

【问题讨论】:

    标签: php apache http


    【解决方案1】:

    您所描述的内容不适用于大多数处理程序,包括 PHP。 HTTP 是一种基于消息的协议,通常它是一种请求-回复方法——唯一的例外是连接请求、Web 套接字和 expect/100 响应。因此实现这一点需要重新设计网络服务器的内部结构、处理程序的接口和处理程序本身:对于 CGI、fastcgi 和 isapi 模块,PHP 直到它被编组到网络服务器中才看到请求。

    您还必须实现自己的客户端(至少作为 AJAX/SJAX JavaScript)。

    考虑改为在您的请求之前进行:

     Client: can I send a really big file?
     Server: 204
     Client: here's a really big file
    

    只有一组额外的标头,与 expect/100 方法相比,特别是没有额外的 RTT。花一些时间来计算每个请求的最终成本。它很小。它将适用于今天的所有服务器。并且不需要几个月的努力来开发。 不希望过于拘泥于问题的替代解决方案的细节,显然我们希望两个客户端请求中的 URL 相同,因此需要在其他地方表达 2 个客户端请求的意图差异,例如在第一个请求中使用 OPTIONS 动词,在第二个请求中使用 PUT/POST/GET/DELETE。

    这方面的客户端代码差别不大。

    但是假设您拥有一支开发人员和测试人员大军,除了开发您提出的模块之外别无他法,并且它不需要对处理程序进行大量更改,或者上述处理程序的维护者自己构建了对 expect/100 的支持。 .. 作为网络服务器管理员,我为什么要安装这样的模块,而无需安装其他模块即可获得相同的结果,增加网络服务器的攻击面并调整我已经在使用的任何代码?

    【讨论】:

    • 是的,这是我第一次查看 Apache 模块,现在阅读了一些关于它的内容,我的一般结论是……这不值得。我曾希望会有一个相当简单的 apache hook-in,其余的可以用 PHP 处理,但似乎没有。我对无法使用 100-continue 感到有点恼火(即使它明显适用),但我的恼怒几乎没有经济价值,而且正如你所描述的,满足它所需的时间成本非常高。
    猜你喜欢
    • 1970-01-01
    • 2021-09-12
    • 1970-01-01
    • 2019-05-01
    • 2012-12-18
    • 2010-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多