Frank Schönmann: Upload von Dateien zum Server

hi!

Da hier immer mal wieder die Frage aufkommt, wie man denn eine Datei über ein Perl-Skript auf dem Server empfangen lassen kann, möchte ich hier mal ein entsprechendes Skript posten, das diese Aufgabe übernehmen kann.

Zuerst der notwendige HTML-Code für das Upload-Formular:
=== cut ===
<form name="Upload" action="cgi-bin/uploadtest.pl" method="POST" enctype="multipart/form-data">
  <input type="file" name="Datei" size="30">
  <input type="submit" value="Upload starten">
</form>
=== cut ===

Und jetzt das gar nicht mal viel längere Perl-Skript:
=== cut ===
#!/usr/bin/perl

binmode STDIN;
read STDIN, $Daten, $ENV{'CONTENT_LENGTH'};

@Teile = split /-----------------------------.{9}/, $Daten;
@Datei = split /\n/, $Teile[1], 5;
while ($Datei[1] =~ /\/) { $Datei[1] =~ s/^.*\//; }
$Datei[1] =~ s/"//;
chop $Datei[1];
chop $Datei[4]; chop $Datei[4];

open DATEI, ">$Datei[1]";
binmode DATEI;
print DATEI $Datei[4];
close DATEI;

print "Content-type: text/html\n\nUpload vollständig!";
=== cut ===

Ich habe obiges zwar nur ein einziges Mal auf meinem lokalen Server getestet, aber ich hoffe, es funktioniert :-) Falls das jemand getestet hat, könnte man das Skript ja in die FAQ aufnehmen.

