2013-07-18 8 views
10

Ich habe gerade eine Kuriosität in der header() - Methode von PHP entdeckt, die einige meiner Status stillschweigend in 500 konvertiert. Ich hatte kein Glück, dieses Verhalten in verschiedenen Websuchen zu finden Ich füge das hier hinzu in der Hoffnung, anderen Ärger zu ersparen, aber auch zu fragen, ob jemand eine bessere Problemumgehung entdeckt hat (entweder mit PHP oder mit Zend1), als ich es mir ausgedacht habe.PHP (Apache) konvertiert unbeaufsichtigt HTTP 429 und andere zu 500

Da ein einfacher PHP-Skript wie:

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

ich erwarten würde, wie etwas zu erhalten:

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 

Stattdessen es gibt tatsächlich:

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 

auf das Geheimnis Hinzufügen , es gibt keine Ereignisse in meinem Apache Fehlerprotokoll und das Zugriffsprotokoll zeigt den korrekten Statuscode (also di fferent von dem, was an den Browser gesendet wurde):

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

Alles funktioniert gut, wenn sie mit vielen anderen Statuscodes wie 401 zu testen, 420, 426.

Alles funktioniert auch gut, wenn ich explizit bin und senden Header ('HTTP/1.1 429 Zu viele Anfragen'); Dies wäre eine nützliche Problemumgehung, außer dass ich Zend Framework verwende und seine setHttpResponseCode-Methode eine ganze Zahl erwartet, die sie als dritten Parameter der php-Funktion header() verwendet.

Ich habe festgestellt, dass es scheint speziell für Status in RFC 6585 (siehe https://github.com/php/php-src/pull/274) hinzugefügt, obwohl ich ein wenig verwirrt bin, warum Status wie 426 arbeiten, wenn sie eindeutig nicht im Quellcode für vorhanden sind 5.4.14 und 5.4.16 (die beiden Versionen, gegen die ich getestet habe), aber nicht-funktionale wie 429 sind.

Update:

Wie Antworten angegeben haben, ist dies meist ein Apache-Problem, nicht PHP, habe ich den Titel entsprechend aktualisiert. Am interessantesten scheint zu sein, dass dies nur in bestimmten Versionen von Apache behoben wird (ohne offensichtliche Übereinstimmung zwischen alt und neu). Ich glaube, das Upstream-Problem in Frage ist hier: https://issues.apache.org/bugzilla/show_bug.cgi?id=44995

+0

als Referenz, hier ist ein Link Das Zeigen der 429 ist eindeutig in der PHP-Quelle vorhanden: https://github.com/php/php-src/blob/PHP-5.4.14/sapi/cgi/cgi_main.c#L388 –

+1

FWIW Ich kann dies nicht dupieren der eingebaute Dev-Server in 5.4.16. Sie testen mit Apache, oder? – Charles

+1

gibt es auch einen Parameter, um den Rückkehrcode zu setzen. Hast du das schon probiert? Auch ein Skript, das viele der Codes, die gerade von 100 bis 499 Schrittgröße beginnen, permutiert, wäre gut zu wissen, welche möglich sind und welche nicht. Bitte teilen Sie auch den verwendeten Webserver und die verwendete Version sowie den PHP SAPI mit, damit der Kontext klar ist. – hakre

Antwort

5

Es ist Apache, 99% sicher, ich kann es nicht finden direcly darin docs ist, aber ich kann es aus dem Test ableiten unten (Apache-Version 2.2.22)

Fügen Sie diese in Ihre config:

ErrorDocument 429 Aaargh to heavy 

Restart:

$ 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 auch seems a recent addition in rfc6585, Status: vorgeschlagen, Datum: April 2012. Ein Jahr alt für HTTP RFCs ist ... nur ein Baby in meiner Erfahrung. Fügen Sie dazu den Prozess, um es in Apache, und dann in Ihrem Paket-Repositories ... Nun, Sie könnte versuchen Apache 2.4 ...

+0

'aber ich kann daraus schließen '- hast du vergessen einen Link hinzuzufügen? – DaveRandom

+0

Ähm, nein, aus dem Zeug, das folgt .... Das Apache verbläßt, wenn ich versuche, 429 in einem 'ErrorDocument' Kontext zu verwenden. – Wrikken

+1

Ja, das scheint tatsächlich das Problem zu sein. Ich überprüfte PHP eingebauten Webserver und es gibt das 429 korrekt zurück. Es ist schade, dass ich auf 2.2.x feststecke. Zeit, Pläne für die Migration auf nginx zu beschleunigen. –

3

Es ist vielleicht Ihre SAPI-Konfiguration.Letztes Mal habe ich etwas ähnliches getestet, sah den Abschluss wie folgt aus:

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

, die in Ihrem Fall für mich noch gut funktioniert (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 
+0

Hm, gleiche Version (2.2.22) hier funktioniert weder php als modul noch als 'cgi-fcgi' .... könnte es unter Windows einen Vorteil haben? – Wrikken

+0

@Wrikken: Nun, unter Windows kann ich nicht "*" in URLs haben, auch wenn es gültig ist. Apache macht irgendwie viel magisches Zeug, aus nicht ganz einem Grund fühlt es sich an wie ...: / – hakre