From: Gonzalo A. <ga...@us...> - 2006-09-08 14:31:03
|
Update of /cvsroot/mod-c/ehtml/include In directory sc8-pr-cvs7.sourceforge.net:/tmp/cvs-serv15294/include Modified Files: Session.h Log Message: Session handling shifted from mod_c to EHTML (more work on this to come). Session handling is divided into: - Session ID generation (SessionIDDriver class/Session.h) - Session storage (SessionDrive class/Session.h) - Session usage: o serialization & marshalling, o accessing/setting session variables, (Session classs/Session.h) Index: Session.h =================================================================== RCS file: /cvsroot/mod-c/ehtml/include/Session.h,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** Session.h 6 Mar 2006 08:00:34 -0000 1.8 --- Session.h 8 Sep 2006 14:30:58 -0000 1.9 *************** *** 22,46 **** #define _SESSION_H_ - #include "ehtml.h" - #include <time.h> #include <string> /** ! * A pointer to the function that should deallocate data provided in the first ! * parameter of <code>Session::ClearData</code>. */ ! typedef void (*DeallocatorFunc)(void *); /** ! * The default deallocator. This one does nothing because memory allocation in ! * the Session class is done with Apache's memory pools. These need not be ! * deallocated. ! * <p>If you allocate data with <code>apr_palloc</code>, then you can use the ! * default deallocator without the fear of memory leaks.</p> */ ! void DefaultDeallocator( void * Data ); ! class EHTMLApplication; /** --- 22,199 ---- #define _SESSION_H_ #include <time.h> + + #ifdef __cplusplus + + #include "ehtml.h" + #include "EHTMLApplication.h" + #include "Plugin.h" + #include "Dictionary.h" + #include "MemBuf.h" #include <string> + class EHTMLApplication; + class Session; + + class SessionID { + MemBuf _binary; + mutable std::string _base64; + mutable std::string _hex; + mutable std::string _urlencoded; + + mutable unsigned _binary_set: 1; + mutable unsigned _base64_set: 1; + mutable unsigned _hex_set: 1; + mutable unsigned _url_set: 1; + + public: + SessionID(); + SessionID(const SessionID& id); + SessionID(void* b, size_t nbytes, bool dup = false); + ~SessionID(); + + MemBuf& binary() throw (const char*); + const MemBuf& binary() const throw (const char*); + bool binary(MemBuf&); + + std::string& base64() throw (const char*); + const std::string& base64() const throw (const char*); + bool base64(std::string&); + + std::string& hex() throw (const char*); + const std::string& hex() const throw (const char*); + bool hex(std::string&); + + std::string& urlencoded() throw (const char*); + const std::string& urlencoded() const throw (const char*); + bool urlencoded(std::string&); + }; + + class SessionIDDriver; /** ! * Session id generation class. ! * Each subclass provide a different algorightm for session id generation. */ ! class SessionIDDriver: public Pluggable<SessionIDDriver> { ! public: ! /** ! * Set arguments for algorithm tunning. May be called more than once. ! * @return false on error. true on success. ! */ ! virtual bool SetArgs(const std::string& arg) = 0; ! virtual bool ValidID(SessionID& id) = 0; ! virtual SessionID GenerateID() = 0; ! }; ! ! class SessionDriver; ! class SessionDriver: public Pluggable<SessionDriver> { ! EHTMLApplication* _app; ! public: ! /** ! * SessionDrvier default constructor (must not be used). ! */ ! SessionDriver(): _app(NULL) { ! } ! ! /** ! * SessionDriver destructor. ! */ ! virtual ~SessionDriver(); ! ! /** ! * Sets arguments. May be called more than once. ! * @return false on error, true otherwise. ! */ ! virtual bool SetArgs(const std::string& arg) = 0; ! ! /** ! * Sets the application to use. May be called more than once. ! * @return false on error, true otherwise. ! */ ! virtual void Application(EHTMLApplication* app) { _app = app; } ! ! /** ! * Connect to backend. ! * @return false on error. ! */ ! virtual bool Connect() = 0; ! ! /** ! * Disconnect from backend. ! * @return false on error. ! */ ! virtual bool Disconnect() = 0; ! ! /** ! * Retrieve a session from the store. ! * @param id ! * id of the session to retrieve ! * @return NULL on error or if session is not found. ! */ ! virtual Session* Get(const SessionID& id) = 0; ! ! /** ! * Retrieve a session from query string or cookie from the store. ! * The session is locked to avoid overlapping updates. ! */ ! virtual Session* Get(); ! ! /** ! * Save the session in the store. ! * @return false on error. ! */ ! virtual bool Save(Session*) = 0; ! ! /** ! * Remove the session (id) from the store. ! * @return false if session is not found or if there is no connection ! * to the backend. ! */ ! virtual bool Remove(Session*) = 0; ! ! /** ! * Release the session lock. ! */ ! virtual bool Release(Session*) = 0; ! }; ! #define EXTERNC extern "C" ! #else /* ifdef __cplusplus */ ! #define EXTERNC extern ! #endif /** ! * Registers a session driver. ! * Registers the session driver "<param>driver_name</param>" located in ! * <param>filename</param>. ! * Note that this has C linkeage. ! * @return 0 on success, a negative value on error. */ ! EXTERNC int registerSessionDriver(const char* driver_name, const char* filename); ! /** ! * Selects a session driver (and sets the argument). ! * See each session driver for specific format and values of ! * <param>arg</param>. ! * @return 0 on success, a negative value on error. ! */ ! EXTERNC int useSessionDriver(const char* name, const char* arg); ! ! /** ! * Registers a session id generation driver. ! * Registers the session driver "<param>driver_name</param>" located in ! * <param>filename</param>. ! * Note that this has C linkeage. ! * @return 0 on success, a negative value on error. ! */ ! EXTERNC int registerSessionIDDriver(const char* driver_name, const char* filename); ! /** ! * Selects a session id generation driver (and sets the argument). ! * See each session driver for specific format and values of ! * <param>arg</param>. ! * @return 0 on success, a negative value on error. ! */ ! EXTERNC int useSessionIDDriver(const char* name, const char* arg); ! ! #ifdef __cplusplus /** *************** *** 51,431 **** * application in the 'init' stage. If there is no session to restore, the * application does not create one! EHTML is designed not to use per session ! * data if not needed by the application. A session is created if and only if an ! * old session has not been restored AND the developer first writes some session ! * data.</p> * <p>Session data is written to the server in the 'finish' stage.</p> */ ! class Session ! { ! public: ! /** ! * Initialises a connection with the session server. This function has ! * no effect if a connection has already been initialised. ! */ ! int InitConnection(); ! /** ! * Closes a connection with the session server. This function has no ! * effect if a connection has already been closed. ! */ ! int CloseConnection(); ! /** ! * Returns the ID of the current session. ! * ! * @return A binary array containing the Id. This function returns ! * <code>NULL</code> if a session is not valid. ! * <p>Call the <code>GetIdSize</code> function to obtain the ! * size of this array.</p> ! */ ! const void * GetId() const { return Data.Id; } ! /** ! * Returns the size of the session ID. ! * ! * @return the size of the session ID. This function should not be used ! * to determine whether a session is valid or not. Use ! * <code>IsValid</code> or <code>GetId</code> ! * instead. ! */ ! int GetIdSize() const { return Data.IdSize; } ! /** ! * Returns the duration of the session in minutes. ! * ! * @return the duration of the session in minutes. ! */ ! int GetDuration() const { return Data.Duration; } ! /** ! * Sets the duration of a session in minutes. This method fails if the ! * session is not valid or not connected. ! * ! * @param Duration ! * The duration of a session in minutes. ! * ! * @return Returns <code>EHTML_OK</code> on success. ! */ ! int SetDuration( int Duration ); ! /** ! * Returns the time (in seconds since 1970) when the session was ! * created. ! * ! * @return the time (in seconds since 1970) when the session was ! * created. ! */ ! time_t GetCreationTime() const { return Data.SessionStarted; } ! /** ! * Returns the time (in seconds since 1970) when the session was last ! * accessed. ! * ! * @return the time (in seconds since 1970) when the session was last ! * accessed. ! */ ! time_t GetAccessTime() const { return Data.LastAccess; } ! /** ! * Returns the time (in seconds since 1970) when the session was last ! * modified (with <code>Store</code>). ! * ! * @return the time (in seconds since 1970) when the session was last ! * modified (with <code>Store</code>). ! */ ! time_t GetModificationTime() const { return Data.Modified; } ! /** ! * Tries to write current data to the server. This method fails if the ! * session is not valid or not connected. ! * ! * @return Returns <code>EHTML_OK</code> on success. ! */ ! int Store(); ! /** ! * Tries to reload the data from the server. This method fails if the ! * session is not valid or not connected. ! * ! * @return Returns <code>EHTML_OK</code> on success. ! */ ! int Reload(); ! /** ! * Returns stored data with the given name. ! * ! * @param Data ! * The method will store the pointer to the data into this ! * parameter. ! * ! * @return The size of the data array. ! */ ! int GetData( void ** Data ); ! /** ! * Sets the data for this session. ! * <p>Any previous data is deallocated with the current deallocator. So ! * never set the data which is already set.</p> ! * ! * @param Data ! * The actual data. ! * ! * @param DataSize ! * The size of the data array. ! * ! * @param Deallocator ! * The function with which to deallocate the newly set data ! * upon destruction. ! * <p>If you allocate data with <code>apr_palloc</code>, ! * then you don't have to provide a deallocator.</p> ! */ ! void SetData( void * Data = NULL, int DataSize = 0, DeallocatorFunc Deallocator = NULL ); ! /** ! * Deletes data as stored in the session. It deallocates data with the ! * current deallocator. ! */ ! void DeleteData(); ! /** ! * Unregisters the current session. The session is 'lost forever' with ! * this call. ! * <p>The session becomes <b>invalid</b> after the call of ! * this method and can not be used anymore (the behaviour of many ! * methods of this class is undefined when the session is invalid).</p> ! * <p>The connection is also closed with this method.</p> ! * ! * @return Returns <code>EHTML_OK</code> on success. ! */ ! int Unregister(); ! /** ! * Returns a value that indicates whether this session object is valid ! * or not. ! */ ! bool IsValid() const { return Data.Id != NULL; } ! /** ! * Indicates whether a connection with the session server has been ! * initialised. ! */ ! bool IsConnected() const { return ConnectionInited; } ! /** ! * Returns a usable string that represents the ID of the current ! * session. ! * ! * @return Returns a string representation of this session. ! */ ! const std::string & GetIdString() const; ! /** ! * Tries to restore the session. ! * <p>If the argument <code>Id</code> equals <code>NULL</code>, then ! * this method tries to look for the ID in the cookie with the name ! * <code><b>SessionIdName</b></code>.</p> ! * <p>If the application is configured to be cookieless and the ! * argument <code>Id</code> equals <code>NULL</code>, then this method ! * tries to find the name <code><b>SessionIdName</b></code> in the query ! * string.</p> ! * <p>This method returns a valid pointer to a restored sesstion if ! * and only if the session has been completely restored. If the session ! * has not been restored, <code>NULL</code> is returned to indicate the ! * error.</p> ! * ! * @param App ! * A reference to the main EHTML application which contains ! * mod_c configuration structures and the Session Management ! * API. ! * ! * @param Id ! * The Id of the session to be restored (may be ! * <code>NULL</code> to automatically resolve the Id from a ! * cookie or from the query). ! * ! * @param IdSize ! * The size of the Id. ! * ! * @return a valid pointer to a restored sesstion if ! * and only if the session has been completely restored. If the ! * session has not been restored, <code>NULL</code> is returned ! * to indicate the error. ! * <p><b>Note</b>: You mustn't delete the returned session ! * when you stop using it - sessions are deleted automatically ! * by <code>EHTMLApplication</code> in the finish stage where ! * <code>EHTMLApplication</code> calls the ! * <code>EHTMLApplication::ShutSessionsDown</code>.</p> ! */ ! static Session * RestoreSession( EHTMLApplication & App, const void * Id = NULL, int IdSize = 0 ); ! /** ! * Tries to restore the session. ! * <p>This method returns a valid pointer to a restored sesstion if ! * and only if the session has been completely restored. If the session ! * has not been restored, <code>NULL</code> is returned to indicate the ! * error.</p> ! * ! * @param App ! * A reference to the main EHTML application which contains ! * mod_c configuration structures and the Session Management ! * API. ! * ! * @param Id ! * The string representation of the Id of the session to be ! * restored. ! * ! * @return a valid pointer to a restored sesstion if ! * and only if the session has been completely restored. If the ! * session has not been restored, <code>NULL</code> is returned ! * to indicate the error. ! * <p><b>Note</b>: You mustn't delete the returned session ! * when you stop using it - sessions are deleted automatically ! * by <code>EHTMLApplication</code> in the finish stage where ! * <code>EHTMLApplication</code> calls the ! * <code>EHTMLApplication::ShutSessionsDown</code>.</p> ! */ ! static Session * RestoreSession( EHTMLApplication & App, const std::string & Id ); ! /** ! * Tries to restore the session. ! * <p>This method returns a valid pointer to a restored sesstion if ! * and only if the session has been completely restored. If the session ! * has not been restored, <code>NULL</code> is returned to indicate the ! * error.</p> ! * ! * @param App ! * A reference to the main EHTML application which contains ! * mod_c configuration structures and the Session Management ! * API. ! * ! * @param Id ! * The string representation of the Id of the session to be ! * restored. ! * ! * @return a valid pointer to a restored sesstion if ! * and only if the session has been completely restored. If the ! * session has not been restored, <code>NULL</code> is returned ! * to indicate the error. ! * <p><b>Note</b>: You mustn't delete the returned session ! * when you stop using it - sessions are deleted automatically ! * by <code>EHTMLApplication</code> in the finish stage where ! * <code>EHTMLApplication</code> calls the ! * <code>EHTMLApplication::ShutSessionsDown</code>.</p> ! */ ! static Session * RestoreSession( EHTMLApplication & App, const char * Id ); ! /** ! * Creates a new session. It registers an Id in the session manager and ! * stores the acquired configuration in the <code>PerSessionData</code> ! * structure. ! * ! * @param App ! * A reference to the main EHTML application which contains ! * mod_c configuration structures and the Session Management ! * API. ! * ! * @param IdSize ! * The desired size of the Id. ! * ! * @param Duration ! * The desired session duration. ! * ! * @return a valid pointer to a new session on success, otherwise it ! * returns <code>NULL</code>. ! * <p><b>Note</b>: You mustn't delete the returned session ! * when you stop using it - sessions are deleted automatically ! * by <code>EHTMLApplication</code> in the finish stage where ! * <code>EHTMLApplication</code> calls the ! * <code>EHTMLApplication::ShutSessionsDown</code>.</p> ! */ ! static Session * CreateSession( EHTMLApplication & App, int IdSize = 0, int Duration = 0 ); ! /** ! * The key with which one should name the cookie or the query string ! * that contains the main session ID string. ! */ ! static const std::string SessionIdName; ! protected: ! friend class EHTMLApplication; ! /** ! * The default constructor is disabled and throws errors. ! */ ! Session() throw ( const char * ); ! /** ! * Creates a new and uninitialised session. ! */ ! Session( EHTMLApplication & App ); ! ~Session(); ! /** ! * Recovers data from the server. If the session is not yet registered ! * this method fails. ! * ! * @param Id ! * The Id of the session to be restored (may be ! * <code>NULL</code> to automatically resolve the Id from a ! * cookie or from the query). ! * ! * @param IdSize ! * The size of the Id. ! * ! * @return Returns <code>EHTML_OK</code> on success. ! */ ! int Restore( void * Id = NULL, int IdSize = 0 ); ! /** ! * Recovers data from the server. If the session is not yet registered ! * this method fails. ! * ! * @param Id ! * The Id of the session to be restored. ! * ! * @return Returns <code>EHTML_OK</code> on success. ! */ ! int Restore( const char * Id ); ! /** ! * Recovers data from the server. If the session is not yet registered ! * this method fails. ! * ! * @param Id ! * The Id of the session to be restored. ! * ! * @return Returns <code>EHTML_OK</code> on success. ! */ ! int Restore( const std::string & Id ); ! /** ! * Registers a new session. Closes the existing session if one is open. ! * ! * @return Returns <code>EHTML_OK</code> on success. ! */ ! int Register(); ! /** ! * Sets the desired size of the ID and the duration of the session. ! * This procedure has no effect if the session is already valid. ! * ! * @param IdSize ! * The desired size of the Id. ! * ! * @param Duration ! * The desired session duration. ! */ ! void SetInitConfig( int IdSize, int Duration ); ! ! protected: ! /** ! * This record stores configuration data as returned by the session ! * manager. ! */ ! PerSessionData Data; ! /** ! * Current deallocator. ! */ ! DeallocatorFunc Dealloc; ! /** ! * The owning application. ! */ ! EHTMLApplication * Application; ! /** ! * The session API to use. ! */ ! ses_api_t * SessionApi; ! /** ! * Driver data. ! */ ! void * DrData; ! /** ! * Request context. ! */ ! __request_context * ReqCon; ! /** ! * The string representation of the id. ! */ ! std::string EncodedId; ! /** ! * Indicates whether a connection was initialized or not. ! */ ! bool ConnectionInited; ! /** ! * Indicates whether this session is broken. ! */ ! bool IsBroken; }; #endif /*_SESSION_H_*/ --- 204,360 ---- * application in the 'init' stage. If there is no session to restore, the * application does not create one! EHTML is designed not to use per session ! * data if not needed by the application. A session is created if and only if ! * an old session has not been restored AND the developer first writes some ! * session data.</p> * <p>Session data is written to the server in the 'finish' stage.</p> */ ! class Session: public Dictionary { ! protected: ! static bool _cookie_less; /**< true iff the session is cookie-based */ ! static std::string _session_id_name; /**< cookie name for session id */ ! public: ! /** ! * RO accessor of @ref _cookie_less. ! * @return true iff session is NOT cookie-based. ! */ ! static bool CookieLess() { return _cookie_less; } ! ! /** ! * WO accessor of @ref _cookie_less. ! * @param cookie_less new value of _cookie_less. ! */ ! static void CookieLess(bool cookie_less) { ! _cookie_less = cookie_less ? true : false; ! } ! ! /** ! * RO accessor of @ref _session_id_name. ! * @return the name of the cookie where the session id is stored. ! */ ! static const std::string& SessionIDName() { ! return _session_id_name; ! } ! ! /** ! * WO accessor of @ref _session_id_name. ! * @param s the name of the cookie. ! */ ! static void SessionIDName(const std::string& s) { ! _session_id_name = s; ! } ! ! protected: ! time_t _expires; /**< expiration date/time */ ! time_t _started; /**< start time */ ! time_t _last_access; /**< last access time */ ! time_t _modification; /**< last modification time */ ! SessionID _id; /**< this session id */ ! ! public: ! /** ! * Default session constructor. ! */ ! Session(): _expires(0) { ; } ! ! /** ! * Session constructor. ! */ ! Session(const SessionID& __id): _expires(0), _id(__id) { ; } ! ! /** ! * Session destructor. ! */ ! virtual ~Session(); ! ! //@todo I'm not happy with this, anyone can modify last access?? ! //RW accessors should be friend of SessionDriver. ! ! /** ! * Sets session last access date/time. ! */ ! void LastAccess(time_t __last_access) { _last_access = __last_access; } ! ! /** ! * Gets session last access date/time. ! */ ! time_t LastAccess(void) { return _last_access; } ! ! /** ! * Sets session modification date/time. ! */ ! void Modification(time_t __mtime) { _modification = __mtime; } ! ! /** ! * Gets session modification date/time. ! */ ! time_t Modification(void) { return _modification; } ! ! /** ! * Sets session start date/time. ! */ ! void Started(time_t __started) { _started = __started; } ! ! /** ! * Gets session start date/time. ! */ ! time_t Started(void) { return _started; } ! ! /** ! * Sets session expiration date/time. ! */ ! void Expires(time_t __expires) { _expires = __expires; } ! ! /** ! * Gets session expiration date/time. ! */ ! time_t Expires(void) { return _expires; } ! ! //{set,get,unset}Value: use operator[](), find(), erase(). ! ! /** ! * Gets session id. ! */ ! ! const SessionID& ID() const { return _id; } ! /** ! * Gets session id. ! */ ! SessionID& ID() { return _id; } ! ! /** ! * Session serialization. ! * ! * Represents session object in a printable (multiline) string, ! * suitable for saving in a platform-indedent (!?) maner. ! * ! * @todo This should be a const memeber. But making dict as mutable ! * is not an option. ! */ ! std::string Serialize(); ! ! /** ! * Session marshalling. ! * ! * This is the opposite of serialization. Given a textual printable ! * (multiline) representation, this method restores the session state. ! */ ! bool Marshall(const std::string& s); ! ! friend std::ostream& operator << (std::ostream& o, Session& s); ! friend std::istream& operator >> (std::istream& i, Session& s); }; + /** + * Session serialization operator (@see Session::serialize). + */ + std::ostream& operator << (std::ostream& o, Session& s); + + /** + * Session marshalling operator (@see Session::marshall). + */ + std::istream& operator >> (std::istream& i, Session& s); + + #endif + #endif /*_SESSION_H_*/ |