diff options
Diffstat (limited to 'src/webclientserver.cpp')
-rw-r--r-- | src/webclientserver.cpp | 69 |
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>"; |