简体   繁体   English

PHP:如何使用Transfer-Encoding读取POST正文:分块,无内容长度

[英]PHP: How to read POST body with Transfer-Encoding: chunked, no Content-Length

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. 设备可以推送数据的唯一方法是使用HTTP POST (具有Transfer-Encoding: chunked ,没有Content-Length ,并且将数据作为XML放入请求正文中。

I would like to be able to read this data in a PHP script (behind Apache) and store it in my database. 我希望能够在PHP脚本(Apache后面)中读取此数据并将其存储在我的数据库中。

It appears that the most correct way to read the HTTP request body in PHP these days is to open and read php://input . 如今,在PHP中读取HTTP请求正文的最正确方法似乎是打开并读取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). 但是,PHP网站上用户的评论表明(并且我的测试确认),如果客户端未指定Content-Length标头,则php://input不会返回任何数据(即使客户端正在分块发送数据)编码)。

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 ? 我是否可以配置Apache(使用.htaccess)来解码分块的数据,并在获得全部数据后调用我的脚本,并包括Content-Length Or configure PHP so it will be able to handle this? 还是配置PHP,以便能够处理此问题?

Thanks! 谢谢!

Might as well write this as an answer I suppose. 最好将其写为我想的答案。

The issue you describe is documented here: https://bugs.php.net/bug.php?id=60826 您描述的问题记录在这里: https : //bugs.php.net/bug.php?id=60826

Highlights from the thread: 主题集锦:

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). 如果您发送了分块的http请求,但没有发送内容长度(如我们应该使用HTTP 1.1协议那样),则请求的正文部分为空(php:// input不返回任何内容)。 This result remains valid for the following configuration where PHP runs via FastCGI : 对于以下通过FastCGI运行PHP的配置,此结果仍然有效:

The same configuration with PHP running as mod_php is fine, the body request is available through php://input. 与运行mod_php的PHP相同的配置很好,可以通过php:// input获得主体请求。

And

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. 本质上,PHP遵循规范,并且读取的内容不超出FastCGI CONTENT_LENGTH标头值-因此,在FastCGI或Web服务器实现中,正确的修补程序必须高于PHP。

Possible Workarounds: 可能的解决方法:

0) Use httpd with mod_php 0)将httpd与mod_php一起使用

1) Use a different web server. 1)使用其他Web服务器。

2) Look at patches for mod_fcgid 2)查看mod_fcgid的补丁

3) Maybe (not recommended) flip always_populate_raw_post_data and see if there is anything in $HTTP_RAW_POST_DATA 3)也许(不建议)翻转always_populate_raw_post_data并查看$ HTTP_RAW_POST_DATA中是否有任何内容

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM