PHP (Apache) безмолвно преобразует HTTP 429 и другие в 500

Я только что обнаружил странность в методе header () PHP, который молча конвертировал некоторые из моих статусов в 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" 

Все работает нормально при тестировании со многими другими кодами состояния, такими как 401, 420, 426.

Все работает отлично, если я явный и отправляю заголовок («HTTP / 1.1 429 слишком много запросов»); Это было бы полезным решением, за исключением того, что я использую Zend Framework, а метод setHttpResponseCode ожидает целое число, которое он использует в качестве третьего параметра для функции header () php.

С тех пор я обнаружил, что он, похоже, относится к статусам, добавленным в 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 года. Один год для 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