2010-07-21 11 views
67

Estaba leyendo http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.35 y tratando de encontrar la forma de continuar con la descarga de un archivo.HTTP rango encabezado

Por ejemplo, supongamos que un archivo tiene una longitud de 100 bytes y tengo todos los 100 bytes. Sin embargo, no sé cuál debe ser el tamaño de archivo esperada, por lo que pido para el archivo y especificar un encabezado Range que se parece a esto:

Range: bytes=100- 

Es ésta una solicitud rango válido?

+5

Erm, el ejemplo debajo cita 'bytes = 9500-' como válido, por lo que .... – Wrikken

+1

La referencia más reciente es RFC7233 - http://httpwg.github.io/specs/rfc7233.html –

+0

Usted puede hacer una solicitud HEAD primero y verificar la longitud del archivo. –

Respuesta

45

Es una solicitud sintácticamente válida, pero no es una solicitud satisfactoria. Si nos fijamos más en esa sección que se ve:

Si un byte-range-conjunto sintácticamente válida incluye al menos un byte-gama-spec cuyo primer byte-pos es menor que la longitud actual de la entidad- cuerpo, o al menos un sufijo-byte-rango-espec con un sufijo de longitud distinta de cero, entonces el conjunto de rango de bytes es satisfactorio. De lo contrario, el conjunto de rango de bytes no es satisfactorio. Si el conjunto de rango de bytes no es satisfactorio, el servidor DEBERÍA devolver una respuesta con un estado de 416 (el rango solicitado no es satisfactorio). De lo contrario, el servidor DEBERÍA devolver una respuesta con un estado de 206 (Contenido parcial) que contenga los rangos satisfactorios de la entidad-cuerpo.

Creo que en su ejemplo, el servidor debe devolver un 416 ya que no es un rango de bytes válido para ese archivo.

+0

Entonces, ¿hay alguna manera en que un cliente pueda reanudar una descarga sin hacer una llamada HEAD para averiguar primero la duración del contenido y luego hacer los cálculos y buscar el contenido real? Me refiero a algún tipo de direccionamiento abierto como "dame todos los bytes después de tal y tal byte ..." – dhruvbird

+5

El cliente ya sabrá si tiene todos los datos de la solicitud original - debería haber recibido un encabezado Content-Length en la respuesta original, o si se trata de codificación fragmentada, habrá recibido un fragmento de longitud cero para indicar que la respuesta se completó. Si no ha guardado este estado y solo tiene un trozo de bytes en el disco, entonces sí tendrá que hacer una solicitud HEAD o usar el encabezado Range para solicitar un rango de bytes, y si vuelve una respuesta 416 sabe que tiene todos los bytes. –

+0

Creo que Esperar-Continuar te permite hacer trozos de transmisión más o menos como deseas? – MJB

115

Como se sugirió Wrikken, es una solicitud válida. También es bastante común cuando el cliente solicita medios o reanuda una descarga.

Un cliente a menudo probará para ver si el servidor maneja las solicitudes a distancia además de simplemente buscar una respuesta Accept-Ranges. Chrome siempre envía un Range: bytes=0- con su primera solicitud GET para un video, por lo que es algo que no puede descartar.

Cuando un cliente incluye Range: en su solicitud, incluso si está mal formado, está esperando una respuesta de contenido parcial (206). Cuando busca avanzar durante la reproducción de video HTML5, el navegador solo solicita el punto de inicio. Por ejemplo:

Range: bytes=3744- 

Por lo tanto, para que el cliente para reproducir vídeo correctamente, el servidor debe ser capaz de manejar estas peticiones de rango incompletos.

Se puede controlar el tipo de 'rango' que ha especificado en su pregunta de dos maneras:

En primer lugar, usted podría responder con el punto de partida solicitada dada en la respuesta, entonces la longitud total del archivo menos uno (el rango de byte solicitado tiene índice cero). Por ejemplo:

Solicitud:

GET /BigBuckBunny_320x180.mp4 
Range: bytes=100- 

Respuesta:

206 Partial Content 
Content-Type: video/mp4 
Content-Length: 64656927 
Accept-Ranges: bytes 
Content-Range: bytes 100-64656926/64656927 

En segundo lugar, se podría responder con el punto de partida que figura en la solicitud y una longitud de archivo abierto (tamaño). Esto es para webcasts u otros medios donde la longitud total es desconocida.Por ejemplo:

