File Upload multiple als verkettete Binärsequenz

Die Blobs werden einfach aneinandergehängt und die Längenangaben mitgesendet

Der hier vorliegende Artikel beschreibt eine zweckmäßige Alternative zum Content-Type: multipart/form-data womit das Hochladen mehrerer Dateien auf eine sehr performante Art und Weise ermöglicht wird. Die Idee ist sehr einfach: per File API wird über ein <input type="file" multiple id="upspot"> eine Liste von File-Objekten geliefert, die als Blob einfach aneinandergehängt werden:

    var blobs = [];
    var query = '';
    for(var i = 0; i < upspot.files.length; i++){
        blobs.push( new Blob([upspot.files[i]]) );
        query += ";size="+upspot.files[i].size;
    }

Gleichzeitig werden die dazugehörigen Längenangaben in einem QUERY_STRING kodiert der beim POST an den URL gehängt wird:

fetch('/mfup.html?multiupload=1'+query,{
    headers: new Headers({'Content-Type': 'application/body+query'}),
    method:  'POST',
    body:    new Blob(blobs)
})...

Damit der Parser weiß was zu tun ist, wird ein entsprechender Content-Type im Request-Header gesendet. Serverseitig werden die Teilsequenzen anhand der Längenangaben aus STDIN gelesen und somit die einzelnen Dateien wiederhergestellt:

    my @lens = $self->param('size');
    while( my($i, $len) = each @lens){
        read( $self->{CGI}{STDIN}, my $bin, $len);
        # hier der weitere Code was mit der Datei
        # zu tun ist.
    }
    $self->{CONTENT} = "Upload Complete!";

Benchmark Serverprozess

Der Hauptgewinn gegenüber multipart/form-data ergibt sich daraus daß der Upload-Stream nicht geparst werden muss. Der serverseitige Prozess begnügt sich damit, die Binary nur zu lesen anhand der mitgelieferten Längenangaben.

           Rate formdata   binary
formdata 20.4/s       --     -90%
binary    213/s     943%       --

Bei sinkender CPU-Lastigkeit und weniger Speicherbedarf ergibt sich ein Geschwindigkeitszuwachs um dem Faktor 10 und je nach Parser entfällt das Anlegen temporärer Dateien. Gegenüber dem Parsen mit CGI.pm ergibt sich ein Geschwindigkeitszuwachs um das 200fache!

Maximale Größe eines Uploads begrenzen

Beim Upload sendet der Browser einen HTTP Header Content-Length. Anhand dieser Längenangabe kann serverseitig entschieden werden ob der Request-Body aus STDIN gelesen werden soll oder nicht. So lässt sich die Größe eines Uploads begrenzen.

Framework Spezial: Die maximale Länge eines POST ist für jeden URL konfigurierbar und für diesen URL auf 1 Byte begrenzt. Sie können das testen indem Sie in untenstehendes Formular mehr als 1 Zeichen eingeben und auf Senden klicken.


Anbieter: nmq​rstx-18­@yahoo.de, die Seite verwendet funktionsbedingt einen Session-Cookie und ist Bestandteil meines nach modernen Aspekten in Perl entwickelten Frameworks.