it-swarm.com.de

HTTP Range Header

Ich las http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.35 Und versuchte herauszufinden, wie ein Dateidownload fortgesetzt werden kann.

Angenommen, eine Datei hat eine Länge von 100 Byte und ich habe alle 100 Byte. Ich weiß jedoch nicht, wie groß die erwartete Dateigröße sein sollte. Daher frage ich nach der Datei und gebe einen Range-Header an, der folgendermaßen aussieht:

Range: bytes=100-

Ist dies eine gültige Range-Anfrage?

71
dhruvbird

Es ist eine syntaktisch gültige Anfrage, aber keine zufriedenstellende Anfrage. Wenn Sie in diesem Abschnitt weiterblicken, sehen Sie:

Wenn ein syntaktisch gültiger Bytebereichssatz mindestens eine Bytebereichspezifikation enthält, deren erste Byteposition kleiner als die aktuelle Länge des Entitätskörpers ist, oder mindestens eine Suffixbytebereichspezifikation mit einem nicht - Nullsuffixlänge, dann ist der Bytebereichssatz zufriedenstellend. Ansonsten ist das Byte-Range-Set nicht erfüllbar. Wenn das Byte-Range-Set nicht zufriedenstellend ist, SOLLTE der Server eine Antwort mit dem Status 416 (angeforderter Bereich nicht zufriedenstellend) zurückgeben . Andernfalls sollte der Server eine Antwort mit dem Status 206 (Partial Content) zurückgeben, die die erfüllbaren Bereiche des Entitätskörpers enthält.

Ich denke also, in Ihrem Beispiel sollte der Server eine 416 zurückgeben, da dies kein gültiger Bytebereich für diese Datei ist.

50
Marc Novakowski

Wie Wrikken vorgeschlagen, handelt es sich um eine gültige Anfrage. Dies ist auch üblich, wenn der Client Medien anfordert oder einen Download fortsetzt. 

Ein Client prüft häufig, ob der Server Fernabfragen verarbeitet, es sei denn, er sucht lediglich nach einer Accept-Ranges-Antwort. Chrome immer sendet einen Range: bytes=0- mit der ersten GET-Anforderung für ein Video. Dies ist etwas, das Sie nicht abweisen können.

Immer, wenn ein Client Range: in seine Anfrage einfügt, erwartet er, selbst wenn er fehlerhaft ist, eine teilweise Antwort (206) des Inhalts. Wenn Sie während der Wiedergabe von HTML5-Videos vorwärts suchen, fordert der Browser nur den Startpunkt an. Zum Beispiel:

Range: bytes=3744-

Damit der Client das Video ordnungsgemäß abspielen kann, muss Ihr Server in der Lage sein, diese unvollständigen Bereichsanforderungen zu verarbeiten. 

Sie können den Typ des Bereichs, den Sie in Ihrer Frage angegeben haben, auf zwei Arten behandeln:

Zuerst könnten Sie mit dem in der Antwort angegebenen Startpunkt antworten, dann die Gesamtlänge der Datei minus eins (der angeforderte Bytebereich ist nullindiziert). Zum Beispiel:

Anfordern:

GET /BigBuckBunny_320x180.mp4 
Range: bytes=100-

Antwort:

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

Zweitens könnten Sie mit dem in der Anforderung angegebenen Startpunkt und einer offenen Dateilänge (Größe) antworten. Dies gilt für Webcasts oder andere Medien, deren Gesamtlänge unbekannt ist. Zum Beispiel: 

Anfordern:

GET /BigBuckBunny_320x180.mp4
Range: bytes=100-

Antwort:

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

Tipps:

Sie müssen immer mit der Inhaltslänge antworten, die im Bereich enthalten ist. Wenn der Bereich mit Anfang bis Ende abgeschlossen ist, ist die Inhaltslänge einfach der Unterschied:

Anfrage: Bereich: Bytes = 500-1000

Antwort: Inhaltsbereich: Bytes 500-1000/123456

Denken Sie daran, dass der Bereich nullindiziert ist, daher fordert Range: bytes=0-999 tatsächlich 1000 Bytes an, nicht 999, also antworten Sie mit etwas wie:

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

Oder:

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

Vermeiden Sie jedoch die letztere Methode, da einige Mediaplayer versuchen, die Dauer anhand der Dateigröße herauszufinden. Wenn es sich bei Ihrer Anfrage um Medieninhalte handelt, was meine Vermutung ist, sollten Sie deren Dauer in die Antwort aufnehmen. Dies geschieht mit folgendem Format:

X-Content-Duration: 63.23 

