Uploadscript zerstört Grafiken / + IE speichert nicht mal
$xNeTworKx
- perl
Hallo,
Ich hab da 2 kleine Probleme. Da mein Uploadscript fast fertig ist, habe ich es mal grob getestet (nur lokal). Die Grafiken werden richtig ins Verzeichnis upgeloaded, nur funktionieren sie leider nicht. Sie werden irgendwie beschädigt. Daraufhin habe ich mich nach meinem CGI Buch orientiert. Da wird die Grafik so am Server gespeichert :
(wurde von mir bereits wie folgt verändert. Das mit der Referenz ist Absicht)
open (SERVER,">flyer/$$flyer") or die "Cant save $$flyer : $!\n";
while (my $bytesread = read ($$flyer, my $buffer, 1024)) {
print SERVER $buffer;
}
close $$flyer;
close SERVER;
Das $bytesread kommt im ganzen Script nur 1 Mal vor. read ($$flyer, my $buffer, 1024)) sagt mir auch nicht viel, und warum muss ich die $buffer Variable am Server speichern und was bedeutet 1024 ? Im Buch wird auch überhaupt nicht beschrieben, was da jetzt ganz genau passiert. Ich bin sicher, es liegt daran, daß die upgeloadeten Grafiken kaputt sind.(können nicht angezeigt werden).
Dann habe ich mal das Ganze mit dem IE getestet, aber dieser Bug Browser speichert nicht mal die Daten. Wenn ich ins Errorlog sehe, sieht man folgendes :
[Sat Jul 13 12:07:58 2002] [error] [client 255.255.255.255] [Sat Jul 13 12:07:58 2002] c:\apache\forum\UPLOAD~1.CGI: Cant save C:\Dokumente und Einstellungen\Markus Pitha\Desktop\screenshots\snap00002.jpg : Invalid argument
Weis jemand was da los ist ?
P.S. Solltest die Slashes beim speichern nicht so / statt so \ sein ?
Liegt es vielleicht daran, daß der IE diese falsche setzt ?
Hallo,
open (SERVER,">flyer/$$flyer") or die "Cant save $$flyer : $!\n";
while (my $bytesread = read ($$flyer, my $buffer, 1024)) {
print SERVER $buffer;
}
close $$flyer;
close SERVER;
Ich denke, daß Du das übliche Problem mit Windows hast. Verwende binmode() nach dem open().
Grüße
Klaus
Hallo,
Ich denke, daß Du das übliche Problem mit Windows hast. Verwende binmode() nach dem open().
danke, das klappt jetzt :), zumindest mal mit richtigen Browsern. Der IE kanns nämlich immer noch nicht ?:
Cant save C:\Dokumente und Einstellungen\Markus Pitha\Desktop\screenshots\snap00002.jpg : Invalid argument
Hallo,
Dann habe ich mal das Ganze mit dem IE getestet, aber dieser Bug Browser speichert nicht mal die Daten. Wenn ich ins Errorlog sehe, sieht man folgendes :
[Sat Jul 13 12:07:58 2002] [error] [client 255.255.255.255] [Sat Jul 13 12:07:58 2002] c:\apache\forum\UPLOAD~1.CGI: Cant save C:\Dokumente und Einstellungen\Markus Pitha\Desktop\screenshots\snap00002.jpg : Invalid argument
Ist das eine von Dir generierte Fehlermeldung?
Wenn ja, verwendest Du den Filenamen, den der Browser mitsendet?
Wenn ja, hast Du überprüft, ob eventuell auch der Pfad der Datei mitgesendet wird und diesen gegebenenfalls abgeschnitten?
Wenn nein, solltest Du es tun.
Außerdem ist es unwahrscheinlich, daß der Webserver Zugriff auf das angegebene Verzeichnis hat, da er sicherlich unter einem anderen Useraccount als 'Markus Pitha' arbeitet.
P.S. Solltest die Slashes beim speichern nicht so / statt so \ sein ?
Grundsätzlich ist Perl unter Windows egal, welche Verzeichnistrennzeichen Du verwendest. Es sollte auch gehen wenn Du C:\verzeichnis/anderes_verzeichnis/dateiname.txt verwendest.
Grüße
Klaus
Hallo,
Dann habe ich mal das Ganze mit dem IE getestet, aber dieser Bug Browser speichert nicht mal die Daten. Wenn ich ins Errorlog sehe, sieht man folgendes :
[Sat Jul 13 12:07:58 2002] [error] [client 255.255.255.255] [Sat Jul 13 12:07:58 2002] c:\apache\forum\UPLOAD~1.CGI: Cant save C:\Dokumente und Einstellungen\Markus Pitha\Desktop\screenshots\snap00002.jpg : Invalid argument
Ist das eine von Dir generierte Fehlermeldung?
Die Meldung steht in der Errorlog, oder am Bildschirm (falls ich CGI::Carp verwende), wenn ich versuche mit dem IE upzuloaden (sowohl lokal, als auch wenn ich das Script vom Webspace ausführe
)
Wenn ja, verwendest Du den Filenamen, den der Browser mitsendet?
Ehmmm ? Da weis ich jetzt nicht genau was du meinst ?
Wenn ja, hast Du überprüft, ob eventuell auch der Pfad der Datei mitgesendet wird und diesen gegebenenfalls abgeschnitten?
Wenn nein, solltest Du es tun.
Außerdem ist es unwahrscheinlich, daß der Webserver Zugriff auf das angegebene Verzeichnis hat, da er sicherlich unter einem anderen Useraccount als 'Markus Pitha' arbeitet.
Am Webserver ist genau das gleiche Problem.
P.S Ausserdem habe ich schon wieder ein neues Problem.
Wenn das File am Server schon exisitert, ändere ich das Hochgeladene so:
my $flyermain = '';
if ($$flyer =~ /^(.+?).[a-zA-Z]{3}$/) {
$flyermain = $1;
}
while (-e "flyer/$$flyer") {
$counter++;
$$flyer =~ s/^.+?(.[a-zA-Z]{3})$/$flyermain$counter$1/;
}
Es wird zwar richtig weiternummeriert, nur ist diese Grafik dann auch kaputt (haben Größe 0), aber wenigstens funktioniert zumindest mal das durchnummerieren.
Hallo,
Dann habe ich mal das Ganze mit dem IE getestet, aber dieser Bug Browser speichert nicht mal die Daten. Wenn ich ins Errorlog sehe, sieht man folgendes :
[Sat Jul 13 12:07:58 2002] [error] [client 255.255.255.255] [Sat Jul 13 12:07:58 2002] c:\apache\forum\UPLOAD~1.CGI: Cant save C:\Dokumente und Einstellungen\Markus Pitha\Desktop\screenshots\snap00002.jpg : Invalid argument
Ist das eine von Dir generierte Fehlermeldung?
Die Meldung steht in der Errorlog, oder am Bildschirm (falls ich CGI::Carp verwende), wenn ich versuche mit dem IE upzuloaden (sowohl lokal, als auch wenn ich das Script vom Webspace ausführe
)Wenn ja, verwendest Du den Filenamen, den der Browser mitsendet?
Ehmmm ? Da weis ich jetzt nicht genau was du meinst ?
Wenn ja, hast Du überprüft, ob eventuell auch der Pfad der Datei mitgesendet wird und diesen gegebenenfalls abgeschnitten?
Wenn nein, solltest Du es tun.
Außerdem ist es unwahrscheinlich, daß der Webserver Zugriff auf das angegebene Verzeichnis hat, da er sicherlich unter einem anderen Useraccount als 'Markus Pitha' arbeitet.
Am Webserver ist genau das gleiche Problem.
P.S Ausserdem habe ich schon wieder ein neues Problem.
Wenn das File am Server schon exisitert, ändere ich das Hochgeladene so:
my $flyermain = '';
if ($$flyer =~ /^(.+?).[a-zA-Z]{3}$/) {
$flyermain = $1;
}
while (-e "flyer/$$flyer") {
$counter++;
$$flyer =~ s/^.+?(.[a-zA-Z]{3})$/$flyermain$counter$1/;
}
Es wird zwar richtig weiternummeriert, nur ist diese Grafik dann auch kaputt (haben Größe 0), aber wenigstens funktioniert zumindest mal das durchnummerieren.
Was ich noch vergessen habe:
Es wurde mir ja empfohlen Image:Size zu verwenden, und ganz sicher zu gehen, daß es auch wirklich eine Grafik ist, aber wenn ich es so verwende :
my($x,$y) = imgsize("$$flyer");
if (!($x || $y)) {
$$error = "<li>Die Breite und Höhe der Grafik kann nicht erkannt werden. Die Datei wird aus Sicherheitsgründen abgelehnt.</li>\n";
}
erscheint immer die von mir generierte Fehlermeldung ?
Hallo,
Ist das eine von Dir generierte Fehlermeldung?
Die Meldung steht in der Errorlog, oder am Bildschirm (falls ich CGI::Carp verwende), wenn ich versuche mit dem IE upzuloaden (sowohl lokal, als auch wenn ich das Script vom Webspace ausführe
Ich meinte, gibts irgendwo in Deinem Script ein 'or die "Cant Save $filename";' oder so ähnlich, also gibst Du in Deinem Script diese Fehlermeldung aus, oder durch welches Perl-Modul wird sie generiert.
Wenn ja, verwendest Du den Filenamen, den der Browser mitsendet?
Ehmmm ? Da weis ich jetzt nicht genau was du meinst ?
Wird der Dateiname von deinem Script generiert, oder übernimmst Du den Namen der Datei, die Du dem Server geschickt hast.
Am Webserver ist genau das gleiche Problem.
P.S Ausserdem habe ich schon wieder ein neues Problem.
Wenn das File am Server schon exisitert, ändere ich das Hochgeladene so:
my $flyermain = '';
if ($$flyer =~ /^(.+?).[a-zA-Z]{3}$/) {
$flyermain = $1;
}
while (-e "flyer/$$flyer") {
$counter++;
$$flyer =~ s/^.+?(.[a-zA-Z]{3})$/$flyermain$counter$1/;
}
Es wird zwar richtig weiternummeriert, nur ist diese Grafik dann auch kaputt (haben Größe 0), aber wenigstens funktioniert zumindest mal das durchnummerieren.
Das liegt wohl an der Dualität der Rückgabe von param('uploaded_file'). Einmal ist es der vom Browser gesendete Dateiname, einmal ein Filehandle. Ich habe mich zwar schon an die Mechanismen von CGI.pm gewöhnt, aber die Behandlung von Fileuploads waren IMHO in cgi-lib.pl einfacher gelöst.
Kannst Du einmal irgendwo das Script vollständig zugänglich machen. Aus diesen Fragmenten werde ich einfach nicht schlau.
Grüße
Klaus
Hallo,
Ist das eine von Dir generierte Fehlermeldung?
Die Meldung steht in der Errorlog, oder am Bildschirm (falls ich CGI::Carp verwende), wenn ich versuche mit dem IE upzuloaden (sowohl lokal, als auch wenn ich das Script vom Webspace ausführe
Ich meinte, gibts irgendwo in Deinem Script ein 'or die "Cant Save $filename";' oder so ähnlich, also gibst Du in Deinem Script diese Fehlermeldung aus, oder durch welches Perl-Modul wird sie generiert.
Ja, ich verwende stets or die, aber ich poste mal das ganze Script für den besseren Überblick.
http://www.acid4u.com/uploadflyer.txt
Ich wiederhole :
Im Mozilla kann ich eine Grafik uploaden.
Lade ich eine 2. mit dem selben Namen rauf, hat diese veränderte Grafik die Größe 0.
Der IE gibt die besagte Fehlermeldung während des Uploades im Errorlog oder im Browser (falls CGI::Carp) aus.
Hallo,
Zuerste möchte ich Dich nochmals darauf hinweisen, daß es eine Doppelbedeutung bei CGI.pm gibt, Datei-Upload-Felder betreffend.
Einerseits ist es der Dateiname, andererseits auch ein Filehandle.
Anscheinend ist es so, daß, wenn Du den Dateinamen veränderst, automatisch auch der Filehandle verloren geht. (Ist mir etzt zu mühsam, mich in die Untiefen des CGI-Moduls zu begeben *g*)
So jetzt zu Deinen Problemen:
1.) IE
Du verwendest den vom Browser gesendeten Dateinamen auch für den Dateinamen am Server.
open (SERVER,">flyer/$$flyer") or die "Cant save $$flyer : $!\n";
(Zeile 113 in sub saveflyer)
Da es aber Browser gibt, welche nur den reinen Dateinamen, also z.B. 'blablabla.gif' senden, und welche die den ganzen Pfad Dir überantworten, also z.B. 'C:\wumptbumpti\blablabla.gif', gibts bei Dir schwierigkeiten, da 'flyer/C:\wumptbumpti\blablabla.gif' unter WIndows sicher kein gültiger Pfad ist, daher das 'Invalid Argument' in der Fehlermeldung. Abgesehen davon kann Perl von sich aus mit open() die notwendigen Verzeichnisstruktur anlegen, was auch gut so ist.
Du mußt also zuallererst einmal sicherstellen, daß in dem übergebenen Dateinamen keine Pfadangaben mehr vorkommen.
Entweder Du verwendest File::Basename, oder Du schreibst etwas eigenes.
BTW No.1: Relative Pfade in CGI-Scripts sind nicht gut, da Du nie genau weißt, welches Verzeichnis gerade das aktuelle Verzeichnis ist.
BTW No.2: Du solltest Dir angewöhnen, Deine Fehlermeldungen zu kennen, bzw. so zu kennzeichnen, daß Du auch weißt, daß sie von Dir sind, und wenns nur 'or die "sch..., schon wieder nix mit open $filename, $!";' ist.
2.) Doppelte Datei-Uploads
Die aufgrund der oben erwähnte Doppeldeutigkeiten auftretenden Probleme bekommst Du wahrschein lcih am einfachsten in den Griffen, wenn Du zuerst den Dateiinhalt in ein Array schreibst, dann den Dateinamen gradebiegst, und am Ende das Array in die Datei schreibst:
#im Initbereich des Scripts:
use File::Basename;
my $flyerdir = 'wo\auch\immer';
[...]
sub saveflyer
{
[...]
my @inhalt = <$$flyer>;
#wobei ich nicht verstehe, warum das eine Referenz sein muß, aber anyway...
my($filename) = getuniquefilename($flyerdir,$$flyer);
open(OUT,">$filename") or die "sch..., nic da mit open flyerfile $filename: Grund = $!";
binmode(OUT);
print OUT @array;
close(OUT);
[...]
}
#und die Funktion getuniquefilename
sub getuniquefilename
{
my($flyerdir,$orig_name) = @_;
my ($basename,$dmy,$suffix) = fileparse($orig_name,'..+');
my $counter=0;
my($guessname) = $basename
while(-e "$flyerdir/$guessname$suffix")
{
$counter++;
$guessname = "$basename$counter";
}
return "$flyerdir/$guessname$suffix";
}
Grüße
Klaus
Hallo,
So jetzt zu Deinen Problemen:
1.) IE
Du verwendest den vom Browser gesendeten Dateinamen auch für den Dateinamen am Server.
open (SERVER,">flyer/$$flyer") or die "Cant save $$flyer : $!\n";
(Zeile 113 in sub saveflyer)
Da es aber Browser gibt, welche nur den reinen Dateinamen, also z.B. 'blablabla.gif' senden, und welche die den ganzen Pfad Dir überantworten, also z.B. 'C:\wumptbumpti\blablabla.gif', gibts bei Dir schwierigkeiten, da 'flyer/C:\wumptbumpti\blablabla.gif' unter WIndows sicher kein gültiger Pfad ist, daher das 'Invalid Argument'
Achso, jetzt hab ich das endlich verstanden.
BTW No.1: Relative Pfade in CGI-Scripts sind nicht gut, da Du nie genau weißt, welches Verzeichnis gerade das aktuelle Verzeichnis ist.
Das hab ich nie genau verstanden. Was bedeutet 'das aktuelle Verzeichnis ist' ? Das Script ist doch immer im gleichen Verzeichnis, deswegen verstehe ich nicht, was da eigentlich gemeint ist.
BTW No.2: Du solltest Dir angewöhnen, Deine Fehlermeldungen zu kennen, bzw. so zu kennzeichnen, daß Du auch weißt, daß sie von Dir sind, und wenns nur 'or die "sch..., schon wieder nix mit open $filename, $!";' ist.
Ja, ich vergebe immer, so weit es möglich ist pro open() verschiedene Fehlermeldungen, da ich sonst bei riesen Scripts den fehlerhaften open() nicht mehr finde. (Hat mir wirklich schon einige Male geholfen)
Die aufgrund der oben erwähnte Doppeldeutigkeiten auftretenden Probleme bekommst Du wahrschein lcih am einfachsten in den Griffen, wenn Du zuerst den Dateiinhalt in ein Array schreibst, dann den Dateinamen gradebiegst, und am Ende das Array in die Datei schreibst:
#im Initbereich des Scripts:
use File::Basename;
my $flyerdir = 'wo\auch\immer';
[...]
sub saveflyer
{
[...]
my @inhalt = <$$flyer>;
#wobei ich nicht verstehe, warum das eine Referenz sein muß, aber anyway...
my($filename) = getuniquefilename($flyerdir,$$flyer);
open(OUT,">$filename") or die "sch..., nic da mit open flyerfile $filename: Grund = $!";
binmode(OUT);
print OUT @array;
close(OUT);
[...]
}
#und die Funktion getuniquefilename
sub getuniquefilename
{
my($flyerdir,$orig_name) = @_;
my ($basename,$dmy,$suffix) = fileparse($orig_name,'..+');
my $counter=0;
my($guessname) = $basename
while(-e "$flyerdir/$guessname$suffix")
{
$counter++;
$guessname = "$basename$counter";
}
return "$flyerdir/$guessname$suffix";
}
Ok ich werd mir das sorgfältig durchsehen. Danke für die ausführliche Antwort.
$xNeTworKx.
Hallo,
Das hab ich nie genau verstanden. Was bedeutet 'das aktuelle Verzeichnis ist' ? Das Script ist doch immer im gleichen Verzeichnis, deswegen verstehe ich nicht, was da eigentlich gemeint ist.
Das aktuelle Verzeichnis ist jenes Verzeichnis in dem das Script ausgeführt wird. Wenn Du z.B. open(IN,'datei') schreibst, wobei Du keine Pfadangabe machst, dann probiert Perl in diesem, hmm, Arbeitsverzeichnis die Datei zu öffnen. Dieses Verzeichnis muß nicht automatisch das sein, in dem das Script abgelegt ist. Es kann durchaus, je nach Aufruf bzw. Serverkonfiguration auch irgendwo anders im Dateisystem sein. Und weil eben nicht sicher ist, wie das arbeitsverzeichnis gerade eingestellt ist, kannst Du Dich auch nicht auf irgend etwas verlassen, auch wenn es sehr oft mit dem Scriptverzeichnis zusammen fällt.
Ja, ich vergebe immer, so weit es möglich ist pro open() verschiedene Fehlermeldungen, da ich sonst bei riesen Scripts den fehlerhaften open() nicht mehr finde. (Hat mir wirklich schon einige Male geholfen)
Ja, natürlich, je besser die Fehlerbehandlung ist, desto schneller findest Du auch den Fehler. Nur meinte ich, daß Du Deine Fehlermeldungen so gestalten solltest, daß zu erstens sie auch als die Deinigen erkennst, und zweitens auch sofort siehst, in welchem Script und wo dort sie erzeugt wurde.
Meldungen wie "Das ging aber schief" helfen eigentlich nicht wirklich weiter. Meldungen wie "Das Oeffnen der neuen Flyerdatei $filename zum Schreiben hat fehlgeschlagen:Grund $!" oder "Fehler bei open($filename) in saveflyer: $!" oder so, sind da schon wesentlcih aussagekräftiger.
Grundsätzlich sollte die Fehlermeldung also:
beinhalten.
Grüße
Klaus
Moin,
[Sat Jul 13 12:07:58 2002] [error] [client 255.255.255.255]
^^^^^^^^^^^^^^^
Kommt dir das nicht ein bisschen spanisch vor?
--
Henryk Plötz
Grüße aus Berlin
Hallo,
[Sat Jul 13 12:07:58 2002] [error] [client 255.255.255.255]
^^^^^^^^^^^^^^^
Kommt dir das nicht ein bisschen spanisch vor?
Nein, weil ich muss ja nicht unbedingt meine IP groß zur Schau stellen :)