PHP:如何用 Transfer-Encoding 读取 POST body:分块,没有 Content-Length
PHP: How to read POST body with Transfer-Encoding: chunked, no Content-Length
我正在编写一个服务来从我家里的能源监控设备接收数据。设备可以推送数据的唯一方法是使用 HTTP POST
,有 Transfer-Encoding: chunked
,没有 Content-Length
,请求中的数据为 XML body.
我希望能够在 PHP 脚本(在 Apache 后面)中读取这些数据并将其存储在我的数据库中。
看来这几天在PHP中阅读HTTP请求body最正确的方法是打开阅读php://input
。但是,PHP 网站上用户的评论表明(并且我的测试证实),如果客户端未指定 Content-Length
header,则 php://input
returns 没有数据(即使客户端以分块编码发送数据)。
是否有其他方法来访问请求 body?我可以配置 Apache(使用 .htaccess)来解码分块数据并在获取所有数据后调用我的脚本,并包含 Content-Length
吗?或者配置 PHP 以便它能够处理这个问题?
谢谢!
不妨把这个写成我想的答案。
您描述的问题记录在此处:https://bugs.php.net/bug.php?id=60826
线程要点:
So here is what I found. If you send chunked http request but do not
send the content-length (as we should do using HTTP 1.1 protocol) the
body part of the request is empty (php://input returns nothing). This
result remains valid for the following configuration where PHP runs
via FastCGI :
The same configuration with PHP running as mod_php is fine, the body
request is available through php://input.
和
Essentially, PHP is following the spec, and not reading beyond the
FastCGI CONTENT_LENGTH header value - so correct fixes are
necessarily above PHP, in the FastCGI or web server implementation.
可能的解决方法:
0) 将 httpd 与 mod_php
一起使用
1) 使用不同的网络服务器。
2) 查看 mod_fcgid
的补丁
3) 也许(不推荐)翻转 always_populate_raw_post_data
并查看 $HTTP_RAW_POST_DATA
中是否有任何内容
我正在编写一个服务来从我家里的能源监控设备接收数据。设备可以推送数据的唯一方法是使用 HTTP POST
,有 Transfer-Encoding: chunked
,没有 Content-Length
,请求中的数据为 XML body.
我希望能够在 PHP 脚本(在 Apache 后面)中读取这些数据并将其存储在我的数据库中。
看来这几天在PHP中阅读HTTP请求body最正确的方法是打开阅读php://input
。但是,PHP 网站上用户的评论表明(并且我的测试证实),如果客户端未指定 Content-Length
header,则 php://input
returns 没有数据(即使客户端以分块编码发送数据)。
是否有其他方法来访问请求 body?我可以配置 Apache(使用 .htaccess)来解码分块数据并在获取所有数据后调用我的脚本,并包含 Content-Length
吗?或者配置 PHP 以便它能够处理这个问题?
谢谢!
不妨把这个写成我想的答案。
您描述的问题记录在此处:https://bugs.php.net/bug.php?id=60826
线程要点:
So here is what I found. If you send chunked http request but do not send the content-length (as we should do using HTTP 1.1 protocol) the body part of the request is empty (php://input returns nothing). This result remains valid for the following configuration where PHP runs via FastCGI :
The same configuration with PHP running as mod_php is fine, the body request is available through php://input.
和
Essentially, PHP is following the spec, and not reading beyond the FastCGI CONTENT_LENGTH header value - so correct fixes are necessarily above PHP, in the FastCGI or web server implementation.
可能的解决方法:
0) 将 httpd 与 mod_php
一起使用1) 使用不同的网络服务器。
2) 查看 mod_fcgid
的补丁3) 也许(不推荐)翻转 always_populate_raw_post_data
并查看 $HTTP_RAW_POST_DATA