Dies muss ein Fließkomma sein. Im Gegensatz zu Content-Length muss dieser Wert nicht genau sein. Es wird verwendet, um dem Player beim Suchen des Videos zu helfen. Wenn Sie einen Webcast streamen und nur eine ungefähre Vorstellung davon haben, wie lange es dauern wird, sollten Sie Ihre geschätzte Dauer angeben, anstatt sie ganz zu ignorieren. Für einen zweistündigen Webcast könnten Sie Folgendes hinzufügen:

X-Content-Duration: 7200.00 

Bei einigen Medientypen, z. B. Webm, müssen Sie auch den Inhaltstyp angeben, z.

Content-Type: video/webm 

All dies ist notwendig, damit die Medien ordnungsgemäß abgespielt werden können, insbesondere in HTML5. Wenn Sie keine Dauer angeben, versucht der Player möglicherweise, die Dauer (um die Suche zuzulassen) anhand der Dateigröße herauszufinden. Dies ist jedoch nicht genau. Dies ist in Ordnung und für Webcasts oder Live-Streaming erforderlich, jedoch nicht ideal für die Wiedergabe von Videodateien. Sie können die Dauer mit einer Software wie FFMPEG extrahieren und in einer Datenbank oder sogar im Dateinamen speichern.

X-Content-Duration wird zugunsten von Content-Duration auslaufen, also würde ich das auch berücksichtigen. Eine grundlegende Antwort auf eine "0-" -Anforderung würde mindestens Folgendes umfassen:

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

Noch ein Punkt: Chrome startet seine erste Videoanforderung immer mit den folgenden:

Range: bytes=0-

Einige Server senden eine reguläre 200-Antwort als Antwort, die sie akzeptiert (jedoch mit eingeschränkten Wiedergabemöglichkeiten). Versuchen Sie jedoch, eine 206 zu senden, um anzuzeigen, dass Ihr Server Bereiche behandelt. RFC 2616 gibt an, dass Bereichsheader ignoriert werden dürfen.

127
Victor Stoddard

Im Gegensatz zu Mark Novakowskis Antwort, die aus irgendeinem Grund von vielen Leuten bestätigt wurde, ist dies eine gültige und befriedigende Anfrage.

In der Tat ist der Standard, wie Wrikken hervorgehoben hat, ein solches Beispiel. In der Praxis reagiert Firefox wie erwartet auf Anfragen (mit einem 206-Code), und genau das verwende ich, um progressiven Download zu implementieren, das heißt, ich bekomme nur den Schwanz einer langen Protokolldatei, die in Echtzeit mit dem Polling wächst.

7
user3198011

Für Leute, die im Jahr 2019 über Victor Stoddards Antwort stolpern und hoffnungsvoll werden und die Augen sehen, beachten Sie Folgendes:

a) Die Unterstützung für X-Content-Duration wurde in Firefox 41 entfernt: https://developer.mozilla.org/en-US/docs/Mozilla/Firefox/Releases/41#HTTP

b) Ich denke, es wurde nur in Firefox für .ogg-Audio und .ogv-Video unterstützt, nicht für andere Typen.

c) Ich kann nicht erkennen, dass es jemals in Chrome unterstützt wurde, aber das ist vielleicht ein Mangel an Recherche meinerseits. Aber seine Anwesenheit oder Abwesenheit scheint in Web 71 oder OVV-Videos ab heute in Chrome 71 keine Wirkung zu haben.

d) Ich kann nirgendwo etwas finden, wo "Content-Duration" durch "X-Content-Duration" ersetzt wurde. Ich glaube nicht, dass "X-Content-Duration" lange genug gelebt hat, um einen Nachfolger-Header-Namen zu erhalten.

Ich denke, das bedeutet, dass Sie ab heute webm- oder ogv-Container bereitstellen möchten, die Streams enthalten, deren Dauer nicht bekannt ist (z. B. die Ausgabe einer ffpeg-Pipe) für Chrome oder FF, und Sie möchten, dass diese in scrubbable sind Als HTML 5-Videoelement haben Sie wahrscheinlich kein Glück. Firefox 64.0 unternimmt einen halbherzigen Versuch, diese Scrubbable unabhängig davon zu machen, ob Sie über Bereichsanfragen dienen oder nicht, aber es wird verwirrt und wirft ein sich drehendes Rad hoch, bis der Stream vollständig heruntergeladen ist, wenn Sie ein paar Mal mehr suchen, als er für angemessen hält. Chrome probiert es nicht einmal aus, es verzichtet nur darauf und lässt Sie überhaupt nicht schrubben, bis der gesamte Stream beendet ist das Abspielen von.

0
Chris McDonough