Dez 26

In einem der tmux-Fenster des letzten Beitrags läuft ein tail auf das squid-access.log.
Dummerweise zeigt das tail nach einem logrotate nichts mehr an, da das Filehandle vom tail ja auf das „rotierte“ log zugreift.
Fein wäre doch ein kleines Script, dass, sobald im geöffnet Filehandle nichts mehr kommt, die Datei „reopened“ und dann weiter anzeigt.

Bitte sehr (Perl // Modul File::Tail vorrausgesetzt):

#!/usr/bin/perl
use File::Tail;
use Socket;
use strict;
$|=1;
my $logfile="/var/log/squid-access.log";
my $file=File::Tail->new(name=>$logfile, maxinterval=>300, adjustafter=>7);
while (defined(my $line=$file->read)) {
        my @liner=split(' ',$line,-1);
        my $host='';
        $host=gethostbyaddr(inet_aton($liner[8]), AF_INET) or $host=$liner[8];
        my @hostname=split(/./,$host); # Split FQDN at dots
        $host=$hostname[0];             # Get Lowest Domainname
        my @hosts=split(/./,$liner[8]);# Split IP at dots
        my $loctet=$hosts[3];           # Get last Octet
        printf "%s %3s %st%sn",$liner[2],$loctet,$host,$liner[12];
}
									

Das Ding zieht gleichzeitig die wichtigsten Infos aus dem Log. Nämlich den Timestamp, das letzte Octet der IP, sowie den ersten Part des Reverse-DNS-Namens.

Tagged with:
Apr 11

Das Kind hat doch derbe Defizite mit dem kleinen 1×1. Macht sich jetzt so richtig bemerkbar, weil im Unterricht Division mit REST durchgenommen wird. Nun habe ich allerdings wenig Lust, mir alle Nasenlang neue Aufgaben aus den Fingern zu saugen. Also mal flux ein Perl-Script geschrieben, welches die Ergebnisse gleich mitliefert. Auf Excel-Output hatte ich gerade keine Lust, sollte aber mit „Spreadsheet::WriteExcel“ (gibts beim CPAN Ihres Vertrauens) auch kein Thema sein.

Das folgende Script wirft also 60 Aufgaben mit 60 Ergebnissen aus. Wenn man den Output (Tab-getrennt) in Excel guttenbergt (CopyPaste), dann hat man auf dem „linken“ Blatt, bei einem 18er Font, die Aufgaben, und auf dem rechten Blatt die Ergebnisse. Die machen es dann etwas leichter, den Kram den der Nachwuchs da hingepinselt hat, zu kontrollieren.

#!/usr/bin/perl
my $i=100;
my @erg,@aufg;
my $sollaufgaben=60;
while ($aufgaben<$sollaufgaben) {
  $i++;
  my $a=int(rand($i)%100);
  my $b=int(rand($i)%10);
  $b=1 if int($b)==0;
  $a=1 if int($a)==0;
  if (int($a/$b)<12) {
    $aufgaben++;
    push @aufg,$aufgaben."\t".$a."\t:\t".$b;
    push @erg,int($a/$b)." R ".($a % $b);
  }
}

for (my $i=0;$i<int($sollaufgaben/2);$i++) {
  print $aufg[$i*2]."\t\t".$aufg[$i*2+1]."\t\t";
  print $erg[$i*2]."\t".$erg[$i*2+1]."\n";
}
									

Tagged with:
Nov 07

Herr Koehntopp philosophiert ueber NULL in PERL vs. NULL in mySQL.

Sehr lesenswert fuer alle, die sich schonmal gefragt haben, wie man am sinnvollsten mit NULL-Werten in Datenbanken umgeht. Das Thema ist ja doch nicht so ganz ohne…

Tagged with:
Mai 29

Das Perl-Modul WWW::Shorten::Bitly als solches bietet die Moeglichkeit URLs, die zuvor mit bit.ly verkuerzt worden sind, wieder zu „expanden“ und auch diverse Clickstatistiken auf diese URLs zu fahren.

Leider hat das Modul ein paar Schoenheitsfehler:

  1. Beim „Expanden“ meint das Modul die Methode „GET“ nutzen zu wollen. Die API von bit.ly schreibt hier aber ein „POST“ vor. Das ist recht zuegig gefixed. Einfach in der Zeile 257 (Methode „expand“ der Version 1.14) aus dem get ein post machen -> Fertig 🙂
  2. Beim Aufruf der Methode „clicks“ auf URLs mit vielen Statistik-Daten (Referrers, etc.) versagt der SAX-Parser auf ganzer Linie. Er quittiert das Parsen mit einer Fehlermeldung a’la: End tag mismatch (nodeKey != nodeValue) [Ln: x, Col: yyyyy]Das Problem laesst sich dadurch loesen, dass man dem XML::Simple Modul sagt, es soll gefaelligst einen Ordentlichen parser benutzen. z.B. den XML::Parser (der zuvor via cpan installiert werden muss (setzt libexpat1-dev vorraus !)). Wir teilen dies dem Bitly Modul nach dem Einbinden von XML::Simple ueber folgenden String mit: $XML::Simple::PREFERRED_PARSER = 'XML::Parser'; … und oh Wunder: Alles funktioniert

In diffs ausgedrueckt sind folgende Aenderungen an WWW::Shorten::Bitly Version 1.14 notwendig:

22a23,24
> $XML::Simple::PREFERRED_PARSER = 'XML::Parser';
>
257c259
< $self->{response} = $self->{browser}->get($self->{BASE} . '/expand', [
---
> $self->{response} = $self->{browser}->post($self->{BASE} . '/expand', [

Ab nun klappt auch das Auslesen mit dem Modul.

Tagged with:
Dez 29

Aufmerksam geworden durch diesen Artikel, mit dem ueber den Proxy geholte Webseiten (genauer gesagt werden alle Images einmal um 180 Grad gedreht) on the Fly manipuliert werden habe ich mir das ganze mal näher angesehen und optimiert.

Vorweg schonmal das Ergebnis (funktioniert TRANSPARENT mit allen JPGs, GIFs und PNGs). Transparent bedeutet in diesem Falle, dass der Anwender in keinerlei Weise mitbekommt, dass es sich hier um ein manipliertes Bild handelt. Die Requests werden quasi 1:1 durchgeleitet.

Wor moechten also alle Bilder, die aus dem LAN via Proxy angefordert werden, einmal um 180 Grad drehen. Folgende Ausgangssituation:

  • Transparenter Squid auf einem Router
  • Webserver auf einem etwas dickeren Rechner im LAN

in /etc/squid/squid.conf folgende Zeile einfügen:

url_rewrite_program /usr/bin/updwn.pl
url_rewrite_children 5

Das File /usr/bin/updwn.pl sollte wie folgt aussehen:

#!/usr/bin/perl
# Runs as proxy:proxy
# input - siehe unten (Array params)
# output - URL - transparent *invisble to Enduser :-) *
$|=1;
while (<>) {
chomp $_;
@params=split(/ /,$_);
# 0 = Request URL
# 1 = Requesting IP/-
# 2 = -
# 3 = Request Method
# 4 = myip= ?
# 5 = myport = ?
$url=$params[0];
if (!($params[1]=~/192\.168\.60\.200/)) { # Nicht rekursiv aufrufen (Boese !!)
$url='http://192.168.60.200/ppics/updwn.pl?u='.$url if ( ($url=~/gif/i) || ($url=~/jpg/i) || ($url=~/jpeg/i) || ($url=~/png/i));
}
print $url."\n";
$count++;
}

Wobei die 192.168.60.200 durch die IP des eigenen Webserver zu ersetzen waere. Die eigentliche „Magie“ findet naemlich jetzt im updwn.pl auf dem Webserver statt. Das Ding benutzt, im gegensatz zu dem File, welches in dem Artikel beschrieben wurde, direkt die GD-Library und ruft keinerlei Executables mehr auf. Damit ist das Script ein wenig performanter

Hier der Inhalt von /var/www/ppics/updwn.pl:

use CGI qw/:standard/;
use LWP::UserAgent;
use GD;
binmode STDOUT;

$|=1;
my $url=param(„u“);

chomp $url;
my $ctype=“;
my $content=“;
get_content($url,\$ctype,\$content);
rotate(\$content,\$ctype) if ($ctype=~/image/i);
print „Content-Type: „.$ctype.“\n\n“;
print $content;
print „\n–magicalboundarystring\n“ if ($ctype=~m/image/);

sub get_content {
my ($url,$ref_ctype,$ref_content)=@_;
my $ua = LWP::UserAgent->new;
$ua->agent(„MyApp/0.1 „);
my $req = HTTP::Request->new(GET => $url);
my $res = $ua->request($req);
$$ref_ctype=$res->content_type;
$$ref_content=$res->content;
}

sub rotate {
my ($ref_content,$ref_header)=@_;
my $image=undef;
$image=newFromPngData GD::Image($$ref_content) if ($$ref_header=~/png/i);
$image=newFromJpegData GD::Image($$ref_content) if ($$ref_header=~/jpeg/i);
$image=newFromGifData GD::Image($$ref_content) if ($$ref_header=~/gif/i);
$image->rotate180();
$$ref_header=’image/png‘;
$$ref_content=$image->png();
}
Wichtig: Die URL sollte nicht aus dem Internet erreichbar sein. Ansonsten hat man einen selbstgebastelten offenen Proxy…

Mithilfe der Parameter des Files /usr/bin/updwn.pl kann man sich jetzt sogar lustige ACLs bauen. (Rotiere nur fuer bestimmte IP’s oder fuer bestimmte URLs, etc…) Der Phantasie sind da keine Grenzen gesetzt.

Tagged with:
preload preload preload