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


PHP (Apache) silently converting HTTP 429 and others to 500

我刚刚在PHP的header()方法中发现了一个奇怪的地方,它无声地将我的一些状态转换为500。由于我在各种网络搜索中都没有发现提到这种行为,我在这里添加这一点是为了避免其他人的愤怒,但也想问是否有人发现了比我想出的更好的解决方法(无论是使用PHP还是Zend1)。

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

<?php
header('HTTP/1.1 429');
echo "Too Many Requests'n";

我希望收到这样的东西:

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

相反,它实际上返回:

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

更神秘的是,我的apache错误日志中没有事件,访问日志显示了正确的状态代码(因此与发送到浏览器的代码不同):

$IP - - [18/Jul/2013:16:31:34 -0700] "GET /test/429.php HTTP/1.1" 429 11 "-" "curl/7.30.0"

当使用许多其他状态代码(如401420426)进行测试时,一切都很正常。

如果我是显式的并发送标头("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

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

将其添加到您的配置中:

ErrorDocument 429 Aaargh to heavy

重新启动:

$ 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!

429似乎也是rfc6585中的最新添加,状态:提议,日期:2012年4月。在我看来,一岁的HTTP RFC只是个婴儿。再加上在Apache中获取它的过程,然后在您的包存储库中。。。好吧,您可以尝试Apache 2.4…

这可能是您的SAPI配置。上次我测试类似的东西时,结论是这样的:

<?php
header('HTTP/ 429 Too Many Requests', false, 429);
echo "Too Many Requests'n";

在你的情况下,它对我来说仍然很好(Apache 2.2/FCGI/Windows):

>curl -i "http://local.example.com/header-test.php"
HTTP/1.1 429 Too Many Requests
Date: Thu, 18 Jul 2013 23:49:09 GMT
Server: Apache/2.2.22 (Win32) mod_fcgid/2.3.6
X-Powered-By: PHP/5.4.13
Transfer-Encoding: chunked
Content-Type: text/html
Too Many Requests