Solicitud:

GET /BigBuckBunny_320x180.mp4 
Range: bytes=100- 

Respuesta:

206 Partial Content 
Content-Type: video/mp4 
Content-Length: 64656927 
Accept-Ranges: bytes 
Content-Range: bytes 100-64656926/* 

Consejos:

Usted debe responder siempre con la longitud del contenido incluido en el rango. Si el rango es completo, con el principio hasta el final, entonces la longitud del contenido es simplemente la diferencia:

Solicitud: Rango: bytes = 500-1000

Respuesta: Content-Range: bytes 500-1000/123456

Recuerde que el rango es un índice de cero, por lo que en realidad está solicitando Range: bytes=0-999 1000 bytes, no 999, por lo que responder con algo como:

Content-Length: 1000 
Content-Range: bytes 0-999/123456 

O:

Content-Length: 1000 
Content-Range: bytes 0-999/* 

Pero, evite este último método si es posible porque algunos reproductores de medios intentan determinar la duración del tamaño del archivo. Si su solicitud es para contenido multimedia, que es mi corazonada, entonces debe incluir su duración en la respuesta. Esto se hace con el siguiente formato:

X-Content-Duration: 63.23 

Debe ser un punto flotante. A diferencia de Content-Length, este valor no tiene que ser preciso. Se usa para ayudar al jugador a buscar el video. Si está transmitiendo un webcast y solo tiene una idea general de cuánto tiempo será, es mejor incluir su duración estimada en lugar de ignorarla por completo. Así, para una transmisión de dos horas, que podría incluir algo como:

X-Content-Duration: 7200.00 

Con algunos tipos de medios, tales como WebM, también debe incluir el tipo de contenido, como por ejemplo:

Content-Type: video/webm 

Todos estos son necesarios para que los medios se reproduzcan correctamente, especialmente en HTML5. Si no le da una duración, el jugador puede intentar calcular la duración (para permitir la búsqueda) de su tamaño de archivo, pero esto no será preciso. Esto está bien, y es necesario para webcasts o transmisión en vivo, pero no es ideal para la reproducción de archivos de video. Puede extraer la duración usando software como FFMPEG y guardarlo en una base de datos o incluso en el nombre del archivo.

X-Content-Duration está siendo eliminado en favor de Content-Duration, por lo que también incluiría eso. Un básico, como respuesta a una petición de "0-" incluiría al menos lo siguiente:

HTTP/1.1 206 Partial Content 
Date: Sun, 08 May 2013 06:37:54 GMT 
Server: Apache/2.0.52 (Red Hat) 
Accept-Ranges: bytes 
Content-Length: 3980 
Content-Range: bytes 0-3979/3980 
Content-Type: video/webm 
X-Content-Duration: 2054.53 
Content-Duration: 2054.53 

Un punto más: Cromo siempre comienza su primera solicitud de vídeo con lo siguiente:

Range: bytes=0- 

algunos servidores envía una respuesta regular de 200 como respuesta, que acepta (pero con opciones de reproducción limitadas), pero trata de enviar un 206 para mostrar que tu servidor maneja los rangos. RFC 2616 dice que es aceptable ignorar los encabezados de rango.

+1

¿Quién está trabajando en la definición de Contenido-Duración? ¿Enlazar? –

+0

¿Qué haces si el contenido es una transmisión de video en vivo que no tiene una duración fija? –

+0

@Joel, debe responder con una duración aunque no lo sepa. En ese caso, solo prueba 0.0. Para el cliente, la duración no importa de todos modos ya que generalmente no puede escanear una transmisión en vivo. Si el 0.0 no funciona, solo prueba algo realmente alto como 1000000.00. –

7

Contrariamente a la respuesta de Mark Novakowski, que por alguna razón ha sido votado por muchos, sí, es una solicitud válida y satisfactoria.

De hecho, el estándar, como señaló Wrikken, es solo un ejemplo. En la práctica, Firefox responde a las solicitudes como se esperaba (con un código 206), y esto es exactamente lo que uso para implementar la descarga progresiva, es decir, obtener la cola de un archivo de registro largo que crece en tiempo real con el sondeo.

+2

Lea la respuesta de Marc Novakowki nuevamente. "satisfactorio" tiene un significado particular en el RFC, que citó. Esta solicitud no es satisfactoria porque los bytes solicitados están más allá de la longitud del archivo. –

Cuestiones relacionadas