Reloadsperre - Script funktioniert nicht
Chrisman
- perl
Hallo Leute,
ich habe für mein Bannerwerbesystem versucht eine Reloadsperre zu programmieren, die auch nur so gehen kann. Also bitte keine allgemeinen Reloadsperren posten, die man hier irgendwo in älteren Beiträgen findet, denn diese habe ich auch schon gesichtet gehabt ;)
Hier der extra von mir für Euch kommentierte Quellcode:
#!/usr/bin/perl
$query = $ENV{'QUERY_STRING'};
@data = split(/&/, $query);
for (@data)
{
($key, $value) = split /=/;
$value =~ s/%([a-fA-F0-9]{2})/pack("C", hex($1))/eg;
$param{$key} = $value;
}
$userinfo = $param{'id'};
($id,$subcode) = split (/\_/, $userinfo);
open (IPDATEI, "<user/$id.ipdatei.txt");
@ipdatei = <IPDATEI>;
close (IPDATEI);
$ip = $ENV{'HTTP_CLIENT_IP'};
if ($ip eq "") { $ip = $ENV{'REMOTE_ADDR'}; }
foreach $line (@ipdatei)
{
($subcode_ipdatei,$wahlid_ipdatei,$ip_ipdatei) = split (/,/, $line);
if ($subcode_ipdatei eq $subcode && $ip_ipdatei eq $ip)
{
last;
}
else
{
}
}
Er bringt immer einen Internal Server Error, wenn der Code mit dem Browser aufgerufen wird. Der Perl-Compiler unter Telnet zeigt allerdings keine Fehler an, was wohl daran liegt, dass ich keine ID übergeben kann. Die Stellen, die ich hier nicht gelistet habe, sind auf jeden Fall richtig, es muss also im oberen Code ein Fehler vorkommen, ich finde ihn nur nicht, bin am Verzweifeln :(
Wer kann mir helfen?
Chrisman
Hallo Chrisman,
Gleich vorneweg als erstes: Wenn Du dem Browser nichts zurückgibst, bekommst Du imho immer einen 500er. Irgendwas steht dazu bestimmt auch im errorlog des Servers. Wenn Du wenigstens print "Content-Type: text/html\n\n<h1>Feddisch</h1>"; ausgibst, sollte der Server keinen Fehler melden.
Und nun will ich mich mal versuchen ;-)
#!/usr/bin/perl -w
^.....gibt dir alle Warnung auf STDERR aus
use strict; # hält dich dazu an, Deine Variablen sauber zu deklarieren,
# bevor Du sie verwendest (mit my() bzw. local())
$query = $ENV{'QUERY_STRING'};
@data = split(/&/, $query);
for (@data)
{
($key, $value) = split /=/;
$value =~ s/%([a-fA-F0-9]{2})/pack("C", hex($1))/eg;
$param{$key} = $value;
}
use CGI ':standard';
$userinfo = $param{'id'};
^.......so ähnlich, aber nun param('id');
($id,$subcode) = split (/\_/, $userinfo);
[...]
open (IPDATEI, "<user/$id.ipdatei.txt") or die $!;
^...(1) ^....(2)
(1) Das ist afaik nicht wirklich gut :-) Hier wird eine Usereingabe ohne Kontrolle, bzw. Bearbeitung mit open() auf das System losgelassen. Afaik sollte sowas unterbunden werden, damit es nicht zu unliebsamen Einbrüchen in Dein System kommen kann. Aber hier frags Du besser einen der Unix- bzw. CGI-Experten (*winkewinke* ;-).
(2) Ein potentieller Fehler sollte imho (und weil es so geschrieben steht ;-) immer abgefangen werden.
Hier könnte imho noch ein Dateilocking erfolgen, falls andere Prozesse auch schreibend mit der Datei agieren sollten.
[...]
close(IPDATEI) or die $!;
^.....(2)
$ip = $ENV{'HTTP_CLIENT_IP'};
if ($ip eq "") { $ip = $ENV{'REMOTE_ADDR'}; }
$ip = $ENV{'HTTP_CLIENT_IP'} $ENV{'REMOTE_ADDR'};
Das ist imho perliger, da hier die Shortcircuit-Eigenschaft und der Vorrang des logischen Operators ausgenutzt werden. D.h. Evaluierung von links nach rechts, und nur wenn es wirklich noch nötig ist.
[Rest nur grob überflogen (das ',' muss afaik nicht maskiert werden) :-)]
Ich hoffe das hilft Dir weiter (vor allem die Ausgabe an den Browser ;-)
Gruß AlexBausW
Please visit my SELFvisitingcard @ http://www.atomic-eggs.com/selfspezial/daten/150.html
Hallo Nochmal,
use strict; # hält dich dazu an, Deine Variablen sauber zu deklarieren,
# bevor Du sie verwendest (mit my() bzw. local())
Es sollte sogar mir klar sein, daß sich das natürlich auf alle Variablen auswirken sollte, auch wenn ich es nicht dabei geschrieben habe ;-))
Also statt:
$query = $ENV{'QUERY_STRING'};
@data = split(/&/, $query);
my $query = ....;
my @data = .....;
usw.
Sorry dafür :-)
Gruß AlexBausW
Hallo Alex,
danke für Deine ausführlichen Verbesserungsvorschläge. Ich werde sie berücksichtigen.
Wenn Du wenigstens print "Content-Type: >text/html\n\n<h1>Feddisch</h1>"; ausgibst, sollte der Server keinen >Fehler melden.
Das mache ich doch, diesen Teil habe ich doch nur im oberen Code weggelassen!
Das ist afaik nicht wirklich gut :-) Hier wird eine Usereingabe >ohne Kontrolle, bzw. Bearbeitung mit open() auf das System >losgelassen. Afaik sollte sowas unterbunden werden, damit es nicht >zu unliebsamen Einbrüchen in Dein System kommen kann.
Die Kontrolle mache ich natürlich auch noch!!! Ich will jetzt aber erstmal das die Reloadsperre überhaupt funktioniert. Der ganze Sicherheitskram kommt dann erst im nachhinein.
Chrisman
Hallo Chrisman,
Was ich beim ersten mal übersehen habe ist folgendes:
@ipdatei = <IPDATEI>;
[...]
foreach $line (@ipdatei) {
»» ($subcode_ipdatei,$wahlid_ipdatei,$ip_ipdatei) = split (/,/, $line);
»» #
»» #
}
Dadurch daß Du alle Zeilen der Datei "asis" in ein Array liest, enthält jedes Element des Arrays am Ende noch einen Zeilenumbruch. Dieser Zeilenumbruch befindet sich nach dem split() in der Variable $ip_datei. Deswegen schlägt Dein Vergleich ($ip eq $ip_datei) fehl, da $ip diesen Zeilenumbruch nicht enhält. Du musst \n also vor dem Vergleich entfernen (z.B. mit chomp();).
Ich hoffe das wars :-)
Gruß AlexBausW
Please visit my SELFvisitingcard @ http://www.atomic-eggs.com/selfspezial/daten/150.html
Hallo Chrisman,
Was ich beim ersten mal übersehen habe ist folgendes:
@ipdatei = <IPDATEI>;
[...]
foreach $line (@ipdatei) {
»» ($subcode_ipdatei,$wahlid_ipdatei,$ip_ipdatei) = split (/,/, $line);
»» #
»» #
}Dadurch daß Du alle Zeilen der Datei "asis" in ein Array liest, enthält jedes Element des Arrays am Ende noch einen Zeilenumbruch. Dieser Zeilenumbruch befindet sich nach dem split() in der Variable $ip_datei. Deswegen schlägt Dein Vergleich ($ip eq $ip_datei) fehl, da $ip diesen Zeilenumbruch nicht enhält. Du musst \n also vor dem Vergleich entfernen (z.B. mit chomp();).
Ich hoffe das wars :-)
Yeah! Das wars!! Danke Dir vielmals ;)
Endlich klappt es, wäre wahrscheinlich in 100 Jahren noch
nicht darauf gekommen :-)
Chrisman