Opis::Session - Interface zum Sessionserver
use Opis::Session;
$s=Opis::Session->new;
$s=Opis::Session->new(session=>$handle);
$handle=$s->session;
$s->create(password=>..., timeout=>..., maxsize=>..., maxkeys=>...)
->set(hugo=>qw/fritz klaus/, [qw/hansfried johann/]);
$s->open;
$s->open(session=>$handle);
$s->close;
$s->destroy;
@data=$s->get('hugo');
%all=$s->getall;
@justdeleted=$s->purge('hugo');
@keys=$s->list;
Opis::Session ist ein Modul zur Arbeit mit dem Sessionserver.
Eine Session ist eine zusammengehörige Menge von benannten Wertelisten. Die Elemente einer Liste können einfache Strings oder Zahlen oder auch komplexe Typen, wie Hashes oder Arrays sein. Objekte sind nicht erlaubt, auch nicht als Teil eines komplexen Typs.
Neben den Nutzdaten gehören zu einer Session noch einige Metadaten. Einige dieser Metadaten sind änderbar, andere nicht. Mehr dazu ist in der Beschreibung des Sessionservers zu finden. Die Metadaten einer Session können beim Erzeugen angegeben und mittel options() geändert werden.
Die wichtigsten Metadaten einer Session sind ihr handle, der timeout und die Größenbeschränkungen maxkeys und maxsize.
Der Zugriff auf eine Session passiert immer in einem open-read/change-close Zyklus. Ist einem Session von einem Client geöffnet, kann kein anderer Client darauf zugreifen.
Ein Opis::Session Objekt ist nicht das Gleiche wie eine Session. Es kann auch ohne Session existieren. Erst beim Öffnen oder Erzeugen einer Session wird das Opis::Session Objekt mit einer Session verbunden.
Obwohl das Interface des Sessionservers es erlaubt mehrere Sessions über eine TCP-Verbindung zu bearbeiten, sollte ein Opis::Session Objekt immer nur für eine Session verwendet werden.
Eine Session wird immer von genau einem Sessionserver verwaltet. In einem Verbund startet jedoch auf jedem Rechner einen Sessionserver. Opis::Session muß daher zu einem Handle als erstes den Sessionserver finden, der diese Session verwaltet. Zu diesem Zweck enthält das vom Sessionserver erzeugte Handle immer die IP Adresse und den Port des Sessionservers.
Eine Funktion von Opis::Session ist die Umkodierung des Handles. Ein von Opis::Session erzeugtes Handle ist so vor mutwilligen Änderungen mit dem Ziel, Zugriff auf andere Sessions zu erlangen, geschützt.
Ein Opis::Session Handle ist ein String aus folgenden Zeichen:
ABCDEFGHIJKLMNOPQRSTUVWXZY abcdefghijklmnopqrstuvwxzy 0123456789@-
Es ist unbedenklich ihn direkt als Cookie zu setzen oder als URL Parameter zu benutzen. Ein Session Handle als Username Feld in einer URL zu benutzen, ist ungeeignet, da es das Zeichen @ enthalten kann.
Weiterhin kann Opis::Session die Inhalte einer Session verschlüsseln, so daß auch jemand, der Zugriff auf den Sessionserver hat, diese nicht lesen kann.
Fehler werden grundsätzlich als über Exceptions angezeigt.
Der Konstruktor erzeugt ein Opis::Session Objekt und initialisiert einige Eigenschaften:
gibt IP:PORT des Sessionservers an. Die IP Adresse wird aus der Umgebungsvariablen internal_address genommen. Der Port ist 823.
gibt IP:PORT des Sessionserver Backups an. Die IP Adresse wird aus der Umgebungsvariablen internal_address_freigabe genommen. Der Port ist 823.
enthält ein Geheimnis, mit dem das vom Sessionserver erzeugte Handle umkodiert wird. Standardmäßig wird die Konstante SCRAMBLE_key aus dem Modul Opis::Const benutzt.
wird als leeres Hash initialisiert.
Weitere Eigenschaften können über KEY => VALUE Parameter übergeben werden. Insbesondere sei hier session und password erwähnt.
stellt eine Verbindung zum Sessionserver ($s->server oder $s->backup) her und erzeugt eine Session. Als Parameter können als KEY => VALUE Paare ein optionales Passwort und Session Metadata übergeben werden.
Das serialize Metadatum kann nicht geändert werden. Ist ein Passwort angegeben oder die password Eigenschaft des Opis::Session Objekts gesetzt, wird stdpw als serialize Datum gesetzt, sonst std. Beim Lesen und Schreiben des Inhalts einer Session wird diese Information dann benutzt, um zwischen verschlüsselten und Klartext-Sessions zu unterscheiden.
Folgende Metadaten sind sinnvoll gleich beim Erzeugen einer Session zu setzen. Sie sind später mittels options() änderbar.
Hier sollte ein Wert gewählt werden, der dem Projekt oder der Art der Session entspricht. Für einen Warenkorb eines Shops wären einige Tage sicher angemessen. Werden Kundenstammdaten verwaltet, ist der Timeout sicher länger.
gibt ein Limit an, wie viele Bytes eine Session halten darf.
gibt ein Limit an, wie viele Schlüssel eine Session halten darf.
Endet der Aufruf erfolgreich, sind folgende Eigenschaften gesetzt und repräsentieren die gerade erzeugt Session. Die Session ist geöffnet.
das Session Handle
das Session Handle des Sessionservers (unverschlüsselt)
ein Hash mit den Metadaten der neuen Session
ein IO::Socket::INET Objekt, das die Verbindung zum Sessionserver darstellt.
Falls ein password als Parameter übergeben wurde, ist die password Eigenschaft des Objekts gesetzt.
Als Rückgabewert wird das Opis::Session Objekt geliefert. Es ist also möglich Methoden zu verketten, z.B.:
$obj->create()->set()
öffnet eine existierende Session. Das Handle kann als Parameter übergeben werden. Wird kein Parameter angegeben, wird die session Eigenschaft des Opis::Session Objekts benutzt.
Endet der Aufruf erfolgreich, sind folgende Eigenschaften gesetzt und repräsentieren die gerade erzeugt Session. Die Session ist geöffnet.
das Session Handle
das Session Handle des Sessionservers (unverschlüsselt)
ein Hash mit den Metadaten der neuen Session
ein IO::Socket::INET Objekt, das die Verbindung zum Sessionserver darstellt.
Als Rückgabewert wird das Opis::Session Objekt geliefert. Es ist also möglich Methoden zu verketten, z.B.:
$obj->open()->get()
schließt die aktuelle Session. Danach können andere Clients die Session im Sessionserver öffnen.
Die Benutzung dieser Methode ist optional. Beim Zerstören des Opis::Session Objekts bzw. beim Beenden der Verbindung zum Sessionserver wird die Session automatisch geschlossen.
Als Rückgabewert wird das Opis::Session Objekt geliefert.
liest und setzt Metadaten. Als Rückgabewert wird ein Hash mit den alten Metadaten der Session geliefert. Werden keine Parameter übergeben, werden die Metadaten unverändert vom Sessionserver gelesen. In jedem Fall wird die metadata Eigenschaft aktualisiert.
Beispiel:
%alte_metadaten=$s->options(timeout=>100,
maxsize=>$s->metadata->{maxsize}+1024,
maxkeys=>$s->metadata->{maxkeys}+10);
merkt die Session zum Löschen vor.
Als Rückgabewert wird das Opis::Session Objekt geliefert.
speichert die übergebenen Werte als NAME in der Session. War zum Zeitpunkt der Erzeugung der Session ein Passwort aktiv, werden die Werte verschlüsselt gespeichert. NAME wird unverschlüsselt gespeichert.
Wird mit dieser Operation der Wert von NAME in der Session überschrieben, wird der alte Wert als Rückgabewert geliefert, sonst undef bzw. eine leere Liste.
Beispiel:
($vorname, $nachname)=$s->set(name=>$neuer_vorname, $neuer_nachname);
löscht NAME aus der Session.
Als Rückgabewert wird der alte Wert geliefert.
Beispiel:
($vorname, $nachname)=$s->purge('name');
liest NAME aus der Session.
Beispiel:
($vorname, $nachname)=$s->get('name');
liest alle (Name, Wert) Paare einer Session.
Beispiel:
%as_hash=$s->getall;
liest alle Namen, die in einer Session vorkommen.
Beispiel:
@keys=$s->list;
eine interne Methode, die benutzt wird, um $obj->session in $obj->session_decoded zu übersetzen.
eine interne Methode, die benutzt wird, um $obj->session_decoded in $obj->session zu übersetzen.
eine interne Methode, um zum Sessionserver Kontakt aufzunehmen.
eine interne Methode, um die Verbindung zum Sessionserver zu trennen. Eine eventuell geöffnete Session wird automatisch geschlossen.
eine interne Methode.
Als Eigenschaften bezeichne ich Werte, die sich auf ein Objekt beziehen. Sie sind als Lvalue-Methoden implementiert, können also mit
$eigenschaft=$obj->name;
gelesen und mit
$obj->name=$eigenschaft;
gesetzt werden.
repräsentiert das Sessionhandle, das vom Benutzer verwendet werden kann.
das Handle, das bei der Kommunikation mit dem Sessionserver benutzt wird. Dieses Handle sollte nicht direkt in WEB Anwendungen benutzt werden, da andere Handles leicht ableitbar sind.
die Adresse des Sessionservers im Format IPADDRESS:PORT, der zur Erzeugung neuer Sessions benutzt wird.
die Adresse des Backups im Format IPADDRESS:PORT.
die aktuell benutzte Verbindung als IO::Socket::INET Objekt.
das Passwort zum Verschlüsseln der Werte einer Session. Es muß beim Anlegen des Opis::Session Objekts oder beim Erzeugen bzw. Öffnen der Session mitgegeben werden. Alternativ kann zwischen Konstruktor und Öffnen/Erzeugen der Session einfach diese Eigenschaft gesetzt werden:
$s->password='streng geheim';
ein Hash mit den aktuellen Metadaten einer Session. Es wird beim Öffnen, Erzeugen und durch Aufruf der options Methode aktualisiert.
%metadata=%{$s->metadata};
Fehler werden von diesem Modul durch Exceptions gemeldet. Als Exception wird kein String, sondern eine Referenz eines Strings benutzt. Damit können Exceptions mit == verglichen werden. Trotzdem sind sprechende Fehlermeldungen möglich:
eval {
$s->open(session=>$handle);
};
if( $@ and ref $@ ) {
if( $@==E_TAMPERED ) {
warn "versuche bitte nicht mich auszutricksen: ${$@}\n";
}
} elsif( $@ ) {
warn "unerwarteter Fehler: $@";
}
Fehlercodes werden auf Anfrage exportiert.
Folgende Fehlercodes sind definiert:
$obj->session konnte nicht korrekt entschlüsselt werden. Möglicherweise ist das ein Versuch, eine fremde Session zu erraten.
sowohl die Verbindung zum Sessionserver als auch zum Backup Server gingen schief.
der Sessionserver hat die Verbindung unerwartet beendet.
eine Session ist von einem Opis::Session Objekt geöffnet und es wird versucht eine weitere Session zu öffnen oder zu erzeugen.
es wurde eine Operation auf einer Session versucht, aber es ist keine Session geöffnet.
es wurde versucht eine nicht-existierende Session zu öffnen. Möglicherweise ist sie einem Timeout zum Opfer gefallen.
die Operation ($obj->set) konnte nicht ausgeführt werden, weil die Session sonst zu groß würde.
die Operation ($obj->set) konnte nicht ausgeführt werden, weil die Anzahl der Namen einer Session sonst die eingestellte Grenze überschreiten würde.
der Sessionserver beendet sich gerade und es ist kein Backupserver angegeben.
Standardmäßig werden keine Funktionen exportiert. Exceptions werden auf Anfrage importiert:
use Opis::Session qw/E_TAMPERED E_HANDLE/; use Opis::Session qw/:all/;
Torsten Förtsch <torsten.foertsch@gmx.net>