PHP(Apache)静默地将HTTP 429和其他转换为500

ex-*_*erd 10 php apache http-headers http-status-code-429

我刚刚在PHP的header()方法中发现了一个奇怪的地方,默默地将我的一些状态转换为500.由于我在各种网络搜索中没有找到提及这种行为的运气,我在这里添加它是为了拯救他人一些恶化,还要询问是否有人发现了一个比我想出的更好的解决方法(使用PHP或Zend1).

给出一个简单的PHP脚本,如:

<?php
header('HTTP/1.1 429');
echo "Too Many Requests\n";
Run Code Online (Sandbox Code Playgroud)

我希望得到类似的东西:

HTTP/1.1 429
Date: Thu, 18 Jul 2013 22:19:45 GMT
Content-Length: 11
Content-Type: text/html; charset=UTF-8

Too Many Requests
Run Code Online (Sandbox Code Playgroud)

相反,它实际上返回:

HTTP/1.1 500 Internal Server Error
Date: Thu, 18 Jul 2013 22:19:45 GMT
Content-Length: 11
Content-Type: text/html; charset=UTF-8

Too Many Requests
Run Code Online (Sandbox Code Playgroud)

除此之外,我的apache错误日志中没有事件,访问日志显示正确的状态代码(因此与发送到浏览器的内容不同):

$IP - - [18/Jul/2013:16:31:34 -0700] "GET /test/429.php HTTP/1.1" 429 11 "-" "curl/7.30.0"
Run Code Online (Sandbox Code Playgroud)

使用许多其他状态代码(如401,420,426)进行测试时,一切正常.

如果我是明确的并发送标题('HTTP/1.1 429 Too Many Requests'),一切也可以正常工作; 这将是一个有用的解决方法,除了我使用Zend Framework并且其setHttpResponseCode方法需要一个整数,它用作php的header()函数的第三个参数.

我已经发现它似乎特别适用于RFC 6585中添加的状态(请参阅https://github.com/php/php-src/pull/274),尽管我有点困惑为什么像426这样的状态工作当他们显然没有出现在5.4.14和5.4.16的源代码中(我测试过的两个版本),但是像429这样的非功能性版本.

更新:

正如答案所示,这主要是Apache问题,而不是PHP,我已相应更新了标题.最有趣的似乎是,这仅在某些版本的Apache中得到修复(旧版和新版之间没有明显的一致性).我相信有问题的上游问题在这里:https://issues.apache.org/bugzilla/show_bug.cgi?id = 44995

Wri*_*ken 5

它是Apache,99%肯定,我在它的文档中找不到它,但我可以从下面的测试推断它(Apache 2.2.22版本)

在您的配置中添加:

ErrorDocument 429 Aaargh to heavy
Run Code Online (Sandbox Code Playgroud)

重新开始:

$ sudo /etc/init.d/apache2 restart
Syntax error on line 6 of /etc/apache2/conf.d/localized-error-pages:
Unsupported HTTP response code 429
Action 'configtest' failed.
The Apache error log may have more information.
   ...fail!
Run Code Online (Sandbox Code Playgroud)

429似乎是最近才加入在rfc6585,状态:提议日期:2012年4月一岁的HTTP RFC中......只是在我的经验,一个婴儿.再加上在Apache中获取它的过程,然后在你的软件包存储库......嗯,你可以尝试Apache 2.4 ...

  • 在Apache的2.4.x分支中,似乎缺少状态代码[支持](https://github.com/apache/httpd/blob/2.4.x/modules/http/http_protocol.c#L146) [不是](https://github.com/apache/httpd/blob/2.2.x/modules/http/http_protocol.c#L129)在2.2.x中.经典的Apache还有一个[很好的演示](https://github.com/apache/httpd/blob/2.2.x/modules/http/http_protocol.c#L125)"哦,它会做的,那就行了"态度.巧合的是,[commit](https://github.com/apache/httpd/commit/81cf3a6177ce7f6a00bf99a1a15cf1546bfd35c9)几乎就在一年前的今天. (3认同)