Barracuda Application Server C/C++ Reference
HttpSession Struct Reference

Provides a way to identify a user across more than one page request or visit to a web site, and to store information about that user. More...

#include <HttpServer.h>

Public Member Functions

void terminate ()
 Unbinds any objects bound to this session object, runs the HttpSession destructor, and frees the memory for this object. More...
 
HttpSessionAttributegetAttribute (const char *name)
 Returns the object bound with the specified name in this session, or null if no object is bound under the name.
 
BaTime getCreationTime ()
 Returns the time when this session was created, measured in seconds since midnight January 1, 1970 GMT.
 
BaTime getLastAccessedTime ()
 Returns the last time the client sent a request associated with this session, as the number of seconds since midnight January 1, 1970 GMT, and marked by the time the container received the request.
 
BaTime getMaxInactiveInterval ()
 Returns the maximum time interval, in seconds, that the session container will keep this session open between client accesses.
 
HttpServergetServer ()
 Get the server object.
 
int removeAttribute (const char *name)
 Removes the object bound with the specified name from this session.
 
int setAttribute (HttpSessionAttribute *value)
 Binds an object to this session, using the name specified.
 
void setMaxInactiveInterval (BaTime interval)
 Specifies the time, in seconds, between client requests before the session container will invalidate this session.
 
void incrRefCntr ()
 Increments the session reference counter. More...
 
void decrRefCntr ()
 Decrements the session reference counter. More...
 
U32 getId ()
 Returns a unique identifier assigned to this session. More...
 
AuthenticatedUsergetAuthenticatedUser ()
 Returns the AuthenticatedUser if user is authenticated.
 
U32 getUseCounter ()
 Get the session usage counter.
 

Detailed Description

Provides a way to identify a user across more than one page request or visit to a web site, and to store information about that user.

The HttpSession container uses this class to create a session between an HTTP client and an HTTP server. The session persists for a specified time period across more than one connection or page request from the user. A session usually corresponds to one user who may visit a site many times. The server can maintain a session in many ways, for example, by using cookies or rewriting URLs.

This interface enables you to:

  • View and manipulate information about a session, such as the session identifier, creation time, and last accessed time.
  • Bind objects to sessions, allowing user information to persist across multiple user connections

The session is automatically terminated after being inactive for the specified number of seconds. The default value is 1200 seconds, or 20 minutes.

The session object and all the session attributes associated with the session are automatically terminated by the server when "MaxInactiveInterval" is reached.

A malicious user can create a tool that could potentially overflow the session container. The authentication classes make sure that a session object is not created before the user is authenticated. It is therefore recommended to create a session object by using the authentication classes. See HttpSessionContainer::setMaxSessions for more information on the size of the session container.

This class is similar to the java Interface HttpSession.

Garbage Collection

Unlike the Java programming language, C and C++ does not handle garbage collection of released objects. We must explicitly delete the object when using C and C++. This is a problem when using the session object as the session may expire or be terminated by another concurrent request. The web-server is therefore designed to keep track of the sessions by using reference counting. The reference counting is automatic when fetching the session object by using HttpRequest::getSession. The web-server keeps track of the number of concurrent requests using the same object and makes sure that the object is not deleted as long as any request is being serviced.

CSP example

<%
/* Get session and implisitly increment the reference counter */
HttpSession* s = request->getSession();
/* Method getSession may return NULL if not enough memory, if the
 * response is committed, or if HttpSession::terminate was previously
 * called during this request.
 */
if(s)
{
   U32 sessionId = s->getId();
   assert(server->getSession(sessionId) != NULL);

   s->terminate(); /* invalidated, but not terminated */
   /* Method getSession returns null since the object is invalidated.
    */
   assert(request->getSession() == NULL);

   HttpServer* server = request->getServer();

   /* HttpServer::getSession can be used by any code, not just a request
   * callback method. The result is NULL for any code using this
   * sessionId even though the actual session object is still not
   * deleted.
   */
   assert(server->getSession(sessionId) == NULL);

   /* The following is not recommended, but the code will not crash as
    * the object is not yet deleted.
    */
   s->getAttribute("MyAttr");
}
%>

We called method HttpSession::terminate in the above example. The termination of the session object is automatically delayed by the web-server until all concurrent requests using this session object have completed.

The HttpRequest::getSession method automatically handles the reference counting and makes sure that the session object cannot be deleted before at the end of the request. This means that you do not normally have to deal with this problem.

The following methods do not handle the reference counting:

  • HttpServer::getSession

Faulty CSP example:

U32 sessionId = myObj->getMySavedSessionId();
HttpSession* s = request->getServer()->getSession(sessionId);
if(sessionId)
{
   //HttpResponse::printf may yield and another thread may start to execute.
   response->printf("I found the session for ID %u", sessionId);
   s->getAttribute("MyAttr"); // Dangerous, the session may be deleted.
}

Any method that writes data to the socket may yield the current thread. Another request may terminate the session or the session may expire. The above code is therefore unsafe.

We can fix the above problem by explicitly incrementing and decrementing the reference counter.

Correct CSP example:

U32 sessionId = myObj->getMySavedSessionId();
HttpSession* s = request->getServer()->getSession(sessionId);
if(sessionId)
{
   s->incrRefCntr();
   response->printf("I found the session for ID %u", sessionId);
   s->getAttribute("MyAttr");
   /* The above code is safe since the object is locked, but
    * request->getServer()->getSession(sessionId) may return null.
    */
   s->decrRefCntr();
}

It is very important that you keep track of how many times you call incrRefCntr and decrRefCntr. Your system will eventually become unstable if you call one of the methods more than the other.