PHP:如何使用Transfer-Encoding读取POST正文:分块,无内容长度 [英] PHP: How to read POST body with Transfer-Encoding: chunked, no Content-Length
问题描述
我正在编写一项服务,以从家里的能源监控设备接收数据.设备可以推送数据的唯一方法是使用HTTP POST
(带Transfer-Encoding: chunked
,不带Content-Length
),以及将数据作为XML放入请求正文中.
I am writing a service to receive data from an energy monitoring device in my house. The only way the device can push data is by using an HTTP POST
, with Transfer-Encoding: chunked
, and no Content-Length
, and the data as XML in the request body.
我希望能够在PHP脚本(Apache后面)中读取此数据并将其存储在我的数据库中.
I would like to be able to read this data in a PHP script (behind Apache) and store it in my database.
这些天来,用PHP读取HTTP请求正文的最正确方法似乎是打开并读取php://input
.但是,PHP网站上用户的评论表明(并且我的测试确认),如果客户端未指定Content-Length
标头,则php://input
不返回任何数据(即使客户端正在以分块编码的形式发送数据)
It appears that the most correct way to read the HTTP request body in PHP these days is to open and read php://input
. However, comments from users on PHP's website indicate (and my testing confirms), that if no Content-Length
header is specified by the client, php://input
returns no data (even if there is data being sent by the client in chunked encoding).
是否存在访问请求正文的另一种方法?我可以配置Apache(使用.htaccess)来解码分块的数据,并在获得所有数据后调用我的脚本,并包括Content-Length
吗?还是配置PHP,使其能够处理此问题?
Is there an alternate way to get access to the request body? Can I configure Apache (with .htaccess) to decode the chunked data and call my script once it gets it all, and include Content-Length
? Or configure PHP so it will be able to handle this?
谢谢!
推荐答案
也许我也应该将此作为答案.
Might as well write this as an answer I suppose.
您描述的问题记录在这里: https://bugs.php.net/bug.php?id = 60826
The issue you describe is documented here: https://bugs.php.net/bug.php?id=60826
该线程的亮点:
这就是我所发现的.如果您发送分块的HTTP请求,但不发送 发送内容长度(就像我们应该使用HTTP 1.1协议那样) 请求的主体部分为空(php://input不返回任何内容).这 结果对于以下运行PHP的配置仍然有效 通过FastCGI:
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 :
与运行mod_php的PHP相同的配置很好,正文 该请求可通过php://input获得.
The same configuration with PHP running as mod_php is fine, the body request is available through php://input.
还有
本质上,PHP遵循规范,而不是超出规范 FastCGI CONTENT_LENGTH标头值-因此,正确的解决方法是 必须在PHP之上,在FastCGI或Web服务器实现中.
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一起使用
0) Use httpd with mod_php
1)使用其他Web服务器.
1) Use a different web server.
2)查看mod_fcgid的补丁
2) Look at patches for mod_fcgid
3)也许(不建议)翻转always_populate_raw_post_data
并查看 $ HTTP_RAW_POST_DATA
3) Maybe (not recommended) flip always_populate_raw_post_data
and see if there is anything in $HTTP_RAW_POST_DATA
这篇关于PHP:如何使用Transfer-Encoding读取POST正文:分块,无内容长度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!