Sequa: Datenupload via HTTP, was ist zu beachten?

Hallo Zusammen,

ich hoffe das das was ich jetzt frage nicht schonmal gefragt wurde... ich hätte ja gerne die Archive durchsucht... aber irgendwie finde ich den Link zur Suche nicht mehr... (auf der Übersichtsseite is er nimmer...).

Nun aber zu meiner Frage...
Ich möchte über ein Formular ein Bild auf den meinen Server schicken lassen... ich habe gehört das das mit Mulitpart oder sowas ähmlichem gehen soll... hab aber bisher noch nichts weiter darüber erfahren... in dem Formular werden auch gleichzeitig noch andere Daten mitgeschickt die vom Perlscript dann auch ausgewertet werden sollen (der Teil steht schon soweit...).
Ok... was genau muss ich tun damit das Bild dann auch auf dem Server gespeichert wird? Hier mal eine kleine Übersicht was alles gemacht werden soll:

Bild soll auf Größe und Dateiformat überprüft werden... wenn Bild größer als X Einheiten -> Fehlermeldung, wenn Dateiformat keinen gültigen Wert besitzt (z.b. .gif, .jpg, .jpeg oder .png) -> Fehlermeldung.
Bild soll auf Breite und Höhe untersucht werden, wenn größer als X Einheiten -> Fehlermeldung
Bild soll unter einem anderen Namen gespeichert werden (dieser wird dynamisch erzeugt), das Dateiformat soll gleich bleiben.

ok... wenn es noch weitere relevanten Daten zu dem Bild gibt (hab vielleicht welche vergessen) so würde ich diese auch gerne noch irgendwie herausfinden wollen...

Ahja, nochetwas... wie kann ich ermitteln wann eine Datei zuletzt verändert worden ist?

