Dalla tua vaga descrizione, I supponiamo che il tuo codice raccolga qualsiasi cosa il server risponda come una grande sequenza di byte, quindi interpreta i byte come se fossero < em> stringa di caratteri nul-terminata , quindi tenta di trovare una sequenza CR + LF al suo interno.
Questo è sbagliato a molti livelli. Prima di tutto, i byte non sono necessariamente una stringa di caratteri , e potrebbero, in particolare, mancare dello zero di chiusura. Inoltre, mentre l'intestazione HTTP consiste in righe che terminano con CR + LF e termina su una riga vuota (cioè un CR + LF subito dopo il precedente CR + LF), nulla impedisce al corpo di risposta di contenere anche sequenze CR + LF. Infine, c'è una cosa chiamata codifica del contenuto che è il modo in cui i contenuti della risposta sono codificati in byte. Con HTTP , ci sono principalmente quattro codifiche per il corpo della risposta:
-
Nessun corpo di risposta. Dipende dal tipo di risposta. Ad esempio, i tipi 204 e 304 non hanno un corpo.
-
Lunghezza esplicita. Un'intestazione Content-Length
specifica la lunghezza del corpo, in byte .
-
Lunghezza implicita. Il corpo si estende fino alla fine della connessione di trasporto. Quando viene utilizzata la lunghezza implicita, la risposta non può, per definizione, essere seguita sulla stessa connessione con un'altra risposta per un'altra richiesta.
-
Codifica Chunked. Il corpo è diviso in blocchi; ogni pezzo ha le sue dimensioni, dato come intestazione di un chunk. Questo è descritto nella sezione 3.6.1 . Non esiste una dimensione massima standard per un blocco. La codifica Chunked supporta anche un "trailer", ovvero linee di intestazione HTTP aggiuntive dopo i dati.
La linea di fondo è che non dovresti provare a trovare sequenze CR + LF direttamente in alcuni byte. Quello che dovresti fare è il seguente:
- Utilizzare una libreria HTTP che fornisce la risposta come flusso; per esempio. LibSoup (Suppongo che dal tuo uso di
g_strstr_len()
tu usi Glib; LibSoup è una libreria HTTP GNOME progettata per funzionare bene con Glib).
- Leggi i dati di risposta, come previsto dalla libreria, come piccoli pezzi (ad esempio, per un massimo di 8192 byte, un valore molto tradizionale). Non preoccuparti di pensare a "pezzi" come visto sul filo; questo è il lavoro della libreria HTTP, non la tua.
- Conta i byte mentre li leggi. Suppongo che tu voglia accumulare questi byte da qualche parte nella RAM, ad es. in un array, per ulteriori elaborazioni. Assicurati di applicare un limite di dimensioni: se il corpo della risposta sembra essere più grande di un valore massimo previsto (che dipende da ciò che desideri), quindi elimina altri byte e segnala un errore.
In questo modo otterrai la lunghezza della risposta e anche la risposta, pur mantenendo le dimensioni della memoria controllata: una risposta eccessiva non consentirà al tuo codice di allocare una parte enorme della RAM. Questo sarà anche compatibile con i vari tipi di codifica. In ogni caso, DEVE leggere la risposta completa ad un certo punto: a meno che non sia inclusa un'intestazione Content-Length
esplicita, non c'è modo di conoscere la lunghezza della risposta senza leggerla tutta; e la lettura della risposta completa è importante per consentire a una risposta successiva di utilizzare la stessa connessione TCP.
In questo senso, gli attacchi relativi alle dimensioni del blocco funzionano solo contro software mal scritti che insistono nell'assegnare i blocchi RAM in base alle dimensioni inviate dal peer e senza alcuna protezione contro i dati "assurdi". Se si desidera implementare un codice di rete appropriato e non troppo vulnerabile, avere deve essere un po 'difensivo sui dati ricevuti, che devono essere considerati come ostili di default fino a quando non si dimostrano benigni. Non devi aspettarti che il server ti invii sempre dei bei caratteri ASCII in messaggi ben strutturati. Ottieni i byte e puoi ottenere qualsiasi byte, sia in quantità che in contenuto. L'utilizzo di una libreria progettata per l'HTTP risolverà i problemi di codifica, facendo quindi la metà di questo lavoro difensivo.