Try It Out
The Session plugin does not do anything on its own -- it works in conjunction with other plugins. Nevertheless, you still set it up as any other plugin, and it needs to be enabled to work just as any other plugin.
What It Does
A "session" is a place to store per-client data which is intended to last the duration of a session, or sequence of HTTP transactions. You can attach arbitrary objects to this session, e.g., list of items in a shopping cart or user preferences, using the put/get/removeValue methods of HttpSession. For a very simple of how to use HttpSession, see the file sample.txt.
How It Works
Many session implementations, including this one, use HTTP cookies to store the key or index into the session table. So the HttpSessionContext stores a table of current sessions, and the browser stores the key corresponding to its session in an HTTP cookie.
When a call to getSession is invoked, the HTTP request header is inspected for an appropriate cookie. If the cookie exists, then the corresponding session is retrieved. If the cookie is not set and the create flag is true, then a new session is created and a flag is set to add a set-cookie header. Later, an Editor checks for that flag and sets the cookie if it exists. This two-step process is necessary so that it is possible to get a session from a Request Editor or Generator before the HTTP response header has been set.
Since this session implementation is based on HTTP cookies, it is subject to some of their limitations. One problem is that it is possible that clients might not support or explicitly disable cookies. Another issue is that cookies are, by default, set to be returned only to the host from which they were issued. It is possible to set the domain flag, using the optional third argument to getSession, however this does not address the problem where you want a session to persist over multiple domains, as you might want to do with the WBI proxy.
Depending on your application, you may want sessions to persist over restarts of the WBI proxy or not. Support is available for both non-persistent and persistent sessions. Non-persistent support works simply by storing the sessions in a java.util.Hashtable, and thus in memory. Persistent sessions work by storing the session in WBI's built-in persistence database. This support, unfortunately, is not scalable since it doesn't handle the problems of garbage collection or efficient management of large numbers of sessions. However, it is possible to write your own persistence system, possibly based on SQL, LDAP or Berkeley DB, etc., and plug it into the session plugin. You simply need to subclass HttpSessionPlugin and set the member variable dict to an implementation of java.util.Dictionary that stores the key/value pairs in your backend. You can see HttpSessionPersistentPlugin.java for an example of how to do this.
Since the session plugin is an implementation of the session portion of Sun©'s servlet API version 2.x, you will need the corresponding jar file in your classpath for building or running the session plugin, as well as plugins that rely upon it.
Some parts of the interface exposed by this plugin are specific to WBI, and will be explained here. For all other information, please be sure to review the documentation at Sun©.
In order to get an HttpSession, you first need a handle to a HttpSessionContext. This is done within a Meg's handleRequest method as:
HttpSessionContext ctx = (HttpSessionContext)getSystemContext().getUserData("session-ctx");The SystemContext is, among other things, a place where plugins can share data using the get/setUserData methods. When it is initialized, the HttpSessionPlugin adds the context to this table. It is important to understand that the order of initialization of plugins in WBI is undefined, so care must be taken to ensure that your plugin retrieves the value of session-ctx after the HttpSessionPlugin is loaded and initialized. The easiest way to ensure this is to get the session each time you handle a request in your Meg. If you're concerned about this extra computation with each request, you might cache that reference in a member variable.
The Session plugin is composed of a single Meg, a low-priority Editor, which runs if the $session-create extra rule key is set. Extra rule keys are useful in cases like this to communicate between megs using the dynamic condition or rule system. This Meg is responsible for adding the set-cookie HTTP header.
Some key WBI classes that were used: