Domanda

Sto cercando di valutare i pro ei contro di impostare l'intestazione HTTP Content-Length rispetto all'utilizzo di codifica Chunked per tornare [forse] file di grandi dimensioni dal mio server. Uno o l'altro è necessario per essere compatibile con HTTP 1.1 spec utilizzando connessioni persistenti. Vedo il vantaggio dell'essere intestazione Content-Length:

  • Scarica le finestre di dialogo possono mostrare accurate barra di avanzamento
  • Il cliente sa in anticipo se il file può / non può essere troppo grande per loro di ingerire

L'aspetto negativo è dover calcolare la dimensione prima di restituire l'oggetto, che non è sempre pratico e potrebbe aggiungere l'utilizzo dei server / database. L'aspetto negativo di codifica Chunked è il piccolo overhead di aggiungere la dimensione del blocco prima di ogni blocco e la barra di avanzamento del download. qualche idea? Eventuali altre considerazioni HTTP per entrambi i metodi che non si può avere pensato?

È stato utile?

Soluzione

Usa Content-Length, sicuramente. L'utilizzo dei server da questo sarà quasi inesistente e il vantaggio per gli utenti sarà grande.

Per contenuti dinamici, è anche abbastanza semplice per aggiungere il supporto risposta compressa ( gzip ). Ciò richiede buffer di uscita, che a sua volta ti dà la lunghezza del contenuto. (Non pratico con il download di file o contenuto già compresso (audio, immagini)).

Si consideri anche l'aggiunta del supporto per contenuto parziale / intervallo di byte serving - cioè, la capacità di riavviare download. Vedi qui per un intervallo di byte esempio (l'esempio è in PHP, ma è applicabile in tutte le lingue). È necessario Content-Length quando serve contenuto parziale.

Naturalmente, coloro che non sono pallottole d'argento: per lo streaming media, è inutile utilizzare il buffer di uscita o dimensione di risposta; per file di grandi dimensioni, in uscita il buffer non ha senso, ma Content-Length e serving di byte fa un sacco di senso (ricominciando un download fallito è possibile).

Personalmente, io servo Content-Length ogni volta che lo so; per il download di file, controllando la dimensione del file è insignificante in termini di risorse. Risultato:. Utente ha una barra di avanzamento determinata (e pagine dinamiche scaricare più velocemente grazie a gzip)

Altri suggerimenti

Se la lunghezza del contenuto è noto in anticipo, poi mi sarebbe certamente preferisco sopra l'invio in blocchi. Se c'è mezzo di file statici al file system del disco locale o in un database, quindi qualsiasi linguaggio di programmazione di auto-rispettato e RDBMS fornisce modi per ottenere la lunghezza del contenuto in anticipo. Si dovrebbe fare uso di esso.

D'altra parte, se la lunghezza del contenuto è davvero imprevedibile in anticipo (ad esempio quando il vostro intento è quello di comprimere più file insieme e inviarlo come uno), quindi inviarlo in blocchi può essere più veloce di buffer nella memoria o la scrittura del server al file system del disco locale in primo luogo. Ma questo in realtà impatti negativamente l'esperienza dell'utente, perché l'avanzamento del download è sconosciuto. Gli impazienti può quindi interrompere il download e si muovono lungo.

Un altro vantaggio di conoscere la lunghezza del contenuto in anticipo è la capacità di riprendere i download. Vedo nella vostra storia post che il vostro linguaggio di programmazione principale è Java; si possono trovare qui un articolo con ulteriori informazioni tecniche ed un esempio Java Servlet, che lo fa.

Content-Length

L'intestazione Content-Length determina la lunghezza in byte del corpo della richiesta / risposta. Se si trascura di specificare l'intestazione Content-Length, server HTTP saranno implicitamente aggiungere un'intestazione Transfer-Encoding: chunked. L'intestazione Content-Length e Transfer-Encoding non devono essere utilizzate insieme. Il ricevitore non hanno idea di ciò che la lunghezza del corpo e non è in grado di stimare il tempo di download di completamento. Se fate aggiungere un'intestazione Content-Length, accertarsi che corrisponda a tutto il corpo in byte, se non è corretto, il comportamento dei ricevitori non è definito.

L'intestazione Content-Length non permetterà lo streaming, ma è utile per i grandi file binari, in cui si desidera supportare contenuto parziale di servire. Ciò significa downloads ripristinabili, download in pausa, download parziali e download multihomed. Ciò richiede l'uso di un'intestazione aggiuntiva chiamata Range. Questa tecnica è chiamata Byte servire .

Transfer-Encoding

L'uso di Transfer-Encoding: chunked è ciò che permette lo streaming all'interno di una singola richiesta o risposta. Ciò significa che i dati siano trasmessi in maniera Chunked, e non influisce sulla rappresentazione del contenuto.

Ufficialmente un client HTTP ha lo scopo di inviare una richiesta con un campo di intestazione TE che specifica quali tipi di trasferimento codifiche il cliente è disposto ad accettare. Questo non è sempre inviato, tuttavia la maggior parte dei server assumono che i clienti in grado di elaborare le codifiche chunked.

Il trasferimento di codifica chunked usi meglio connessioni TCP persistenti che HTTP 1.1 assume essere vero per difetto.

Content-Encoding

È anche possibile comprimere i dati Chunked o non-chunked. Questo è praticamente fatto tramite l'intestazione Content-Encoding.

Si noti che il Content-Length è uguale alla lunghezza del corpo dopo la Content-Encoding. Questo significa che se avete gzip la risposta, allora il calcolo della lunghezza avviene dopo la compressione. Avrete bisogno di essere in grado di caricare l'intero corpo in memoria se si vuole calcolare la lunghezza (a meno che non si dispone di informazioni che altrove).

Durante lo streaming utilizzando la codifica Chunked, l'algoritmo di compressione deve supportare l'elaborazione on-line. Per fortuna, gzip supporta la compressione del flusso. Credo che il contenuto viene compresso prima, e poi tagliato a pezzi. In questo modo, i pezzi sono stati ricevuti, poi decompressi per acquisire il contenuto reale. Se fosse il contrario, si otterrà il flusso compresso, e quindi decomprimere ci darebbe pezzi. Il che non ha senso.

Una tipica risposta di flusso compresso può avere queste intestazioni:

Content-Type: text/html
Content-Encoding: gzip
Transfer-Encoding: chunked

semanticamente l'utilizzo di Content-Encoding indica un "end to end" schema di codifica, il che significa che solo il cliente finale o si suppone server di finale per decodificare il contenuto. I proxy nel mezzo non sono supponiamo di decodificare il contenuto.

Se si desidera consentire i proxy in mezzo per decodificare il contenuto, l'intestazione corretto da utilizzare è, infatti, l'intestazione Transfer-Encoding. Se la richiesta HTTP possedeva un'intestazione TE: gzip chunked, allora è legale di rispondere con Transfer-Encoding: gzip chunked.

Tuttavia, questo è molto raramente supportato. Per questo si deve usare solo Content-Encoding per la compressione al momento.

Chunked vs Store & Forward

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top