pl: Demo: JavaScript und Binärdateien, Multimedia

Beitrag lesen

Ok, jetzt weiß ich was Du mit Datei und Datenstruktur gemeint hast. Die Datei (in diesem Fall der Content des POST-Requests) ist eine physische Manifestation der clientseitigen Datenstruktur und Streamingfähigkeit bedeutet, dass der Server nicht gezwungen ist, die komplette clientseitige Struktur erstmal im RAM zu reproduzieren, sondern nur die gerade unbedingt benötigten Teile davon (Dateiname und einige KB der Datei für den nächsten Schreibzugriff in die Upload-Datei). Insofern sind Datenstruktur UND gewählte Serialisierungstechnik wichtig für eine effiziente Lösung. Wenn ich den Content zunächst in eine Hierarchie aus Hashtables lade, muss ich aber erstmal alles lesen. Das ist kein Streaming.

Streamfähig heiß, dass die Sequenz unendlich sein kann, nicht in sich geschlossen ist und somit sofort nach dem Eintreffen der ersten Bytes am Zielort mit dem Lesen begonnen werden kann. Im Fall der von mir erzeugten Datenstruktur beeinhaltet der erste 4-Byte-Big-Endian die Länge des ersten Array-Elements, egal wieviele Array-Elements noch kommen. Somit ergibt die Sequenz eine zyklische Datenstruktur wobei auch der Serializer einen bestimten Lesevorgang solange wiederholt, bis die Sequenz vollständig sequentiell abgearbeitet ist.

Zyklisch kann auch heißen: Anstatt Array-Elemente sind es Objekte. Natürlich müssen für ein Objekt ein paar mehr Bytes gelesen werden als nur vier. Siehe auch Wikipedia.

Dass CGI.pm es auch nicht macht (wobei ich keine Ahnung habe was CGI.pm ist) macht die Sache nicht besser. Kein Streaming heißt, dass ein viele parallele Uploads großer Dateien schnell den Server überlasten und einen DoS Vektor eröffnen. Deswegen hat PHP ja ein Limit für die Dateigröße bei Uploads (und PERL garantiert auch). Das Problem durch ein irgendwie geartetes Containerformat zu verschärfen, kann demnach nicht die Lösung sein.

Fakt ist, dass multipart/form-data sehr speicherintensiv und CPU-lastig ist beim Wiederherstellen der Einzelkomponenten. Warum das so ist, hab ich auf meinen Seiten ausführlich beschrieben.

Für ein im Serverseitigen Prozess zu setzendes Limit ist allein die Umgebungsvariable CONTENT_LENGTH relevant und nicht etwa die der Content-Type oder die Request-Method. Auch das ist in CGI.pm eine der Altlasten weil es dort falsch implementiert ist ( CGI.pm ist praktisch der Perl-Standard ).

Ein böser Client könnte auch mit Request-Methode 'GET' BigData im Message Boby senden und dafür einen Content-Type: text/plain deklarieren oder gar eine Request-Methode benennen, die der Server gar nicht kennt. Mit Perl oder PHP kannste solche LowLevel Clients bauen und damit Deine Serverchen testen ;)

D.h. für große Uploads, die aus JS heraus initiiert werden, muss man irgendwie die Behauptung aus dem MDN zum Fliegen bekommen, dass XMLHttpRequest auch einen FTP-Transfer kann (was lt. Google eine Herausforderung zu sein scheint und wofür man Cross-Domain Hürden überwinden muss), oder man braucht eine serverseitige URL, die hinreichend low-level verarbeitet wird, dass der Server NICHTS puffert. Das PL Framework scheint mir dafür ungeeignet. Eine PHP-Standardlösung auch. Ob in Perl oder PHP eine effiziente Lösung grundsätzlich möglich ist, kann ich nicht sagen.

Na, dann guck mal hier, das Teil ist echt der Hammer: Upload via PUT und da wird serverseitig überhaupt nichts mehr geparst -- der Content-Type im Request-Header entspricht dem Inhalt. Diese schicke Anwendung schickt also jede Datei einzeln.

Eine FTP Emulation via HTTP nach diesem Prinzip hab ich vor ein paar Jahren mal mit Perl gebaut, Du brauchst ein zweites Socket (z.B. auf einem anderen Port) damit für jeden Chunk bzw. gesendeten Puffer bei einer offenen Verbindung zurückgeliefert werden kann dass er angekommen ist. Ob ein XHR-Objekt zwei Verbindungen auf verschiedenen Ports offenhalten kann, wäre zu prüfen ;)

Teste mal meinen UploadManager, 400 Dateien hochzuladen is kein Thema und das macht die Anwendung ohne Aufsicht (unattended). Privacy ist gegeben, serverseitig speichert diese DEMO nichts.

MfG