2013-07-18 12 views
10

Właśnie odkryłem dziwność w metodzie header() w trybie cichym konwersja niektórych moich statusów na 500. Ponieważ nie miałem szczęścia w znalezieniu wzmianki o tym zachowaniu w różnych wyszukiwaniach internetowych Dodaję to tutaj, w nadziei, że uratuję inne osoby, ale także zapytam, czy ktoś odkrył lepsze obejście (z PHP lub Zend1), niż ja wymyśliłem.PHP (Apache) po cichu konwertując HTTP 429 i inne na 500

Biorąc prosty skrypt PHP jak:

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

Spodziewam się, aby otrzymać coś takiego:

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 

Zamiast faktycznie zwraca:

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 

Dodawanie do tajemnicy , nie ma żadnych zdarzeń w moim dzienniku błędów apache, a dziennik dostępu pokazuje poprawny kod statusu (czyli di fferent z co został wyrzucony do przeglądarki):

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

Wszystko działa prawidłowo podczas testowania w wielu innych kodów stanu jak 401, 420, 426.

Wszystko działa również w porządku, jeśli jestem jawny i wysłać nagłówek ("HTTP/1.1 429 Too Many Requests"); Byłoby to użyteczne obejście, oprócz tego, że używam Zend Framework, a jego metoda setHttpResponseCode oczekuje liczby całkowitej, która jest używana jako trzeci parametr funkcji header() php.

Od tamtej pory odkryłem, że wydaje się, że dotyczy to w szczególności statusów dodanych w RFC 6585 (patrz https://github.com/php/php-src/pull/274), chociaż jestem nieco zdezorientowany, dlaczego statusy takie jak 426 działają, gdy wyraźnie nie występują w kodzie źródłowym dla 5.4.14 i 5.4.16 (dwie wersje, których testowałem), ale niefunkcjonalne jak 429.

Aktualizacja:

Jak wykazały odpowiedzi, jest to głównie kwestia Apache, PHP nie, mam zaktualizowany tytuł odpowiednio. Najbardziej interesujące wydaje się, że jest to naprawione tylko w niektórych wersjach Apache (bez wyraźnej zgodności pomiędzy starymi i nowymi). Uważam, że problem, o którym mowa powyżej jest tutaj: https://issues.apache.org/bugzilla/show_bug.cgi?id=44995

+0

Dla porównania, oto link pokazując, że 429 wyraźnie istnieje w źródle PHP: https://github.com/php/php-src/blob/PHP-5.4.14/sapi/cgi/cgi_main.c#L388 –

+1

FWIW Nie mogę tego zrobić za pomocą wbudowany serwer dev w wersji 5.4.16. Testujesz używając Apache, prawda? – Charles

+1

jest również parametr do ustawienia kodu powrotu. Czy próbowałeś tego? Również skrypt, który permutuje wiele kodów zaczynających się od 100 do 499 stopni, dobrze byłoby wiedzieć, które z nich są możliwe, a które nie. Proszę również poinformować serwer WWW i wersję, której używasz, a także SAPI PHP, aby kontekst był jasny. – hakre

Odpowiedz

5

To Apache, 99% pewien, nie mogę go znaleźć direcly w to dokumenty, ale mogę wywnioskować to z poniższego testu (wersja Apache 2.2.22)

Dodaj ten w 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 również seems a recent addition in rfc6585, status: zaproponował, data: Kwiecień 2012. Jeden rok dla HTTP RFC to ... po prostu dziecko z mojego doświadczenia. Dodaj do tego proces uzyskiwania go w Apache, a następnie w repozytoriach pakietów ... Cóż, możesz może wypróbować Apache 2.4 ...

+0

'ale mogę wywnioskować z tego" - czy zapomniałeś dodać link? – DaveRandom

+0

Erm, nie, z rzeczy, które wynikają .... Że apache zaciąga się, jeśli próbuję użyć 429 w kontekście "ErrorDocument". – Wrikken

+1

Tak, to rzeczywiście wydaje się być problemem. Sprawdziłem wbudowany serwer WWW PHP i zwraca poprawnie 429. Szkoda, że ​​utknąłem na 2.2.x. Czas przyspieszyć plany migracji do nginx. –

3

To jest prawdopodobnie twój konfigurator SAPI.Ostatni raz testowałem coś podobnego, wniosek wyglądał następująco:

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

które w danym przypadku nadal działa dobrze dla mnie (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, ta sama wersja (2.2.22) tutaj, ani php jako moduł, ani jako 'cgi-fcgi' działa .... czy może działać pod Windows ma przewagę? – Wrikken

+0

@Wrikken: Cóż, w systemie Windows nie mogę mieć "*" wewnątrz adresów URL, nawet jeśli jest on prawidłowy. Apache w jakiś sposób robi wiele magicznych rzeczy z wielu powodów, dla których czuje się jak ...: / – hakre