2013-07-18 7 views
10

Ho appena scoperto una stranezza nel metodo header() di PHP che convertiva silenziosamente alcuni dei miei stati in 500. Poiché non ho avuto fortuna nel trovare menzionare questo comportamento in varie ricerche sul web , Sto aggiungendo questo qui con la speranza di salvare qualche altro aggravamento, ma anche di chiedere se qualcuno ha scoperto una soluzione migliore (sia con PHP o Zend1) di quanto abbia pensato.PHP (Apache) conversione silenziosa di HTTP 429 e altri in 500

Dato un semplice script PHP come:

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

mi sarei aspettato di ricevere qualcosa come:

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 

Invece, in realtà ritorna:

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 

Aggiunta al mistero , non ci sono eventi nel mio log degli errori di Apache, e il log di accesso mostra il codice di stato corretto (quindi di fferent da quello ottenuto mandato al browser):

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

Tutto funziona bene durante il test con molti altri codici di stato come 401, 420, 426.

Tutto funziona bene anche se io sono esplicite e mando intestazione ('HTTP/1.1 429 troppe richieste'); Questa sarebbe una soluzione utile, tranne per il fatto che sto usando Zend Framework e il suo metodo setHttpResponseCode si aspetta un intero, che usa come terzo parametro per la funzione header() di php.

Da allora ho scoperto che sembra applicarsi in modo specifico agli stati aggiunti in RFC 6585 (vedi https://github.com/php/php-src/pull/274), anche se sono un po 'confuso perché gli stati come 426 funzionano quando chiaramente non sono presenti nel codice sorgente per 5.4.14 e 5.4.16 (le due versioni che ho testato contro) ma non funzionali come 429.

Aggiornamento:

Come risposte hanno indicato, questo è soprattutto un problema di Apache, PHP non, ho aggiornato il titolo di conseguenza. Più interessante sembra essere che questo è stato risolto solo in alcune versioni di Apache (senza apparente coerenza tra vecchio e nuovo). Credo che il problema a monte in questione è qui: https://issues.apache.org/bugzilla/show_bug.cgi?id=44995

+0

Per riferimento, ecco un link mostra chiaramente il 429 nel sorgente PHP: https://github.com/php/php-src/blob/PHP-5.4.14/sapi/cgi/cgi_main.c#L388 –

+1

FWIW Non posso duplicarlo usando il server di sviluppo integrato in 5.4.16. Stai testando con Apache, giusto? – Charles

+1

c'è anche un parametro per impostare il codice di ritorno. Hai provato quello? Inoltre, uno script che permuta molti dei codici solo a partire da 100 fino a 499 dimensioni di un passo sarebbe bene sapere quali sono possibili e quali no. Inoltre, informa il server Web e la versione che stai utilizzando, nonché il SAPI PHP in modo che il contesto sia chiaro. – hakre

risposta

5

E 'Apache, il 99% sicuro, non posso trovarlo direcly nella sua documentazione, ma posso dedurre che dal test sotto (versione di Apache 2.2.22)

Aggiungere questo nella configurazione:

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 anche seems a recent addition in rfc6585, stato: proposto, data: Aprile 2012. Un anno per RFC HTTP è ... solo un bambino nella mia esperienza. Aggiungete a ciò il processo di ottenerlo in Apache, e poi nei repository dei pacchetti ... Bene, voi potete provare Apache 2.4 ...

+0

'ma posso dedurlo da questo' - hai dimenticato di aggiungere un collegamento? – DaveRandom

+0

Ehm, no, dalle cose che seguono .... Quell'apache non va bene se provo a usare 429 in un contesto 'ErrorDocument'. – Wrikken

+1

Sì, sembra proprio che questo sia il problema. Ho controllato il web server integrato di PHP e restituisce correttamente il 429. È un peccato essere bloccato su 2.2.x. È ora di accelerare i piani per migrare a nginx. –

3

È forse la vostra configuraiton SAPI.L'ultima volta che ho provato qualcosa di simile, la conclusione si presentava così:

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

che nel tuo caso funziona ancora bene per me (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, stessa versione (2.2.22) qui, né php come modulo né come 'cgi-fcgi' funziona .... potrebbe funzionare con Windows ha un vantaggio? – Wrikken

+0

@Wrikken: Beh, in Windows non posso avere '*' all'interno degli URL anche se è valido. Apache in qualche modo fa un sacco di cose magiche per non un motivo per cui ci si sente ...: / – hakre

Problemi correlati