2013-03-27 11 views
7

Sto scrivendo un semplice server web in python che consente all'utente di caricare un file utilizzando multipart/form-data. Per quanto posso dire, i dati MIME multipart dovrebbero essere basati sulla linea. Ad esempio, il confine deve essere all'inizio di una linea.Linee binari in multipart/form-data (upload di file)

Non riesco a capire come vengono gestiti i dati binari in questo senso. Il mio client (Firefox) è non codificandolo in ASCII a 7 bit o altro, è solo dati binari non elaborati che sta inviando. Divide i dati in linee in posizioni arbitrarie? Esiste una lunghezza massima della linea specificata per i dati multipart? Ho provato a cercare attraverso la RFC per multipart/form-data, ma non ho trovato nulla.

risposta

7

Dopo aver scavato attraverso le RFC, penso di aver finalmente capito tutto nella mia testa. Le parti del corpo (vale a dire il contenuto corporeo di una singola parte in un messaggio multipart/*) devono essere solo basate sulla linea in quanto il limite alla fine della parte inizia con CR+LF. Altrimenti, i dati non devono essere basati sulla linea, e se il contenuto sembra avere interruzioni di riga, non c'è una distanza massima tra di loro, né devono essere sfuggiti in alcun modo (beh, a meno che non sia indicato il Content-Transfer-Encoding- stringa). Le opzioni 7-bit, 8-bit e binarie per Content-Transfer-Encoding in realtà non indicano che è stata eseguita alcuna codifica sui dati (e quindi nessuna codifica deve essere annullata), servono solo per indicare il tipo di dati puoi aspettarti di vedere nella parte del corpo.

Quello che stavo veramente ricevendo nella mia domanda [poco espressa] era come leggere/bufferare i dati dal socket in modo da essere sicuro di aver raggiunto il limite e senza dover disporre di un buffer arbitrariamente grande (ad es. , se non ci sono stati interruzioni di riga nel contenuto, e quindi un readline ha finito il buffering dell'intera cosa).

Quello che ho finito è stato il buffering dal socket con uno readline utilizzando una lunghezza massima, quindi il buffer non sarebbe mai stato più lungo di quello, ma avrebbe anche fatto in modo di terminare se si fosse verificato un interruzione di riga. Ciò ha garantito che al momento del confine (seguendo uno CR+LF), si trovasse all'inizio del buffer. Ho dovuto fare un po 'di monkeying in più per assicurarmi di non includere quell'ultimo CR+LF nel contenuto reale del corpo, perché secondo la RFC è richiesto prima del confine, e quindi non parte del contenuto stesso.

2

Prova a verificare RFC 2045. In genere, il contenuto binario viene convertito in dall'applicazione e incluso nel messaggio a più parti utilizzando "Content-Transfer-Encoding: Base64". Esistono altri meccanismi per trasferire dati binari, ma questo è abbastanza comune. I dati binari sono convertiti in ottetti e suddivisi in stringhe di lunghezza arbitary (a seconda della variante di codifica - vedere il collegamento BASE64 sopra). L'applicazione ricevente quindi la decodifica nel contenuto binario originale.

Non sono un programmatore Python, ma sarei sorpreso che tu abbia dovuto codificare tutto questo da solo. Ho il sospetto che ci siano funzioni di libreria python predefinite per fare questo per te.

+1

Grazie, stavo guardando un diverso RFC che non era così informativo. Ho anche trovato RFC 2046 che definisce in modo specifico i messaggi multiparte nella sezione 5. Notate che c'è un po 'di sottigliezza in questi RFC che attraverso me off: dice che i messaggi multipart non possono avere codifiche diverse da 7-bit, 8-bit e binari (cioè, non Base-64). Tuttavia, continua dicendo che le singole parti all'interno della multiparte possono avere le proprie codifiche del contenuto, quindi è corretto che Base-64 sia possibile. – brianmearns