CU Sequa

  1. Hi,

    Ok... was genau muss ich tun damit das Bild dann auch auf dem Server gespeichert wird?

    das steht eigentlich alles in

    perldoc CGI

    Bild soll auf Größe und Dateiformat überprüft werden...

    perldoc Image::Size

    Muß evtl. installiert werden. Module gibt es immer unter http://www.cpan.org/.

    Bild soll unter einem anderen Namen gespeichert werden (dieser wird dynamisch erzeugt), das Dateiformat soll gleich bleiben.

    Kein Thema. Eine einfache RegExp reicht zur Erkennung der Dateiendung. Übrigens: Damit ist noch nichts über das Dateiformat gesagt; Du kannst eigentlich nur raten, daß nicht gelogen wird.

    ok... wenn es noch weitere relevanten Daten zu dem Bild gibt (hab vielleicht welche vergessen) so würde ich diese auch gerne noch irgendwie herausfinden wollen...

    Dateigröße?

    perldoc -f -X

    Ahja, nochetwas... wie kann ich ermitteln wann eine Datei zuletzt verändert worden ist?

    perldoc -f -X
    perldoc -f stat

    Das betrifft natürlich ausschließlich Dateien, die im Filesystem des Servers liegen. Ansonsten mußt Du schon z.B. Net::FTP benutzen (s. entsprechende Doku).

    Cheatah

    1. Hi Cheatah,

      Damit ist noch nichts über das Dateiformat gesagt; Du kannst eigentlich nur raten, daß nicht gelogen wird.

      Apropos raten, sende ich ein gefaktes "Bild"(eine nach .jpg umbenannte zip-datei) wird diese von IE5.x korrekt übergeben und im CONTENT-TYPE als application/x-zip-compressed erkannt. Die Netscape Fraktion scheint sich aber eher an der Endung zu orientieren und übergibt image/jpeg.

      Wenn der IE das nun aber richtig macht, gibt es nicht doch noch eine Möglichkeit den Korrekten Mime-Type auszulesen und kann man Netscape(leider natürlich nur auf Clientseite) überreden den korrekten Mime-Type zu senden. Ich meine, auf dem Mac muss er das Ding ja auch ohne Endung erkennen können, oder sendet er da permenent application/octet-stream??(ich kanns nicht testen).

      Danke für's Nachdenken.

      Bye Ed X

      1. Moin,

        Damit ist noch nichts über das Dateiformat gesagt; Du kannst eigentlich nur raten, daß nicht gelogen wird.
        Apropos raten, sende ich ein gefaktes "Bild"(eine nach .jpg umbenannte zip-datei) wird diese von IE5.x korrekt übergeben und im CONTENT-TYPE als application/x-zip-compressed erkannt. [...]

        ich frage mich, was wohl der IE raet, wenn ich eine Textdatei (.txt) uebergebe, wo folgendes drinsteht:

        === cut ===
        <?xml version="1.0" ?>
        <html>
        <head></head>
        <body>
        Diese Datei heisst 'plain.txt'. Und soll auch als text/plain gesendet werden.
        </body>
        </html>
        === cut ===

        Ich koennte wetten, der IE luegt bei dieser Datei ;)

        Wenn der IE das nun aber richtig macht, [...]

        wohl kaum, der IE macht es *nicht* richtig. Er raet und nichts anderes machen die anderen Browser, die sich auf die Dateiendung verlassen. In einem Filesystem, welches soetwas wie MIME-Types nicht unterstuetzt, bleibt einem eh nichts anderes uebrig. (nicht, dass die MIME-Types stimmen muessten ;)
        IMHO ist die Dateiendung derzeit noch die sinnvollste Moeglichkeit, auf den Inhalt zu schliessen (im Dateisystem wohlgemerkt, fuer HTTP *gibts* Content-types und die sollten auch genutzt werden, was der IE beispielsweise ueberhaupt nicht macht!)

        Danke für's Nachdenken.

        hehe, kein Problem ;)

        Viele Gruesse,

        n.d.p.

        1. Hi,

          IMHO ist die Dateiendung derzeit noch die sinnvollste Moeglichkeit, auf den Inhalt zu schliessen (im Dateisystem wohlgemerkt,

          ACK.

          fuer HTTP *gibts* Content-types und die sollten auch genutzt werden,

          s/sollten/müssen/

          Ansonsten ist es kein HTTP mehr, sondern ChaosTTP.

          was der IE beispielsweise ueberhaupt nicht macht!)

          Für mich ein Grund, ihm die Bezeichnung "Browser", als Gruppe von "HTTP-Client" abzusprechen :-)

          Cheatah

      2. Hi auch!

        In Ergaenzung zu n.d. moechte ich noch sagen:

        Apropos raten, sende ich ein gefaktes "Bild"(eine nach .jpg umbenannte zip-datei) wird diese von IE5.x korrekt übergeben und im CONTENT-TYPE als application/x-zip-compressed erkannt.

        Nein, das ist nicht korrekt.

        Die Netscape Fraktion scheint sich aber eher an der Endung zu orientieren und übergibt image/jpeg.

        Nein, das mit dem HTTP funktioniert so: Der einzige, der wissen kann, welcher Art eine Datei ist, ist der Web*server*. Weil der Browser diese Information braucht, um die Daten richtig darstellen zu koennen, teilt der Server dem Browser diesen "Datentyp" mit dem Content-type Header mit. Der Wert in diesem Header (das was nach dem Doppelpunkt kommt) ist der MIME-Typ der Daten. Das, und nur das, gibt an, was das fuer Daten sind, und somit kann der Browser reagieren und sozusagen das entsprechende Anzeigemodul herauskramen.

        Nun kommt aber der IE (seit Version 5) her, und meint, saemtliche Administratoren dieser Welt sind zu doof, ihren Webserver richtig zu konfigurieren, und schicken deswegen am laufenden Band falsche MIME-Types mit. Deshalb muss nach Meinung von M$ auf Clientseite ueberprueft werden, wie die Daten ungefaehr aussehen und sich dementsprechend ein eigener MIME-Type ausgedacht werden (wie dies genau von statten geht, steht auf http://msdn.microsoft.com/workshop/networking/moniker/overview/appendix_a.asp. Wie sinnvoll das ist, muss ich wohl nicht weiter kommentieren.

        Und nun ist es also in Deinem Beispiel offenbar so, dass Netscape vom Server den Type image/jpeg gemeldet bekommt, und IE natuerlich auch, und Netscape tut, was er tun soll, naemlich versuchen das Bild anzuzeigen, IE aber erstmal die Daten untersucht und sich selber was dazu ausdenkt. Dass der gemeldete Typ nun image/jpeg ist, das liegt tatsaechlich an der Dateiendung, weil naemlich der *Server* so konfiguriert ist, fuer Dateien mit dieser Endung eben diesen Typ zu melden. Leider hat er kaum eine andere Chance, hoechstens indem er selber in der Art von IE die Daten begutachtet (http://httpd.apache.org/docs/mod/mod_mime_magic.html), was allerdings recht performancelastig ist. Hier waere fuer mich die logische Folgerung, den MIME-Type mit im Dateisystem zu speichern, mir ist jedoch kein Filesystem bekannt, das das tatsaechlich macht.

        So, und jetzt hab ich verdammten Hunger und keine Lust mehr, weiterzuschreiben, und geh zur Doenerbude, weil ich seit gestern abend noch nix gegessen hab. *g*

        So long

        1. Hi Calocybe und n.d. parker!

          Erstmal danke für die Antworten. Offensichtlich habe ich mich etwas fehlerhaft ausgedrückt: es geht hier ja um Upload. Und deshalb meine ich das was in dem Datenstrom steht, welchen der CLient an den Server schickt.

          Wenn ihr Böcke habt das zu vertiefen, ihr braucht nur kopieren:

          <-----------schnipp------------------>

          #!f:/copyprog/perl56/bin/perl.exe

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

          ($boundary = $ENV{CONTENT_TYPE}) =~ s/^(.+)boundary=//;

          @Teile = split /--$boundary/, $Daten;
          foreach $part (@Teile)
            {
            # Eingangsrattenschwanz abschneiden
            $part =~ s/(Content-Disposition: form-data; name=")//;
            # aufteilung in namen und inhalt
            ($name, $part) = split(/"/, $part, 2);
            # entfernt fuehrende und endende whitspaces aus namen und part
            $name =~ s/\s*//;
            $part =~ s/^\s*//;
            $part =~ s/\s{2}$//;
            # ist dies ein teil der ein Attachement enthaelt??????
            if ($part =~ /filename/)
             {
             $namefeld = $name;
             # extrahiere den filename, mimetype, file
             ($filename, $mimetype) = split(/Content-Type: /i, $part, 2);
             ($mimetype, $file)  = split(/\n/, $mimetype, 2);

          # isolate filename
             ($filename) = ($filename =~ /"(.*)"/);
             while ($filename =~ /\/) { $filename =~ s/^.*\//; }

          $mimetype =~ s/\s*$//;
             # removes the leading whitespaces from the actual filecontent
             $file =~ s/^\s{2}//;
             }
            }

          return the infos

          print "Content-type: text/html\n\n";
          print "<HTML>\n";
           print "<head><title>returnpage</title></head>\n";
           print "<body style="font: 14px Arial, Verdana;">\n";
           print "<center>\n";
           print "<H2>Upload completed</H2>\n";
           print "<HR>\n";
           print "</center>\n<br>";
           print "Grenzzeichenkette = <b>$boundary</b><br><br>\n";
           print "Die Daten sind folgendermaßen:<br><br><br><br>\n";
           print "name des input-felds: <b>$namefeld</b><br><br>";
           print "name der angelieferten datei: <b>$filename</b><br><br>";
           print "mimetype(oder eben nicht) der angelieferten datei: <b>$mimetype</b><br><br>";
           print "den ausdruck des dateiinhalts spar ich mir!!!<br><br>";
           print "</BODY>\n";
           print "</HTML>\n";

          <-----------schnapp----------------->

          und weil past und copy so einen spaß macht:

          <-----------schnipp----------------->

          <html>
          <head>
                  <title>Fileupload</title>
          </head>

          <body>

          <form name="Upload" action="http://eddie/cgi-bin/snippet1.pl" method="post" enctype="multipart/form-data">
            <input type="file" name="Dateiupload" size="30"><br><br>
            <input type="submit" value="Upload starten">
          </form>
          </body>
          </html>

          <-----------schnapp----------------->

          ok,ok, jetzt nich hauen. Ich weiß, dass das nicht der sauberste code ist und die RegEx sind nach Mitternacht geschrieben.... Was soll's, er tut's.

          Wenn ihr die gefakte Datei(eigentlich zip nach jpg benannt) mit dem IE5.xx hochbolzt bekommt ihr trotzdem einen compressed Content-Type, NN4-6.x schnappt sich die Endung und sagt fröhlich image/jpeg.

          Good nigth Ed X

          1. Hi,

            ok,ok, jetzt nich hauen. Ich weiß, dass das nicht der sauberste code ist

            in der Tat :-) Den größten Teil davon solltest Du _allerdringendst_ von CGI.pm erledigen lassen - nach der nächsten Formularänderung hast Du sonst plötzlich Fehler, die Du nicht absehen konntest.

            Wenn ihr die gefakte Datei(eigentlich zip nach jpg benannt) mit dem IE5.xx hochbolzt bekommt ihr trotzdem einen compressed Content-Type, NN4-6.x schnappt sich die Endung und sagt fröhlich image/jpeg.

            Windows kennt keinen MIME-Type, daher kann man nur schwerlich festmachen, welche Datei welchen Type hat. Netscape (und die meisten Browser, die ich kenne) macht das wie der Server: er guckt auf die Dateiendung. Der IE versucht die Datei zu analysieren.

            Leider tut er dies auch bei Daten, die er vom Server erhält. Beim Upload kann man darüber streiten, welche Variante besser ist; beim Download nicht.

            Cheatah

  2. Hi,

    ich hätte ja gerne die Archive durchsucht... aber irgendwie finde
    ich den Link zur Suche nicht mehr... (auf der Übersichtsseite is
    er nimmer...).

    Von wegen! (Es gibt dort sogar ein eigenes Eingabefeld dafür.)

    Wenn Du Links suchst, dann mußt Du links suchen ... ;-)

    Viele Grüße
          Michael