2012-12-04 11 views
8

Ho un'applicazione PHP (PHP 5.3.2) in esecuzione su Apache (2.2.14) su server Linux. Più di una volta nella sua storia l'utente ha iniziato a vedere nei propri browser il seguente messaggio: "Richiedi entità troppo grande". La prima ricerca su google ha suggerito che si verifica quando un file caricato è troppo grande o quando i cookie sono troppo grandi. Ma non sta accadendo sul caricamento dei file, solo al momento del login e sempre nella pagina di accesso. L'utente inserisce questa pagina solo attraverso un normale modulo POST su una pagina. E i cookie contengono solo ID di sessione.Apache, PHP Lunghezza del contenuto non valida

Inoltre, apache sta registrando "Lunghezza del contenuto non valida". Questo viene registrato prima dell'esecuzione del mio codice. $ _POST è vuoto nonostante debba contenere alcuni dati. Quando ho aggiunto la seguente riga:

error_log("Content-Length: ".$_SERVER['CONTENT_LENGTH']); 

si dice

Content-Length: 32, 32 

che sembra essere davvero valido. Cambiare browser o resettare il PC dell'utente non sembra essere d'aiuto. Tutto ha appena iniziato a funzionare il giorno dopo.

Dove si trova il problema? È qualcosa con Apache, PHP, le impostazioni di rete dell'utente? Se ho bisogno di aggiungere qualche altra informazione, per favore fatemelo sapere.

+1

Forse [questa risposta] (http://stackoverflow.com/questions/1361451/get-size-of-post-request-in-php#3259068) può essere d'aiuto. – Wh1T3h4Ck5

+0

Stavo provando alcune di queste opzioni ma senza risultati. Ad esempio strlen (file_get_contents ('php: // input')) è 0. – PWojnar

+1

Prova: 'strlen (file_get_contents ('php: // stdin'))' invece – Dale

risposta

2

Il modo più semplice per esaminare problemi di questo tipo è utilizzare TCPDump per acquisire i pacchetti inviati tra il client e il server in un file e quindi utilizzare Wireshark per visualizzare i pacchetti come un flusso TCP.

Un esempio del comando per acquisire i pacchetti sarebbe.

tcpdump -vvv -A -i eth0 'ospite 123.123.10.12 & & porta 80' w eth0.dat

Come è la vostra pagina di login, si avrà probabilmente bisogno di decodificare il flusso TCP come dovrebbe essere dietro HTTPS - che può essere fatto utilizzando le istruzioni da http://segfault.in/2010/11/decrypt-https-traffic-using-wireshark-and-key-file/

Plasmid87 è quasi certamente corretta anche se - suona come una delle intestazioni è solo crescendo in maniera massiccia e fino a diventare più grande della Apache LimitRequestFieldSize.

Fintanto che sta crescendo lentamente piuttosto che tutto in una volta, è possibile indagare controllando le variabili globali.

function checkVars(){ 
    $varsToCheck = array($GLOBALS, $_SERVER, $_GET, $_POST, $_FILES, $_REQUEST, $_SESSION, $_ENV, $_COOKIE); 

    foreach($varToCheck as $var){ 
     foreach($var as $key => $value){ 

      if(count($key) > 1024){ 
       logToFile("Found ridiculous key: ".$key." value is ".$value); 
      } 
      if(count($value) > 1024){ 
       logToFile("Found ridiculous value for key: ".$key." value is ".$value); 
      } 
     } 
    } 
} 
5

Nei giorni scorsi abbiamo rilevato messaggi "Lunghezza del contenuto non valido" registrati da Apache in error_log. rintracciato il problema per qualche visitatore da pochi classi IP specifici, ad esempio Movistar Argentina: 200.81.44.201 ulteriore verifica della richiesta con tcpdump/whireshark abbiamo osservato che la richiesta POST conteneva alcuni

duplicate Headers, namely Content-Length and Content-Type

Il vero problema è con Content-Length, perché Apache trattare più variabili, da loro concatenazione, per esempio:

Content-Length: 51 
Content-Length: 51 

Il risultato sarà:

Content-Length: 51, 51 

Quindi Apache prova a convertire la stringa "51, 51" in un numero intero che non è possibile. Nella versione più recente di Apache> 2.2.17, o con patch backported Apache registra un errore: 413 Richiesta Entità troppo grande, con Apache più vecchio, il processo richiede solo un sacco di tempo CPU. Dietro questa classe IP vediamo client più distinti, quindi forse sono server proxy gateway 3G erroneamente configurati, perché duplicano le intestazioni. Così troviamo una soluzione per configurare Apache per riscrivere la richiesta con un solo Content-Length e un Content-Headers: Ecco il mio codice per questo, utilizzando mod_headers, e SetEnvIfNoCase inserito in httpd.conf:

SetEnvIfNoCase Content-Length (.*), MyContentLength=$1 
SetEnvIfNoCase Content-Type (.*), MyContentType=$1 
RequestHeader set Content-Length: "%{MyContentLength}e" env=MyContentLength 
RequestHeader set Content-Type: "%{MyContentType}e" env=MyContentType 

Sei libero di testare e utilizzare questo codice per filtrare le variabili di intestazione HTTP Content-Length duplicate.

Problemi correlati