summaryrefslogtreecommitdiffstats
path: root/src/webclientserver.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/webclientserver.cpp')
-rw-r--r--src/webclientserver.cpp69
1 files changed, 62 insertions, 7 deletions
diff --git a/src/webclientserver.cpp b/src/webclientserver.cpp
index f29abf0..762664b 100644
--- a/src/webclientserver.cpp
+++ b/src/webclientserver.cpp
@@ -49,11 +49,11 @@ void HttpRequest::parseText()
if (line.startsWith("GET")) {
m_path = QUrl::fromPercentEncoding(line.mid(4).split(' ').at(0)).toAscii(); // ### assumes well-formed string
} else if (line.startsWith("POST")) {
- m_path = QUrl::fromPercentEncoding(line.mid(5).split(' ').at(0)).toAscii(); // ### assumes well-formed string
+ m_path = QUrl::fromPercentEncoding(line.mid(5).split(' ').at(0)).toAscii(); // ### assumes well-formed string
} else if (line.startsWith("Cookie:")) {
-// qDebug() << "cookie line" << line.simplified();
+// DEBUG << "cookie line" << line.simplified();
m_cookies = line.mid(7).simplified(); // remove "Cookie:"
-// qDebug() << "cookies text" << m_cookies;
+// DEBUG << "cookies text" << m_cookies;
foreach (const QByteArray cookieText, m_cookies.split(';')){
if (cookieText.contains('=')) {
QList<QByteArray> cookieParts = cookieText.split('=');
@@ -159,7 +159,7 @@ QByteArray HttpResponse::toText()
Session::Session(Server *server, int sessionId)
:m_sessionId(sessionId), m_idleSocket(0), m_server(server)
{
-
+ lastActivityTime = QDateTime::currentDateTime();
}
int Session::sessionId()
@@ -198,7 +198,7 @@ Server::Server(quint16 port)
this->port = port;
connect(this, SIGNAL(newConnection()), SLOT(connectionAvailable()));
listen(QHostAddress::Any, port);
- qDebug() << QString("Server running on: http://" + QHostInfo::localHostName() + ":" + QString::number(port) + "/");
+ DEBUG << QString("Server running on: http://" + QHostInfo::localHostName() + ":" + QString::number(port) + "/");
qsrand(QDateTime::currentDateTime().toTime_t());
nextCookieId = qrand();
dynamicBytesWritten = 0;
@@ -208,7 +208,10 @@ Server::Server(quint16 port)
totalSessions = 0;
activeSessionLimit = INT_MAX;
activeSessionLimitHtml = "<html><body>Active session limit exceeded.</body></html>";
+ inactiveSessionTimeout = 60 * 10;
+ connect(&purgeInactiveSessionsTimer, SIGNAL(timeout()), SLOT(purgeInactiveSessions()));
+ purgeInactiveSessionsTimer.start(1000 / 1);
// This didn't work out. Disable for now.
sendUpdatesForPlainQWidgets = true;
// skipUpdatesClasses.insert("QWidget");
@@ -293,7 +296,7 @@ void Server::dataOnSocket()
if (session == 0) {
// ### accept unknown sessions for now, TODO do authentication here.
- DEBUG << "new session for" << sessionId;
+ DEBUG << "create new session";
if (totalSessions >= activeSessionLimit) {
dynamicBytesWritten += activeSessionLimitHtml.size();
@@ -320,6 +323,8 @@ void Server::dataOnSocket()
// DEBUG << "found session for" << sessionId;
}
+ session->lastActivityTime = QDateTime::currentDateTime();
+
// Strip away the page ids: "-pageId="
/*
int index = request.m_path.indexOf("-pageId=");
@@ -372,12 +377,62 @@ void Server::dataOnSocket()
// DEBUG << "socket write response done";
}
+void Server::purgeInactiveSessions()
+{
+ DEBUG << "purgeInactiveSessions";
+ QDateTime now = QDateTime::currentDateTime();
+
+ // find where we left off the last time, restart from
+ // the beginning if not found.
+ QHash<int, Session *>::iterator it = activeSessions.find(lastSessionVisited);
+ if (it == activeSessions.end())
+ it = activeSessions.begin();
+
+ const int maxSessonsToExamine = 50; // avoid pausing to long.
+ int i = 0;
+ while (it != activeSessions.end()) {
+ if (i > maxSessonsToExamine) {
+ lastSessionVisited = it.key();
+ return;
+ }
+
+ Session *session = it.value();
+ DEBUG << "last act" << session << session->lastActivityTime;
+ int inactiveSeconds = now.toTime_t() - session->lastActivityTime.toTime_t();
+ DEBUG << "inactive" << inactiveSeconds;
+ if (inactiveSeconds > inactiveSessionTimeout) {
+ QHash<int, Session *>::iterator itToDelete = it;
+
+ // get the next key so the search can continue after the
+ // erase. (all iterators are invalidated.)
+ ++it;
+ if (it == activeSessions.end()) {
+ delete itToDelete.value();
+ activeSessions.erase(itToDelete);
+ it = activeSessions.end();
+ } else {
+ int newKey = it.key();
+ delete itToDelete.value();
+ activeSessions.erase(itToDelete);
+ it = activeSessions.find(newKey);
+ }
+ continue; // it has been repositioned. (i has not been incremented -
+ // there is no limit to how many session we can delete in one go.)
+ }
+ ++it;
+ ++i;
+ }
+
+ // reached the end, restart for next time.
+ lastSessionVisited = -1; //actually a valid session value, but most likely a miss.
+}
+
QByteArray Server::createStatiticsPage()
{
const double ec2DataRate=0.02 / (1000 * 1000 * 1000) ; // cost per byte
const double ec2InstanceRate = 0.1; // cost per hour
const double upHours = (QDateTime::currentDateTime().toTime_t() - serverStart.toTime_t() / (60.0 * 60.0));
- qDebug() << "up" << upHours << QDateTime::currentDateTime().toTime_t();
+ DEBUG << "up" << upHours << QDateTime::currentDateTime().toTime_t();
QByteArray stats;
stats += "<b> Statistics </b><br><br>";
stats += "<table border=1>";