Aus der Vielzahl der com CPAN erhältlichen Module stellen wir im folgenden Abschnitt noch einmal zwei Module besonders heraus:
Der Einsatz von PERL im WWW ist nicht auf CGI-Scripts begrenzt. Das CPAN
bietet eine ganze Reihe von Modulen mit denen man http-Client- und Serverfunktionen
ausführen kann. Die erforderlichen Module befinden sich meist im Archiv
"libwww-perl-*.tar.gz", der "Library for WWW.Access in PERL" .
Die libwww enthält über 50(!) Module für die HTTP-relevante Programmierung, die sich auf mehrere Namespaces verteilen:
Den LWP::UserAgent könnte man leger aber suggestiv als "nichtinteraktiven Browser" bezeichnen. Mit dem User Agent ist es möglich "ferngesteuert" Dokumente aus dem WWW zu laden, und anderen Anwendungen zur Verfügung zu stellen. Typische Anwendungen sind Web-Robots die das Web nach bestimmten Inhalten (Obszönitäten, Markenrechts-- oder Patentverletzungen) durchsuchen.
Der folgende Fünfzeiler "useragent_get.pl" holt ein CGI-Dokument vom Server "localhost":
#!/usr/bin/perl
#
use LWP::UserAgent;
#
$myagent=LWP::UserAgent->new();
$requesturl="http://localhost/cgi-bin2/fasttemplatedemo.cgi?name1=value1";
$myrequest=HTTP::Request->new(GET,$requesturl);
$myresponse=$myagent->request($myrequest);
print ($myresponse->content());
Das Beispiel zeigt die drei typischen Schritte beim Holen eines WWW-Dokumentes:
$myagent=LWP::UserAgent->new();
HTTP::Request
angelegt wird, das die Request-Methode (GET) und den URL als Parameter erhält:
$myrequest=HTTP::Request->new(GET,$requesturl);
request" Methode des User Agents geholt.
Die Request Methode erhält das eben erzeugte Request Objekt als Parameter,
führt den Request aus, und liefert das Ergebnis der Anfrage (das Dokument)
als ein Objekt der Klasse HTTP::Response zurück:
$myresponse=$myagent->request($myrequest);
Auf den Inhalt (Content) des Dokuments lässt sich dann mit der "content"
Methode zugreifen. Eventuell kann man auch vorher mit der Methode "is_success"
anfragen, ob dem Request überhaupt Erfolg beschieden war.
Auch ein POST-Request lässt sich mit dem UserAgent
realisieren.
Dazu müsen die Request-Methode des Requests
auf "POST", die Felder
für Content-Type und Content auf die gewünschten Werte
eingestellt werden (useragent2.pl):
#!/usr/bin/perl -w
#
use LWP::UserAgent;
$myagent = new LWP::UserAgent;
#
$req = new HTTP::Request 'POST','http://localhost/cgi-bin2/cgidemo2.cgi';
$req->content_type('application/x-www-form-urlencoded');
$req->content('+++name=wert++++');
#
$res = $myagent->request($req);
print $res->content();
Viele weitere Anregungen zum Umgang mit der libwww gibt
das Libwww-Perl Cookbook von libwww Autor
Gisele Aas, das einige der häufigsten
Problemstellungen beispielhaft in "Kochrezepform" löst.
Das libwww-cookbook erhält man nach der Installation der libwww
mit dem Kommando " perldoc lwpcook". Das Kochbuch enthät
u.A Kochrezepte für:
Eines der schönsten Features des UserAgent,
ist die Möglichkeit den HTTP_USER_AGENT String.
zu manipulieren. Per Voreinstellung liefert der HTTP_USER_AGENT
String einfach die Version der libwww zurück, z.B:
libwww-perl/5.36
Will man unerfahrene Webmaster oder instabile Auswertungssoftware ärgern,
dann kann man mit diesen Eintrag mit der "agent" Methode
verändern (hier auf Microsoft Internet Explorer für Linux):
$myagent->agent"(Mozilla/5.0 (compatible; MSIE 5.5 X11; U; Linux 2.6.16 i586))"
Die libwww Homepage findet man unter http://www.linpro.no/lwp/
Die "libnet" von Graham Barr ist eine Sammlung von Client-Implementationen der meistgenutzten TCP/IP Protokolle. Nur HTTP-Unterstützung gibt es nicht, dafür gibt es ja die libwww. Die folgende Tabelle gibt einen Überblick über die unterstützten Protokolle, und die RFCs die diese Protokolle beschreiben:
File Transfer Protocol (RFC959)
Simple Mail Transfer Protocol (RFC821)
Daytime Protocol (RFC867)
Time Protocol (RFC868)
Network News Transfer Protocol (RFC977)
Post Office Protocol (RFC1939)
Simple Network Pager Protocol (RFC1861)
Ein weitverbreiteter Anwendungsfall für die libnet sind nichtinteraktive
FTP-Sessions. Zwar lassen sich auch mit den meisten kommandozeilenorientierten
FTP-Clients nichtinteraktive FTP-Sitzungen
realisieren, wenn das Problem aber außer simplen Up- und Downloads auch
eine kompliziertere Anwendungslogik erfordert, hat PERL
schnell die Nase vorn. Das folgende Beispielscript (ftpdemo.pl)
lädt alle Dateien deren Namen mit "cgi" endet vom Homedirectory des
Benutzers cgidev ("/home/cgidev") in das aktuelle Verzeichnis.
Danach wird eine Logdatei erstellt, und in "/home/cgidev"
abgelegt. (Dieses Beispiel funktioniert aber nur, wenn der Benutzer
"cgidev" das Passwort "cgipass" benutzt ):
#!/usr/bin/perl -w
#
use Net::FTP;
#
#
$ftp = Net::FTP->new("localhost", Timeout => 60);
#
# einloggen mit Benutzernamen und Passwort
#
$ftp->login ('cgidev', 'cgipass');
#
#
# Testen ob der Login erfolgreich wr, gegenenfalls
# Abbruch mit Fehlermeldung
#
if($ftp == undef){
$errormsg=$@;
onError();
}
#
# OK-der Login war erfolgreich, wir koennen
# weitermachen...
#
# wechseln in das richtige Verzeichnis
# auf dem Server...
#
$ftp->cwd('/home/cgidev');
# Uebertragungstyp auf ASCII setzen
$ftp->ascii();
#
# Das Directory-Listing der *.cgi Dateien abbbholen
#
@dir = $ftp->ls('*.cgi');
print @dir;
#
#
#
foreach(@dir){
eval { #kritischer Block: Datei herunterladen
$cgi_filename=$_;
print "\n\n versuche $cgi_filename herunterzuladen\n";
$ftp->get($cgi_filename);
print " $cgi_filename heruntergeladen\n" ;
};
if($@){ #Fehlerabfrage
onError("Fehler beim download von $cgi_filename : \n\n $@");
}
}
#
#
print "\n Download beendet \n";
#
#
$now=localtime();
#
open (LOGFILE,"> ftp-log.$now");
print LOGFILE "Download um $now";
print LOGFILE join("\n",@dir);
close (LOGFILE);
#
#
$ftp->put("ftp-log.$now");
print "logdatei abgelegt \n";
#
sub onError($){
print "Fehler im System : $errormsg";
exit (1);
}
Der erste Schritt ist das Anlegen eines FTP-Objektes,
das die FTP-Sitzung modelliert. Der Konstruktor
"new" nimmt den Namen des FTP-Servers (hier:localhost)
und eventuell weitere optionale Parameter als Einträge eines Hashes
entgegen.
Hier ist sind es ein Timeout von 60 Sekunden,
und "True" fü Hashmark-Printing:
$ftp = Net::FTP->new("localhost", Timeout => 60, hash => "true" );
Andere Parameter könnten eventuelle Firewalls, die Größe der übertragenen Blöcke, der Serverport oder ein höheres DebugLevel sein.
Mit der login-Methode loggt sich der Client auf dem FTP-Server
ein. Die Login Methode nimmt normalerweise Benutzername und Passwort
des Benutzers auf dem Server als Parameter entgegen.
Ohne Parameter aufgerufen versucht login ein anonymes login mit der
Emailadresse als Passwort. Wenn das Login fehlschlägt,
liefert login ein "undef" zurück.
$ftp->login ('cgidev', 'cgipass');
Die nächsten Befehle sind 1:1 Entsprechungen von FTP-Kommandos.
cwd ändert das Remote-Verzeichnis, ascii
ändert den Übertragungsmodus, ls ruft den
FTP-Listingbefehl "dir" auf. ls liefert das
Directory-Listing als Array zurück:
$ftp->cwd('/home/cgidev');
$ftp->ascii();
@dir = $ftp->ls('*.cgi');
Eine Schleife lädt dann jede Datei aus dem Directory-Listing einzeln mit dem FTP-GET Komando herunter:
$ftp->get($cgi_filename);
Um die Aktion zu protokollieren wird am Ende eine Logdatei angelegt und mit
dem Kommando "put" auf dem Server abgelegt.
$ftp->put("ftp-log.$now");