TIdHTTPServer 在接收 PostStream 时获取内容长度

TIdHTTPServer Getting content-length when receiving the PostStream

我正在使用 Delphi 7 和 Indy 9 来实现一个简单的 HTTP 服务器。当我使用 POST 方法将文件上传到服务器时,我想知道 OnCommandGet 事件之前的内容长度,以便显示进度条。 事件顺序如下:

  1. 在 OnPostStream 上,我创建了一个文件流并挂接了 OnWork 事件。 (这里我需要content-length来设置进度条)
  2. POST 正文已上传,OnWork 使用传输的字节触发。
  3. OnCommandGet 甚至触发,我得到了具有正确内容长度的 TIdHTTPRequestInfo 对象,但此时为时已晚。

我修改了 Indy 源代码,以在传递给 OnPostStream 处理程序的 ASender.Data 字段中获取 TIdHTTPRequestInfo 的副本。 一切正常,但我不想碰 Indy。

是否有更清洁的解决方案? 谢谢

Is there a cleaner solution?

不适用于 Indy 9,不。修改 Indy 的源代码以公开对请求 object(或至少请求 headers)的访问是唯一的选择。

在 Indy 10 中,TIdHTTPServer 实际上提供了 2 种方法,您可以在读取 POST 数据之前获取 Content-Length 值 -有一个新的 OnHeadersAvailable 事件有一个 AHeaders 参数,OnCreatePostStream 事件也有一个新的 AHeaders 参数(所以不同的流 类 可以根据发出的请求的类型使用)。您可以在任一事件中从提供的 TIdHeaderList object 中获取 Content-Length 值,并将该值存储在 ASender.Data 中以备后用。

但是 - 请记住 Indy 10 中的 TIdHTTPServer 支持 HTTP 1.1,并且 需要 HTTP 1.1 服务器以允许 HTTP 1.1 客户端 post 数据使用 chunked 传输编码。在这种情况下,将没有 Content-Length header 存在(或者它将是 0),因此在接收到最后一个块之前不会知道数据长度。幸运的是,您可以查看 OnHeadersAvailable/OnCreatePostStream 事件中的 Transfer-Encoding header 来检测该情况并相应地调整您的进度事件。