bye, Frank!

  1. hi!

    Da hier immer mal wieder die Frage aufkommt, wie man denn eine Datei über ein Perl-Skript auf dem Server empfangen lassen kann, möchte ich hier mal ein entsprechendes Skript posten, das diese Aufgabe übernehmen kann.

    ...

    Ich habe obiges zwar nur ein einziges Mal auf meinem lokalen Server getestet, aber ich hoffe, es funktioniert :-) Falls das jemand getestet hat, könnte man das Skript ja in die FAQ aufnehmen.

    bye, Frank!

    Hi Frank,

    hört sich ja alles ganz doll an, aber muß man dafür nicht noch tausend sachen auf dem Server einstellen? Oder wo ist das Problem??? Es kann doch nicht so einfach sein.

    Gruß

    Thomas

    1. hi!

      hört sich ja alles ganz doll an, aber muß man dafür nicht noch tausend sachen auf dem
      Server einstellen? Oder wo ist das Problem??? Es kann doch nicht so einfach sein.

      Was sollte man denn noch einstellen müssen? Wie gesagt: auf meinem Xitami lief es so wie es jetzt ist.

      bye, Frank!

      1. Hi Frank, hi alle,

        hi!

        hört sich ja alles ganz doll an, aber muß man dafür nicht noch tausend sachen auf dem
        Server einstellen? Oder wo ist das Problem??? Es kann doch nicht so einfach sein.

        Was sollte man denn noch einstellen müssen? Wie gesagt: auf meinem Xitami lief es so wie es jetzt ist.

        Ich dachte bei dem Einstellen so an Berechtigungen, damit ich Dateien auch auf der Pladde speichern kann, ich will aber die hochgeladenen Dateien nicht ausführen können (was es da alles gibt... viren und son kram ;-( ), und natürlich soll nicht jeder auf meinem Server alles schreiben dürfen, halt nur über Script...

        Oder bin ich da zu ängstlich?

        Schöne Grüße

        Thomas

        PS: entschuldigt mein unwissen, aber ich will es wissen, denn früher oder später will ich sowatt auch haben.

        1. hi!

          Ich dachte bei dem Einstellen so an Berechtigungen, damit ich Dateien auch auf der Pladde
          speichern kann, ich will aber die hochgeladenen Dateien nicht ausführen können (was es da
          alles gibt... viren und son kram ;-( ), und natürlich soll nicht jeder auf meinem Server alles
          schreiben dürfen, halt nur über Script...

          Ein CGI-Skript läuft mit der Berechtigung des Webservers, darf also normalerweise auch Dateien auf die Festplatte schreiben, und was anderes macht das Skript ja nicht, außer Daten, die vom Browser geschickt werden, in eine Datei zu schreiben.
          Wenn der Server unter Linux oder Unix läuft, kann man die Datei auch gar nicht ausführen, da man vorher die entsprechenden Attribute setzen müsste. Unter einem Betriebssystem, das aufgrund von Dateiendungen den Typ erkennt, könnte man ja einfach noch eine Endung anhängen, damit die Dateien nicht mehr ausgeführt werden können.

          bye, Frank!

  2. Hallo Frank,

    vielen Dank fuer das Posting! Werde ich mir noch mal genauer ansehen. Aber zwei Sachen sind mir gleich aufgefallen:

    1. so wie das Perl-Script geschrieben ist, darf das HTML-Formular keine anderen Daten als den File-Button enthalten.

    2. es wird weder eine Mimetype-Einschraenkung noch eine maximale Dateigroesse in HTML angegeben. Hast Du es mal mit versucht, und klappt es dann? Denn diese Dinge sind wohl jedem wichtig, der vermeiden will, dass sich unsinniger Muell auf seinem Server sammelt.

    Die Regular Expressions, mit deren Hilfe der Datei-Content aus dem Datenstrom gefiltert wird, muesste man natuerlich mal gruendlich daraufhin testen, ob sie wirklich alle denkbaren Faelle korrekt behandeln.

    Ich denke, man koennte dieses Script einfach noch ein wenig verallgemeinern (siehe 1. und 2.), und dann wuerde es auf jeden Fall in die FAQ gehoeren.

    viele Gruesse
      Stefan Muenz

    viele Gruesse
      Stefan Muenz

    1. hi!

      1. so wie das Perl-Script geschrieben ist, darf das HTML-Formular keine anderen Daten als den File-Button enthalten.

      Ich weiß... ;-))

      1. es wird weder eine Mimetype-Einschraenkung noch eine maximale Dateigroesse in HTML
        angegeben. Hast Du es mal mit versucht, und klappt es dann? Denn diese Dinge sind wohl
        jedem wichtig, der vermeiden will, dass sich unsinniger Muell auf seinem Server sammelt.

      Hier der MIME-Header einer upgeloadeten Datei:
      === cut ===
      -----------------------------95973098716269
      Content-Disposition: form-data; name="Datei"; filename="c:\command.com"
      Content-Type: application/x-unknown-content-type-comfile
      === cut ===
      Bitte verrate mir, wie ich den MIME-Typ oder die Dateigröße da rausfinden soll? *g* Ich kann zb. die Dateierweiterung überprüfen und die Größe des Skalars herausfinden, aber alleine durch den MIME-Header funktioniert das nicht, es hat also auch nichts direkt mit dem Upload-Skript zu tun.
      Vielleicht setzt mein Webserver auch einfach den falschen Content-type ein, weil ich daran nichts verändert habe. Vielleicht kannst du es mal mit einem richtigen Webserver testen, bei dem die MIME-Typen stimmen? Keine Ahnung, ob dann dort etwas anderes steht.

      Die Regular Expressions, mit deren Hilfe der Datei-Content aus dem Datenstrom gefiltert
      wird, muesste man natuerlich mal gruendlich daraufhin testen, ob sie wirklich alle denkbaren
      Faelle korrekt behandeln.

      Wie du oben am MIME-Header siehst, ist dieser immer gleich aufgebaut. Deshalb funktioniert der reguläre Ausdruck auch :-)

      Ich denke, man koennte dieses Script einfach noch ein wenig verallgemeinern (siehe 1. und
      2.), und dann wuerde es auf jeden Fall in die FAQ gehoeren.

      Zu 2. siehe meine Antwort. Zu 1. kann ich noch mal versuchen, rauszufinden, wie es funktioniert. Aber wenn jemand einfach Dateien auf seinem Server uploaden lassen will, ist es doch schonmal ein Anfang :-)

      bye, Frank!

      1. Hallo Frank,

        Bitte verrate mir, wie ich den MIME-Typ oder die Dateigröße da rausfinden soll? *g*

        Ich meinte nicht in Perl, sondern in HTML. Bei <input type=file> kannst Du ja eine Mime-Type-Einschraenkung machen, auch mit Wildcards, etwa "text/*", und eine Dateigroessenbeschraenkung mit maxlength=. Ich wollte nur wissen, ob solche Angaben "rueberkommen". Eigentlich muesste das zwar schon der Browser korrekt handeln, aber wer weiss...

        viele Gruesse
          Stefan Muenz

        1. hi!

          Bitte verrate mir, wie ich den MIME-Typ oder die Dateigröße da rausfinden soll? *g*
          Ich meinte nicht in Perl, sondern in HTML. Bei <input type=file> kannst Du ja eine
          Mime-Type-Einschraenkung machen, auch mit Wildcards, etwa "text/*", und eine
          Dateigroessenbeschraenkung mit maxlength=. Ich wollte nur wissen, ob solche Angaben
          "rueberkommen". Eigentlich muesste das zwar schon der Browser korrekt handeln, aber wer
          weiss...

          Achso. Dann ist es aber auch Aufgabe des Browsers, nicht meines Skripts, denn das Skript hat ja gar keine Möglichkeit zu erfahren, welche Eigenschaften dieses Formularfeld eigentlich hatte.

          bye, Frank!

  3. Und jetzt das gar nicht mal viel längere Perl-Skript:

    Hi,
    super dein perl-script!
    wie kann man im script ein bestimmtes upload-verzeichnis am server angeben?
    Weil sonst kommen die upgeloadeten dateien immer ins cgi-bin-Verzeichnis.

    lg,
    robert

    1. hi!

      Und jetzt das gar nicht mal viel längere Perl-Skript:
      super dein perl-script!
      wie kann man im script ein bestimmtes upload-verzeichnis am server angeben?
      Weil sonst kommen die upgeloadeten dateien immer ins cgi-bin-Verzeichnis.

      An der Stelle, an der die Datei geöffnet wird:
        open DATEI ">irgendein/verzeichnis/$Datei[1]";

      bye, Frank!