# Tento modul má za úkol zabránit v přístupu ke skriptům robotům nebo
# obecně klientům, kteří se jako roboti chovají (mají příliš mnoho požadavků
# za jednotku času).

# (c) 2005 Daniel Zeman <zeman@ufal.mff.cuni.cz>
# Licence: GNU GPL

use utf8;

package norobot;
$maxcas = 240000; # 24 h 0 min 00 s
$maxpoz = 100;   # >maxpoz požadavků za maxcas => jsi robot!

sub proverit
{
    # Z proměnných prostředí zjistit, odkud přišel aktuální požadavek.
    my $ip = $ENV{REMOTE_ADDR};
    my $params = $ENV{QUERY_STRING};
    # Pokud je tato adresa na černé listině, vrátit chybu.
    open(BLACK, "norobot-blacklist.txt");
    while(<BLACK>)
    {
        s/\r?\n$//;
        if($_ eq $ip)
        {
            return 0;
        }
    }
    close(BLACK);
    # Zjistit počet požadavků z této adresy za poslední 2 minuty.
    # Zjistit aktuální čas.
    my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime(time);
    my $cas = sprintf("%04d%02d%02d%02d%02d%02d", $year+1900, $mon+1, $mday, $hour, $min, $sec);
    # Načíst seznam požadavků.
    open(LOG, "norobot-accesslog.txt");
    while(<LOG>)
    {
        s/\r?\n$//;
        my ($ipi, $casi, $paramsi) = split(/;/, $_);
        if($cas-$casi<=$maxcas)
        {
            $n_pozadavku{$ipi}++;
            push(@pozadavky, {"ip" => $ipi, "cas" => $casi, "params" => $paramsi});
        }
    }
    close(LOG);
    # Přidat do seznamu nový požadavek.
    $n_pozadavku{$ip}++;
    push(@pozadavky, {"ip" => $ip, "cas" => $cas, "params" => $params});
    # Jestliže už je požadavků moc, přidat adresu na černou listinu a vrátit chybu.
    if($n_pozadavku{$ip}>$maxpoz)
    {
        open(BLACK, ">>norobot-blacklist.txt");
        print BLACK ("$ip\n");
        close(BLACK);
        return 0;
    }
    # Jinak uložit aktualizovaný seznam čerstvých požadavků a vrátit schválení.
    open(LOG, ">norobot-accesslog.txt");
    foreach my $poz (@pozadavky)
    {
        print LOG ("$poz->{ip};$poz->{cas};$poz->{params}\n");
    }
    close(LOG);
    return 1;
}



sub ohlasit_chybu
{
    # Z proměnných prostředí zjistit, odkud přišel aktuální požadavek.
    my $ip = $ENV{REMOTE_ADDR};
    print <<EOF
Status: 403 
Content-type: text/html; charset=utf-8

<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>Chyba</title>
</head>
<body>
<h1>Chyba</h1>
<p>Omlouváme se, že vám náš server odepřel přístup k&nbsp;dynamické stránce.
Pravděpodobně k&nbsp;tomu došlo proto, že někdy v&nbsp;minulosti server
zaznamenal zvýšený počet požadavků v&nbsp;krátké době, pocházejících
z&nbsp;vaší IP adresy $ip. Toto opatření bylo zavedeno jako ochrana serveru
proti robotům. Jestliže nejste robot, upozorněte nás prosím na adrese
"paluba hrejsi cz" (místo první mezery zavináč, místo druhé tečka), že
vám byl neprávem odepřen přístup. Nezapomeňte uvést svou IP adresu
($ip).</p>

<p>Na lepším řešení pracujeme.</p>
<address><a href="http://hrejsi.cz/">Vaše Paluba</a></address>
</body>
</html>
EOF
    ;
}



1;
