libnavajo
web server for static and dynamic pages developement in C++
HttpSession.hh
Go to the documentation of this file.
1 //****************************************************************************
12 //****************************************************************************
13 
14 #ifndef HTTPSESSION_HH_
15 #define HTTPSESSION_HH_
16 
17 #include <map>
18 #include <vector>
19 #include <string>
20 #include <sstream>
21 
22 #include <stdlib.h>
23 
25 {
26  public:
27  virtual ~SessionAttributeObject() {};
28 };
29 
31 {
32  typedef struct {
33  enum{BASIC, OBJECT} type;
34  union
35  {
36  void *ptr;
38  };
39  } SessionAttribute;
40 
41 
42  typedef std::map <std::string, std::map <std::string, SessionAttribute>* > HttpSessionsContainerMap;
43 
44  static HttpSessionsContainerMap sessions;
45  static pthread_mutex_t sessions_mutex;
46  static time_t lastExpirationSearchTime;
47  static time_t sessionLifeTime;
48 
49  public:
50 
51  inline static void setSessionLifeTime(const time_t sec) { sessionLifeTime = sec; };
52 
53  inline static time_t getSessionLifeTime() { return sessionLifeTime; };
54 
55  /**********************************************************************/
56 
57  static void create(std::string& id)
58  {
59 
60  const size_t idLength=128;
61  const char elements[] = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
62  const size_t nbElements = sizeof(elements) / sizeof(char);
63  srand(time(NULL));
64 
65  id.reserve(idLength);
66 
67  do
68  {
69  id.clear();
70  for(size_t i = 0; i < idLength; ++i)
71  id+=elements[rand()%(nbElements - 1)];
72  }
73  while (find(id));
74 
75  pthread_mutex_lock( &sessions_mutex );
76  sessions[id]=new std::map <std::string, SessionAttribute>();
77  pthread_mutex_unlock( &sessions_mutex );
78  time_t *expiration=(time_t *)malloc(sizeof(time_t));
79  *expiration=time(NULL)+sessionLifeTime;
80  setAttribute(id, "session_expiration", expiration);
81 
82  // look for expired session (max every minute)
83  if (time(NULL) > lastExpirationSearchTime + 60)
84  {
85  removeExpiredSession();
86  lastExpirationSearchTime = time(NULL);
87  }
88  };
89 
90  /**********************************************************************/
91 
92  static void updateExpiration(const std::string& id)
93  {
94  time_t *expiration=(time_t*)getAttribute(id, "session_expiration");
95  if (expiration != NULL)
96  *expiration=time(NULL)+sessionLifeTime;
97  };
98 
99  /**********************************************************************/
100 
101  static void noExpiration(const std::string& id)
102  {
103  time_t *expiration=(time_t*)getAttribute(id, "session_expiration");
104  if (expiration != NULL)
105  *expiration=0;
106  };
107 
108  /**********************************************************************/
109 
110  static void removeExpiredSession()
111  {
112 
113  pthread_mutex_lock( &sessions_mutex );
114  HttpSessionsContainerMap::iterator it = sessions.begin();
115  for (;it != sessions.end(); )
116  {
117  std::map <std::string, SessionAttribute>* attributesMap=it->second;
118  std::map <std::string, SessionAttribute>::iterator it2 = attributesMap->find("session_expiration");
119  time_t *expiration=NULL;
120  if (it2 != attributesMap->end()) expiration=(time_t*) it2->second.ptr;
121 
122  if (expiration!=NULL && *expiration && *expiration > time(NULL))
123  {
124  it++;
125  continue;
126  }
127 
128  removeAllAttribute(attributesMap);
129  delete attributesMap;
130  sessions.erase(it++);
131  }
132  pthread_mutex_unlock( &sessions_mutex );
133  }
134 
135  /**********************************************************************/
136 
137  static void removeAllSession()
138  {
139  pthread_mutex_lock( &sessions_mutex );
140  HttpSessionsContainerMap::iterator it = sessions.begin();
141  for (;it != sessions.end(); )
142  {
143  std::map <std::string, SessionAttribute>* attributesMap=it->second;
144  removeAllAttribute(attributesMap);
145  delete attributesMap;
146  sessions.erase(it++);
147  }
148  }
149 
150  static bool find(const std::string& id)
151  {
152 
153  bool res;
154  pthread_mutex_lock( &sessions_mutex );
155  res=sessions.size() && sessions.find(id) != sessions.end() ;
156  pthread_mutex_unlock( &sessions_mutex );
157  if (res)
158  updateExpiration(id);
159 
160  return res;
161  }
162 
163  /**********************************************************************/
164 
165  static void remove(const std::string& sid)
166  {
167  pthread_mutex_lock( &sessions_mutex );
168  HttpSessionsContainerMap::iterator it = sessions.find(sid);
169  if (it == sessions.end()) { pthread_mutex_unlock( &sessions_mutex ); return; };
170  removeAllAttribute(it->second);
171  delete it->second;
172  sessions.erase(it);
173  pthread_mutex_unlock( &sessions_mutex );
174  }
175 
176  /**********************************************************************/
177 
178  static void setObjectAttribute ( const std::string &sid, const std::string &name, SessionAttributeObject *sessionAttributeObject )
179  {
180  pthread_mutex_lock( &sessions_mutex );
181  HttpSessionsContainerMap::const_iterator it = sessions.find(sid);
182 
183  if (it == sessions.end()) { pthread_mutex_unlock( &sessions_mutex ); return; };
184 
185  SessionAttribute attribute;
186  attribute.type=SessionAttribute::OBJECT;
187  attribute.obj=sessionAttributeObject;
188  it->second->insert(std::pair<std::string, SessionAttribute>(name, attribute ));
189  pthread_mutex_unlock( &sessions_mutex );
190  }
191 
192  /**********************************************************************/
193 
194  static void setAttribute ( const std::string &sid, const std::string &name, void* value )
195  {
196  pthread_mutex_lock( &sessions_mutex );
197  HttpSessionsContainerMap::const_iterator it = sessions.find(sid);
198 
199  if (it == sessions.end()) { pthread_mutex_unlock( &sessions_mutex ); return; };
200 
201  SessionAttribute attribute;
202  attribute.type=SessionAttribute::BASIC;
203  attribute.ptr=value;
204  it->second->insert(std::pair<std::string, SessionAttribute>(name, attribute ));
205  pthread_mutex_unlock( &sessions_mutex );
206  }
207 
208  /**********************************************************************/
209 
210  static SessionAttributeObject *getObjectAttribute( const std::string &sid, const std::string &name )
211  {
212  pthread_mutex_lock( &sessions_mutex );
213  HttpSessionsContainerMap::iterator it = sessions.find(sid);
214  if (it == sessions.end()) { pthread_mutex_unlock( &sessions_mutex ); return NULL; }
215 
216  std::map <std::string, SessionAttribute>* sessionMap=it->second;
217  std::map <std::string, SessionAttribute>::iterator it2 = sessionMap->find(name);
218  pthread_mutex_unlock( &sessions_mutex );
219 
220  if ( it2 != sessionMap->end() && (it2->second.type == SessionAttribute::OBJECT) )
221  return it2->second.obj;
222  return NULL;
223  }
224 
225  /**********************************************************************/
226 
227  static void *getAttribute( const std::string &sid, const std::string &name )
228  {
229  pthread_mutex_lock( &sessions_mutex );
230  HttpSessionsContainerMap::iterator it = sessions.find(sid);
231  if (it == sessions.end()) { pthread_mutex_unlock( &sessions_mutex ); return NULL; }
232 
233  std::map <std::string, SessionAttribute>* sessionMap=it->second;
234  std::map <std::string, SessionAttribute>::iterator it2 = sessionMap->find(name);
235  pthread_mutex_unlock( &sessions_mutex );
236 
237  if ( it2 != sessionMap->end() && (it2->second.type == SessionAttribute::BASIC))
238  return it2->second.ptr;
239  return NULL;
240  }
241 
242  /**********************************************************************/
243 
244  static void removeAllAttribute( std::map <std::string, SessionAttribute>* attributesMap)
245  {
246  std::map <std::string, SessionAttribute>::iterator iter = attributesMap->begin();
247  for(; iter!=attributesMap->end(); ++iter)
248  if (iter->second.ptr != NULL)
249  {
250  if (iter->second.type==SessionAttribute::OBJECT)
251  delete iter->second.obj;
252  else
253  free (iter->second.ptr);
254  }
255  }
256 
257  /**********************************************************************/
258 
259  static void removeAttribute( const std::string &sid, const std::string &name )
260  {
261  pthread_mutex_lock( &sessions_mutex );
262  HttpSessionsContainerMap::iterator it = sessions.find(sid);
263  if (it == sessions.end()) { pthread_mutex_unlock( &sessions_mutex ); return; }
264  std::map <std::string, SessionAttribute>* attributesMap=it->second;
265  std::map <std::string, SessionAttribute>::iterator it2 = attributesMap->find(name);
266  if ( it2 != attributesMap->end() )
267  {
268  if (it2->second.ptr != NULL)
269  {
270  if (it2->second.type==SessionAttribute::OBJECT)
271  delete it2->second.obj;
272  else
273  free (it2->second.ptr);
274  }
275  attributesMap->erase(it2);
276  }
277  pthread_mutex_unlock( &sessions_mutex );
278  }
279 
280  /**********************************************************************/
281 
282  static std::vector<std::string> getAttributeNames( const std::string &sid )
283  {
284  pthread_mutex_lock( &sessions_mutex );
285  std::vector<std::string> res;
286  HttpSessionsContainerMap::iterator it = sessions.find(sid);
287  if (it != sessions.end())
288  {
289  std::map <std::string, SessionAttribute>* attributesMap=it->second;
290  std::map <std::string, SessionAttribute>::iterator iter = attributesMap->begin();
291  for(; iter!=attributesMap->end(); ++iter)
292  res.push_back(iter->first);
293  }
294  pthread_mutex_unlock( &sessions_mutex );
295  return res;
296  }
297 
298  /**********************************************************************/
299 
300  static void printAll()
301  {
302  pthread_mutex_lock( &sessions_mutex );
303  HttpSessionsContainerMap::iterator it = sessions.begin();
304  for (;it != sessions.end(); ++it )
305  {
306  std::map <std::string, SessionAttribute>* attributesMap=it->second;
307  printf("Session SID : '%s' \n", it->first.c_str());
308  std::map <std::string, SessionAttribute>::iterator iter = attributesMap->begin();
309  for(; iter!=attributesMap->end(); ++iter)
310  if ( iter->second.ptr != NULL ) printf("\t'%s'\n", iter->first.c_str());
311  }
312  pthread_mutex_unlock( &sessions_mutex );
313  }
314 
315  /**********************************************************************/
316 
317 };
318 
319 //****************************************************************************
320 
321 
322 #endif
Definition: HttpSession.hh:24
Definition: HttpSession.hh:30