Catalog Script: Session.pm

This module defines an abstract class for session generation and maintenance using URL rewriting.

package Session;
# modules/Session.pm
# This utility module is an interface to a Session object based on URL rewriting.
# The session ID is stored in the "additional path info" of the URL.  All URLs must
# be passed through rewrite_url() in order to maintain the state.

# manage database sessions with URL rewriting
use strict;
use CGI 'path_info','url';
use Carp;

# return a new session object, possibly retrieving
# id from the additional path info.  May do a redirection
# and exit if a new ID needs to be created.  Therefore this
# should be called before header() or other output.
sub new {
    my $class = shift;
    my $self = bless {},$class;
    $self->initialize(@_);  # class-specific initialization
    my $id = $self->retrieve_id;
    unless ($id && $self->verify_id($id)) {
	$id = $self->new_id;
	$self->do_redirect($id);
	return;
    }
    $self->{'id'} = $id;
    return $self;
}

# erase the ID from the underlying storage
sub erase {
    my $self = shift;
    return $self->erase_id;
}

# return the ID
sub id { return $_[0]->{'id'}; }

# fetch data from the store as a hash reference
sub fetch {
    my $self = shift;
    return $self->fetch_data();
}

# place a hash reference into storage
sub store {
    my $self = shift;
    my $data = shift;
    return $self->store_data($data);
}

# retrieve ID from path info
sub retrieve_id {
    my $self = shift;
    my ($id) = path_info() =~ m!^/(\d+)!;
    return $id;
}

# Please pass all self-referencing URLs through this method
# in order to preserve the session ID.
sub rewrite_url {
    my ($self,$url) = @_;
    my $id = $self->id;  # retrieve ID
    return $url unless defined $id;
    my ($main,$query) = split('\?',$url);
    $main = "../$main" if $main !~ m[^(http:|/)] && path_info();
    return "$main/$id?$query" if     $query;
    return "$main/$id"        unless $query;
}

# do_redirect() is called when a new session ID needs to be generated
sub do_redirect {
    my ($self,$id) = @_;
    $self->{'id'} = $id;
    my $url = $self->rewrite_url(url(-full=>1,-query=>1)); # CGI::url()
    print CGI::redirect($url);   # CGI::redirect()
}

# Class-specific initialization.  Probably want to override.
sub initialize { return bless {},shift; }

# the remainder is to be implemented by subclasses
sub new_id     { croak "new_id() must be implemented by subclass";     }
sub verify_id  { croak "verify_id() must be implemented by subclass";  }
sub erase_id   { croak "erase_id() must be implemented by subclass";   }
sub fetch_data { croak "fetch_data() must be implemented by subclass"; }
sub store_data { croak "store_data() must be implemented by subclass"; }

1;
  


<< Previous
Contents >> Next >>

Lincoln D. Stein, lstein@cshl.org
Cold Spring Harbor Laboratory
Last modified: Sun Apr 25 14:09:22 EDT 1999