Apache模块:实现100-Continue

时间:2016-02-17 11:59:39

标签: php apache http

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

上下文

HTTP / 1.1规范创建了请求标头'Expect',它有一个定义的值;即'100-Continue'。 2014年6月发布的修订后的HTTP / 1.1 RFC(见RFC 7231 Section 5.1.1)声明如下:

  

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

这也是一个普遍接受的声明,即规范的这一部分不完全由服务器和客户端实现。修订后的规范甚至提到了这一点:

  

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

强调是我的,而不是来自规范

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

但是,它仅基于其自己的请求处理来完成此操作,即不咨询PHP资源。这似乎打败了标头的目的,因为大多数请求都会因无效的请求参数或权限而失败;不是由于格式错误的HTTP请求。因此,即使客户端声明100-continue期望并收到100-continue响应,也不意味着请求头是有效的。

意图

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

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

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

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. 过去是否有任何模块试图解决这个问题?

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

    1. 有哪些Apache钩子可用?我找不到一个标识可用挂钩的资源以及它们的处理顺序。找到它 Apache2: Apache Hooks

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

1 个答案:

答案 0 :(得分:2)

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

你也必须实现自己的客户端(至少作为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。

客户端代码没有什么区别。

但是假设你有一大批开发人员和测试人员没有比开发你提议的模块更好的事情,并且它不需要对处理程序进行大量更改,或者上述处理程序的维护者为自己构建期望/ 100。 ..为什么我,因为网络服务器管理员想要安装这样的模块,当我可以得到相同的结果而不必安装额外的模块,增加我的网络服务器的攻击面并调整我已经使用的任何代码?