| 
									
										
										
										
											2017-08-23 18:47:07 +02:00
										 |  |  | /**
 | 
					
						
							|  |  |  |   @file | 
					
						
							|  |  |  |   @author Stefan Frings | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "httpsessionstore.h"
 | 
					
						
							| 
									
										
										
										
											2017-11-13 01:17:55 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-23 18:47:07 +02:00
										 |  |  | #include <QDateTime>
 | 
					
						
							|  |  |  | #include <QUuid>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-11 09:32:15 +01:00
										 |  |  | using namespace qtwebapp; | 
					
						
							| 
									
										
										
										
											2017-08-23 18:47:07 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | HttpSessionStore::HttpSessionStore(QSettings* settings, QObject* parent) | 
					
						
							| 
									
										
										
										
											2017-11-13 13:46:02 +01:00
										 |  |  |     :QObject(parent), useQtSettings(true) | 
					
						
							| 
									
										
										
										
											2017-08-23 18:47:07 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     this->settings=settings; | 
					
						
							|  |  |  |     connect(&cleanupTimer,SIGNAL(timeout()),this,SLOT(sessionTimerEvent())); | 
					
						
							|  |  |  |     cleanupTimer.start(60000); | 
					
						
							|  |  |  |     cookieName=settings->value("cookieName","sessionid").toByteArray(); | 
					
						
							|  |  |  |     expirationTime=settings->value("expirationTime",3600000).toInt(); | 
					
						
							|  |  |  |     qDebug("HttpSessionStore: Sessions expire after %i milliseconds",expirationTime); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-13 13:46:02 +01:00
										 |  |  | HttpSessionStore::HttpSessionStore(const HttpSessionsSettings& settings, QObject* parent) | 
					
						
							| 
									
										
										
										
											2017-11-13 01:17:55 +01:00
										 |  |  |     :QObject(parent), settings(0), useQtSettings(false) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2017-11-13 13:46:02 +01:00
										 |  |  |     sessionsSettings=settings; | 
					
						
							| 
									
										
										
										
											2017-11-13 01:17:55 +01:00
										 |  |  |     connect(&cleanupTimer,SIGNAL(timeout()),this,SLOT(sessionTimerEvent())); | 
					
						
							|  |  |  |     cleanupTimer.start(60000); | 
					
						
							| 
									
										
										
										
											2017-11-13 13:46:02 +01:00
										 |  |  |     cookieName=QByteArray(qPrintable(settings.cookieName)); | 
					
						
							|  |  |  |     expirationTime=settings.expirationTime; | 
					
						
							| 
									
										
										
										
											2017-11-13 01:17:55 +01:00
										 |  |  |     qDebug("HttpSessionStore: Sessions expire after %i milliseconds",expirationTime); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-23 18:47:07 +02:00
										 |  |  | HttpSessionStore::~HttpSessionStore() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     cleanupTimer.stop(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | QByteArray HttpSessionStore::getSessionId(HttpRequest& request, HttpResponse& response) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     // The session ID in the response has priority because this one will be used in the next request.
 | 
					
						
							|  |  |  |     mutex.lock(); | 
					
						
							|  |  |  |     // Get the session ID from the response cookie
 | 
					
						
							|  |  |  |     QByteArray sessionId=response.getCookies().value(cookieName).getValue(); | 
					
						
							|  |  |  |     if (sessionId.isEmpty()) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         // Get the session ID from the request cookie
 | 
					
						
							|  |  |  |         sessionId=request.getCookie(cookieName); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     // Clear the session ID if there is no such session in the storage.
 | 
					
						
							|  |  |  |     if (!sessionId.isEmpty()) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         if (!sessions.contains(sessionId)) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             qDebug("HttpSessionStore: received invalid session cookie with ID %s",sessionId.data()); | 
					
						
							|  |  |  |             sessionId.clear(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     mutex.unlock(); | 
					
						
							|  |  |  |     return sessionId; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | HttpSession HttpSessionStore::getSession(HttpRequest& request, HttpResponse& response, bool allowCreate) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QByteArray sessionId=getSessionId(request,response); | 
					
						
							|  |  |  |     mutex.lock(); | 
					
						
							|  |  |  |     if (!sessionId.isEmpty()) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         HttpSession session=sessions.value(sessionId); | 
					
						
							|  |  |  |         if (!session.isNull()) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             mutex.unlock(); | 
					
						
							|  |  |  |             // Refresh the session cookie
 | 
					
						
							| 
									
										
										
										
											2017-11-13 13:46:02 +01:00
										 |  |  |             QByteArray cookieName = useQtSettings ? settings->value("cookieName","sessionid").toByteArray() : QByteArray(qPrintable(sessionsSettings.cookieName)); | 
					
						
							|  |  |  |             QByteArray cookiePath = useQtSettings ? settings->value("cookiePath").toByteArray() : QByteArray(qPrintable(sessionsSettings.cookiePath)); | 
					
						
							|  |  |  |             QByteArray cookieComment = useQtSettings ? settings->value("cookieComment").toByteArray() : QByteArray(qPrintable(sessionsSettings.cookieComment)); | 
					
						
							|  |  |  |             QByteArray cookieDomain = useQtSettings ? settings->value("cookieDomain").toByteArray() : QByteArray(qPrintable(sessionsSettings.cookieDomain)); | 
					
						
							| 
									
										
										
										
											2017-08-23 18:47:07 +02:00
										 |  |  |             response.setCookie(HttpCookie(cookieName,session.getId(),expirationTime/1000,cookiePath,cookieComment,cookieDomain)); | 
					
						
							|  |  |  |             session.setLastAccess(); | 
					
						
							|  |  |  |             return session; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     // Need to create a new session
 | 
					
						
							|  |  |  |     if (allowCreate) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2017-11-13 13:46:02 +01:00
										 |  |  |         QByteArray cookieName = useQtSettings ? settings->value("cookieName","sessionid").toByteArray() : QByteArray(qPrintable(sessionsSettings.cookieName)); | 
					
						
							|  |  |  |         QByteArray cookiePath = useQtSettings ? settings->value("cookiePath").toByteArray() : QByteArray(qPrintable(sessionsSettings.cookiePath)); | 
					
						
							|  |  |  |         QByteArray cookieComment = useQtSettings ? settings->value("cookieComment").toByteArray() : QByteArray(qPrintable(sessionsSettings.cookieComment)); | 
					
						
							|  |  |  |         QByteArray cookieDomain = useQtSettings ? settings->value("cookieDomain").toByteArray() : QByteArray(qPrintable(sessionsSettings.cookieDomain)); | 
					
						
							| 
									
										
										
										
											2017-08-23 18:47:07 +02:00
										 |  |  |         HttpSession session(true); | 
					
						
							|  |  |  |         qDebug("HttpSessionStore: create new session with ID %s",session.getId().data()); | 
					
						
							|  |  |  |         sessions.insert(session.getId(),session); | 
					
						
							|  |  |  |         response.setCookie(HttpCookie(cookieName,session.getId(),expirationTime/1000,cookiePath,cookieComment,cookieDomain)); | 
					
						
							|  |  |  |         mutex.unlock(); | 
					
						
							|  |  |  |         return session; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     // Return a null session
 | 
					
						
							|  |  |  |     mutex.unlock(); | 
					
						
							|  |  |  |     return HttpSession(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | HttpSession HttpSessionStore::getSession(const QByteArray id) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     mutex.lock(); | 
					
						
							|  |  |  |     HttpSession session=sessions.value(id); | 
					
						
							|  |  |  |     mutex.unlock(); | 
					
						
							|  |  |  |     session.setLastAccess(); | 
					
						
							|  |  |  |     return session; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void HttpSessionStore::sessionTimerEvent() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     mutex.lock(); | 
					
						
							|  |  |  |     qint64 now=QDateTime::currentMSecsSinceEpoch(); | 
					
						
							|  |  |  |     QMap<QByteArray,HttpSession>::iterator i = sessions.begin(); | 
					
						
							|  |  |  |     while (i != sessions.end()) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         QMap<QByteArray,HttpSession>::iterator prev = i; | 
					
						
							|  |  |  |         ++i; | 
					
						
							|  |  |  |         HttpSession session=prev.value(); | 
					
						
							|  |  |  |         qint64 lastAccess=session.getLastAccess(); | 
					
						
							|  |  |  |         if (now-lastAccess>expirationTime) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             qDebug("HttpSessionStore: session %s expired",session.getId().data()); | 
					
						
							|  |  |  |             sessions.erase(prev); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     mutex.unlock(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** Delete a session */ | 
					
						
							|  |  |  | void HttpSessionStore::removeSession(HttpSession session) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     mutex.lock(); | 
					
						
							|  |  |  |     sessions.remove(session.getId()); | 
					
						
							|  |  |  |     mutex.unlock(); | 
					
						
							|  |  |  | } |