The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

  HTML::EP::Session - Session management for the HTML::EP package

SYNOPSIS

  <ep-comment>
    Create a new session or open an existing session
  </ep-comment>
  <ep-session id="$cgi->id$" var="cart">

  <ep-comment>
    Modify the session by putting an item into the shopping cart
  </ep-comment>
  <ep-perl>
    my $_ = $self; my $cart = $self->{'cart'};
    my $items = $cart->{'items'} || {};
    my $cgi = $self->{'cgi'};
    $items->{$cgi->param('item_id')} = $cgi->param('num_items');
  </ep-perl>

  <ep-comment>
    Same thing by using the ep-item command
  </ep-comment>
  <ep-session-item item="$cgi->item_id"
   num="$cgi->num_items">

  <ep-comment>
    Store the session
  </ep-comment>
  <ep-session-store>

DESCRIPTION

The HTML::EP::Session package is something like a little brother of Apache::Session: Given an ID and a structured Perl variable called the session, it stores the session into a DBI database, an external file or whatever you prefer. For example you like to use this in shopping carts: The shopping cart could look like this

  $session = {
    'id' => '21A32DE61A092DA1',
    'items' => { '10043-A' => 1, # 1 item of article '10043-A'
                 '10211-C' => 2  # 2 items of article '10211-C'
               }
  }

The package takes the session, converts it into a string representation by using the Storable or FreezeThaw module and saves it into some non-volatile storage space. The storage method is choosen by selecting an appropriate subclass of HTML::EP::Session, for example HTML::EP::Session::DBI, the default class using DBI, the database independent Perl interface or HTML::EP::Session::File for using flat files.

Creating or opening a session

  <ep-session class="HTML::EP::Session::DBI" table="sessions"
              var=session id="$@cgi->id$" hex=0>

If the attribute id is empty or not set, this will create a new and empty session for you. Otherwise the existing session with the given id will be opened.

By default the session will have class HTML::EP::Session::DBI and data will be stored in the table sessions, but you can choose another subclass of HTML::EP::Session for saving data. The session is stored in the session variable of the object, but that is overridable with the var attribute.

Some storage systems don't support NUL bytes. The hex attribute forces conversion of session strings into hex strings, if set to on. The default is off.

Some session classes, in particular the DBI session class, will generate an ID for you, if required. That ID can by retrieved by looking at

        $self->{'_ep_session_id'}

or, within an HTML page with

        $_ep_session_id$

Storing the session

  <ep-session-store locked=0>

This stores the session back into the non-volatile storage. By default the session is unlocked at the same time and must not be modified in what follows, unless you set the optional locked attribute to a true value.

Managing a shopping cart

As a helper for shopping carts you might use the following command:

  <ep-session-item item="$cgi->item$" num="$cgi->num$">

This command uses a hash ref items in the shopping cart, the hash will be created automatically. The value num is stored in the hashs key item. Alternatively you might use

  <ep-session-item item="$cgi->item$" add="$cgi->num$">

which is very much the same, but the item is incremented by add.

Deleting a session

You can delete an existing session with

  <ep-session-delete>

LOCKING CONSIDERATIONS

All subclasses have to implement a locking scheme. To keep this scheme clean and simple, the following rules must be applied:

1.)

First of all, acquire the resources that the respective subclass needs. In the case of the DBI subclass this means that you have to execute the ep-database command.

2.)

Next you create or open the session.

3.)

If required, do any modifications and call ep-session-store or ep-session-delete.

4.)

Once you have called ep-session-store or ep-session-delete, you most not use any more ep-session commands.

SUBCLASS INTERFACE

Subclasses of HTML::EP::Session must implement the following methods:

new($ep, $id, \%attr)

(Class method) This constructor creates a new session with id $id. The constructor should configure itself by using the EP object $ep and the attribute hash ref \%attr.

Open($ep, $id, \%attr)

(Class method) This constructor must open an existing session.

Store($ep, $id, $locked)

(Instance method) Stores the session. The $locked argument advices to keep the session locked (TRUE) or unlocked (FALSE).

Delete($ep, $id)

Error handling in subclasses is simple: All you need to do is throwing a Perl exception. If subclasses need to maintain own data, they should store it in $ep->{'_ep_session_data'}. The id is stored in $ep->{'_ep_session_id'}.

The DBI subclass

This class is using the DBI (Database independent Perl interface), sessions are stored in a table. The table name is given by the table attribute and defaults to sessions. The table structure is like

  CREATE TABLE SESSIONS (
      ID INTEGER NOT NULL PRIMARY KEY,
      SESSION LONGVARCHAR,
      ACCESSED TIMESTAMP,
      LOCKED INTEGER
  )

in particular the SESSION column must be sufficiently large. I suggest using something like up to 65535, for example I am using SHORT BLOB with MySQL.

The SESSION column must accept binary characters, in particular NUL bytes. If it doesn't, you need to replace the Storable package with FreezeThaw. Storable(3). FreezeThaw(3).

Ilya Ketris (ilya@gde.to) has pointed out, that these column names are causing problems from time to time. He suggested to use queries like

  INSERT INTO $table ("ID", "SESSION", ...

instead. This is of course higly incompatible to other engines. To fix that problem, I have added a subclass of HTML::EP::Session::DBI, called HTML::EP::Session::DBIq (quoted). You use it by just replacing the class name in the ep-session statement.

This class is using Cookies, as introduced by Netscape 2. When using Cookies for the session, you have to use a slightly different syntax:

  <ep-session class="HTML::EP::Session::Cookie" id="sessions"
              var=session id="$@cgi->id$" expires="+1h"
              domain="www.company.com" path="/"
              zlib=0 base64=0>

The attribute id is the cookie's name. (Cookies are name/value pairs.) The optional attributes expires, domain and path are referring to the respective attributes of CG::Cookie->new(). CGI::Cookie(3).

Cookies are unfortunately restricted to a certain size, about 4096 bytes. If your session is getting too large, you might try to reduce the cookie size by using the Compress::Zlib and/or MIME::Base64 module. This is enabled by adding the parameters zlib=1 and/or base64=1.

The Dumper subclass

This is, in some sense, an unusual class for sessions: All users are sharing a single session, unlike the DBI and Cookie subclasses, which implement one session per user. I enjoy using the Dumper subclass anyways, for example to implement site wide preferences.

What the class does is creating a file which holds a single hash ref. This hash ref is created using the Data::Dumper package. Data::Dumper(3).

You create a Dumper session like this:

  <ep-session class="HTML::EP::Session::Dumper"
              id="/var/tmp/my.session" var="prefs">

In other words, the session ID is just the name of the file.

MULTIPLE SESSION

When looking at the Cookie and Dumper subclass, the question arises: Can I use multiple sessions within a single HTML page? Of course you can!

However, there are a few drawbacks:

1.)

The variable $_ep_session_id$ always contains the ID of the last created session. After you have created the first session, it will contains this sessions ID. If you create another session, the variable will change to the new ID.

2.)

You must use the attributes var=something and id=something with any call to ep-session, ep-session-store, ep-session-delete and ep-session-item.

AUTHOR AND COPYRIGHT

This module is

    Copyright (C) 1998    Jochen Wiedmann
                          Am Eisteich 9
                          72555 Metzingen
                          Germany

                          Phone: +49 7123 14887
                          Email: joe@ispsoft.de

All rights reserved.

You may distribute this module under the terms of either the GNU General Public License or the Artistic License, as specified in the Perl README file.

SEE ALSO

HTML::EP(3), Apache::Session(3), DBI(3), Storable(3), FreezeThaw(3), CGI::Cookie(3)