From e51508ee33a629405b1609edcec974fdc81a133e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Wed, 9 Jan 2019 12:23:47 +0100 Subject: [PATCH] Update webserver debug output, add WebServerTraffic category and fix favicons for debugserver --- data/debug-interface/debug-interface.qrc | 13 +++ libnymea-core/servers/httpreply.cpp | 113 ++++++++++++++-------- libnymea-core/servers/httpreply.h | 5 +- libnymea-core/servers/httprequest.cpp | 40 +++----- libnymea-core/servers/rest/restserver.cpp | 6 +- libnymea-core/servers/webserver.cpp | 64 ++++++------ libnymea/loggingcategories.cpp | 1 + libnymea/loggingcategories.h | 1 + server/main.cpp | 1 + 9 files changed, 145 insertions(+), 99 deletions(-) diff --git a/data/debug-interface/debug-interface.qrc b/data/debug-interface/debug-interface.qrc index 89b7a29d..733a0ac7 100644 --- a/data/debug-interface/debug-interface.qrc +++ b/data/debug-interface/debug-interface.qrc @@ -11,5 +11,18 @@ favicons/favicon-196x196.png favicons/favicon.ico favicons/favicon.svg + favicons/mstile-70x70.png + favicons/mstile-144x144.png + favicons/mstile-150x150.png + favicons/mstile-310x150.png + favicons/mstile-310x310.png + favicons/apple-touch-icon-152x152.png + favicons/apple-touch-icon-144x144.png + favicons/apple-touch-icon-57x57.png + favicons/apple-touch-icon-60x60.png + favicons/apple-touch-icon-72x72.png + favicons/apple-touch-icon-76x76.png + favicons/apple-touch-icon-114x114.png + favicons/apple-touch-icon-120x120.png diff --git a/libnymea-core/servers/httpreply.cpp b/libnymea-core/servers/httpreply.cpp index 3635c424..c56b70c0 100644 --- a/libnymea-core/servers/httpreply.cpp +++ b/libnymea-core/servers/httpreply.cpp @@ -161,7 +161,7 @@ HttpReply::HttpReply(QObject *parent) : setHeader(HttpHeaderType::CacheControlHeader, "no-cache"); setHeader(HttpHeaderType::ConnectionHeader, "Keep-Alive"); setRawHeader("Access-Control-Allow-Origin","*"); - setRawHeader("Keep-Alive", "timeout=12, max=50"); + setRawHeader("Keep-Alive", QString("timeout=%1, max=50").arg(m_timeout).toUtf8()); packReply(); } @@ -184,7 +184,7 @@ HttpReply::HttpReply(const HttpReply::HttpStatusCode &statusCode, const HttpRepl setHeader(HttpHeaderType::CacheControlHeader, "no-cache"); setHeader(HttpHeaderType::ConnectionHeader, "Keep-Alive"); setRawHeader("Access-Control-Allow-Origin","*"); - setRawHeader("Keep-Alive", "timeout=12, max=50"); + setRawHeader("Keep-Alive", QString("timeout=%1, max=50").arg(m_timeout).toUtf8()); packReply(); } @@ -326,7 +326,7 @@ void HttpReply::packReply() } m_rawHeader.append("\r\n"); - m_data = m_rawHeader.append(m_payload); + m_data = QByteArray(m_rawHeader).append(m_payload); } /*! Returns the current raw data (header + payload) of this \l{HttpReply}.*/ @@ -343,72 +343,101 @@ bool HttpReply::timedOut() const QByteArray HttpReply::getHttpReasonPhrase(const HttpReply::HttpStatusCode &statusCode) { + QByteArray response; switch (statusCode) { case HttpStatusCode::Ok: - return "Ok"; + response = QString("Ok").toUtf8(); + break; case Created: - return "Created"; + response = QString("Created").toUtf8(); + break; case Accepted: - return "Accepted"; + response = QString("Accepted").toUtf8(); + break; case NoContent: - return "No Content"; + response = QString("No Content").toUtf8(); + break; case Found: - return "Found"; + response = QString("Found").toUtf8(); + break; case PermanentRedirect: - return "Permanent Redirect"; + response = QString("Permanent Redirect").toUtf8(); + break; case BadRequest: - return "Bad Request"; + response = QString("Bad Request").toUtf8(); + break; case Forbidden: - return "Forbidden"; + response = QString("Forbidden").toUtf8(); + break; case NotFound: - return "NotFound"; + response = QString("NotFound").toUtf8(); + break; case MethodNotAllowed: - return "Method Not Allowed"; + response = QString("Method Not Allowed").toUtf8(); + break; case RequestTimeout: - return "Request Timeout"; + response = QString("Request Timeout").toUtf8(); + break; case Conflict: - return "Conflict"; + response = QString("Conflict").toUtf8(); + break; case InternalServerError: - return "Internal Server Error"; + response = QString("Internal Server Error").toUtf8(); + break; case NotImplemented: - return "Not Implemented"; + response = QString("Not Implemented").toUtf8(); + break; case BadGateway: - return "Bad Gateway"; + response = QString("Bad Gateway").toUtf8(); + break; case ServiceUnavailable: - return "Service Unavailable"; + response = QString("Service Unavailable").toUtf8(); + break; case GatewayTimeout: - return "Gateway Timeout"; + response = QString("Gateway Timeout").toUtf8(); + break; case HttpVersionNotSupported: - return "HTTP Version Not Supported"; - default: - return QByteArray(); + response = QString("HTTP Version Not Supported").toUtf8(); + break; } + + return response; } QByteArray HttpReply::getHeaderType(const HttpReply::HttpHeaderType &headerType) { + QByteArray header; switch (headerType) { case ContentTypeHeader: - return "Content-Type"; + header = QString("Content-Type").toUtf8(); + break; case ContentLenghtHeader: - return "Content-Length"; + header = QString("Content-Length").toUtf8(); + break; case CacheControlHeader: - return "Cache-Control"; + header = QString("Cache-Control").toUtf8(); + break; case LocationHeader: - return "Location"; + header = QString("Location").toUtf8(); + break; case ConnectionHeader: - return "Connection"; + header = QString("Connection").toUtf8(); + break; case UserAgentHeader: - return "User-Agent"; + header = QString("User-Agent").toUtf8(); + break; case AllowHeader: - return "Allow"; + header = QString("Allow").toUtf8(); + break; case DateHeader: - return "Date"; + header = QString("Date").toUtf8(); + break; case ServerHeader: - return "Server"; - default: - return QByteArray(); + header = QString("Server").toUtf8(); + break; } + + return header; } /*! Starts the timer for an async \l{HttpReply}. @@ -417,24 +446,22 @@ QByteArray HttpReply::getHeaderType(const HttpReply::HttpHeaderType &headerType) */ void HttpReply::startWait() { - m_timer->start(60000); + m_timer->start(m_timeout); } void HttpReply::timeout() { - qCDebug(dcWebServer) << "Http reply timeout"; + qCDebug(dcWebServer()) << "Http reply timeout"; m_timedOut = true; emit finished(); } -QDebug operator<<(QDebug debug, const HttpReply &httpReply) +QDebug operator<<(QDebug debug, HttpReply *httpReply) { - debug << "-----------------------------------" << "\n"; - debug << httpReply.rawHeader() << "\n"; - debug << "-----------------------------------" << "\n"; - debug << httpReply.payload() << "\n"; - debug << "-----------------------------------" << "\n"; - return debug; + debug.nospace() << "HttpReply(" << httpReply->clientId().toString() << ")" << endl; + debug << qUtf8Printable(httpReply->rawHeader()); + debug << qUtf8Printable(httpReply->payload()); + return debug.space(); } } diff --git a/libnymea-core/servers/httpreply.h b/libnymea-core/servers/httpreply.h index 27358021..8e406281 100644 --- a/libnymea-core/servers/httpreply.h +++ b/libnymea-core/servers/httpreply.h @@ -121,7 +121,8 @@ private: bool m_closeConnection; - QTimer *m_timer; + QTimer *m_timer = nullptr; + int m_timeout = 60000; bool m_timedOut; QByteArray getHttpReasonPhrase(const HttpStatusCode &statusCode); @@ -138,7 +139,7 @@ signals: }; -QDebug operator<< (QDebug debug, const HttpReply &httpReply); +QDebug operator<<(QDebug debug, HttpReply *httpReply); } diff --git a/libnymea-core/servers/httprequest.cpp b/libnymea-core/servers/httprequest.cpp index 933a14d0..582b701c 100644 --- a/libnymea-core/servers/httprequest.cpp +++ b/libnymea-core/servers/httprequest.cpp @@ -172,7 +172,7 @@ void HttpRequest::validate() // split the data into header and payload int headerEndIndex = m_rawData.indexOf("\r\n\r\n"); if (headerEndIndex < 0) { - qCWarning(dcWebServer) << "Could not parse end of HTTP header (empty line between header and body):" << m_rawData; + qCWarning(dcWebServer()) << "Could not parse end of HTTP header (empty line between header and body):" << m_rawData; return; } @@ -184,14 +184,14 @@ void HttpRequest::validate() QString statusLine = headerLines.takeFirst(); QStringList statusLineTokens = statusLine.split(QRegExp("[ \r\n][ \r\n]*")); if (statusLineTokens.count() != 3) { - qCWarning(dcWebServer) << "Could not parse HTTP status line:" << statusLine; + qCWarning(dcWebServer()) << "Could not parse HTTP status line:" << statusLine; return; } // verify http version m_httpVersion = statusLineTokens.at(2).toUtf8().simplified(); if (!m_httpVersion.contains("HTTP")) { - qCWarning(dcWebServer) << "Unknown HTTP version:" << m_httpVersion; + qCWarning(dcWebServer()) << "Unknown HTTP version:" << m_httpVersion; return; } m_methodString = statusLineTokens.at(0).simplified(); @@ -205,7 +205,7 @@ void HttpRequest::validate() // verify header formating foreach (const QString &line, headerLines) { if (!line.contains(":")) { - qCWarning(dcWebServer) << "Invalid HTTP header:" << line; + qCWarning(dcWebServer()) << "Invalid HTTP header:" << line; return; } int index = line.indexOf(":"); @@ -216,7 +216,7 @@ void HttpRequest::validate() // check User-Agent if (!m_rawHeaderList.contains("User-Agent")) - qCWarning(dcWebServer) << "User-Agent header is missing"; + qCWarning(dcWebServer()) << "User-Agent header is missing"; // verify content length with actual payload @@ -224,22 +224,22 @@ void HttpRequest::validate() bool ok = false; int contentLength = m_rawHeaderList.value("Content-Length").toInt(&ok); if (!ok) { - qCWarning(dcWebServer) << "Could not parse Content-Length."; + qCWarning(dcWebServer()) << "Could not parse Content-Length."; return; } // check if we have all data if (m_payload.size() < contentLength) { - qCDebug(dcWebServer) << "Request incomplete:"; - qCDebug(dcWebServer) << " -> Content-Length:" << contentLength; - qCDebug(dcWebServer) << " -> Payload size :" << payload().size(); + qCDebug(dcWebServer()) << "Request incomplete:"; + qCDebug(dcWebServer()) << " -> Content-Length:" << contentLength; + qCDebug(dcWebServer()) << " -> Payload size :" << payload().size(); m_isComplete = false; return; } // check if the content length bigger than header Content-Length if (m_payload.size() > contentLength) { - qCWarning(dcWebServer) << "Payload size greater than header Content-Length:"; - qCWarning(dcWebServer) << " -> Content-Length:" << contentLength; - qCWarning(dcWebServer) << " -> Payload size :" << payload().size(); + qCWarning(dcWebServer()) << "Payload size greater than header Content-Length:"; + qCWarning(dcWebServer()) << " -> Content-Length:" << contentLength; + qCWarning(dcWebServer()) << " -> Payload size :" << payload().size(); m_isComplete = true; return; } @@ -261,23 +261,15 @@ HttpRequest::RequestMethod HttpRequest::getRequestMethodType(const QString &meth } else if (methodString == "OPTIONS") { return RequestMethod::Options; } - qCWarning(dcWebServer) << "Method" << methodString << "will not be handled."; + qCWarning(dcWebServer()) << "Method" << methodString << "will not be handled."; return RequestMethod::Unhandled; } QDebug operator<<(QDebug debug, const HttpRequest &httpRequest) { - debug << "===================================" << "\n"; - debug << " HTTP version: " << httpRequest.httpVersion() << "\n"; - debug << " method: " << httpRequest.methodString() << "\n"; - debug << " URL path: " << httpRequest.url().path() << "\n"; - debug << " URL query: " << httpRequest.urlQuery().query() << "\n"; - debug << " is valid: " << httpRequest.isValid() << "\n"; - debug << "-----------------------------------" << "\n"; - debug << httpRequest.rawHeader() << "\n"; - debug << "-----------------------------------" << "\n"; - debug << httpRequest.payload() << "\n"; - debug << "-----------------------------------" << "\n"; + debug << "HttpRequest:" << endl; + debug << qUtf8Printable(httpRequest.rawHeader()); + debug << qUtf8Printable(httpRequest.payload()); return debug; } diff --git a/libnymea-core/servers/rest/restserver.cpp b/libnymea-core/servers/rest/restserver.cpp index 1f5fc814..e852ee4b 100644 --- a/libnymea-core/servers/rest/restserver.cpp +++ b/libnymea-core/servers/rest/restserver.cpp @@ -151,7 +151,7 @@ void RestServer::asyncReplyFinished() HttpReply *reply = qobject_cast(sender()); if (!m_asyncReplies.values().contains(reply)) { - qCWarning(dcWebServer) << "Reply for async request does no longer exist"; + qCWarning(dcWebServer()) << "Reply for async request does no longer exist"; reply->deleteLater(); return; } @@ -159,7 +159,7 @@ void RestServer::asyncReplyFinished() QUuid clientId = m_asyncReplies.key(reply); m_asyncReplies.remove(clientId); - qCDebug(dcWebServer) << "Async reply finished"; + qCDebug(dcWebServer()) << "Async reply finished"; // check if the reply timeouted if (reply->timedOut()) { @@ -169,7 +169,7 @@ void RestServer::asyncReplyFinished() // check if client is still connected if (!m_clientList.contains(clientId)) { - qCWarning(dcWebServer) << "Client for async reply not longer connected."; + qCWarning(dcWebServer()) << "Client for async reply not longer connected."; } else { reply->setClientId(clientId); WebServer *webserver = m_clientList.value(clientId); diff --git a/libnymea-core/servers/webserver.cpp b/libnymea-core/servers/webserver.cpp index 76f82c34..44ba5411 100644 --- a/libnymea-core/servers/webserver.cpp +++ b/libnymea-core/servers/webserver.cpp @@ -105,7 +105,7 @@ WebServer::WebServer(const WebServerConfiguration &configuration, const QSslConf if (QCoreApplication::instance()->organizationName() == "nymea-test") { m_configuration.publicFolder = QCoreApplication::applicationDirPath(); } - qCDebug(dcWebServer) << "Starting WebServer. Interface:" << m_configuration.address << "Port:" << m_configuration.port << "SSL:" << m_configuration.sslEnabled << "AUTH:" << m_configuration.authenticationEnabled << "Public folder:" << QDir(m_configuration.publicFolder).canonicalPath(); + qCDebug(dcWebServer()) << "Starting WebServer. Interface:" << m_configuration.address << "Port:" << m_configuration.port << "SSL:" << m_configuration.sslEnabled << "AUTH:" << m_configuration.authenticationEnabled << "Public folder:" << QDir(m_configuration.publicFolder).canonicalPath(); m_avahiService = new QtAvahiService(this); connect(m_avahiService, &QtAvahiService::serviceStateChanged, this, &WebServer::onAvahiServiceStateChanged); @@ -135,13 +135,14 @@ void WebServer::sendHttpReply(HttpReply *reply) QSslSocket *socket = nullptr; socket = m_clientList.value(reply->clientId()); if (!socket) { - qCWarning(dcWebServer) << "Invalid socket pointer! This should never happen!!! Missing clientId in reply?"; + qCWarning(dcWebServer()) << "Invalid socket pointer! This should never happen!!! Missing clientId in reply?"; return; } // send raw data reply->packReply(); - qCDebug(dcWebServer) << "Respond" << reply->httpStatusCode() << reply->httpReasonPhrase(); + qCDebug(dcWebServerTraffic()) << "Send reply to" << socket->peerAddress().toString() << reply; + qCDebug(dcWebServer()) << "Respond" << socket->peerAddress().toString() << reply->httpStatusCode() << reply->httpReasonPhrase(); socket->write(reply->data()); } @@ -151,7 +152,7 @@ bool WebServer::verifyFile(QSslSocket *socket, const QString &fileName) // make sure the file exists if (!file.exists()) { - qCWarning(dcWebServer) << "requested file" << file.filePath() << "does not exist."; + qCWarning(dcWebServer()) << "requested file" << file.filePath() << "does not exist."; HttpReply *reply = RestResource::createErrorReply(HttpReply::NotFound); reply->setClientId(m_clientList.key(socket)); sendHttpReply(reply); @@ -161,7 +162,7 @@ bool WebServer::verifyFile(QSslSocket *socket, const QString &fileName) // make sure the file is in the public directory if (!file.canonicalFilePath().startsWith(QDir(m_configuration.publicFolder).canonicalPath())) { - qCWarning(dcWebServer) << "Requested file" << file.fileName() << "is outside the public folder."; + qCWarning(dcWebServer()) << "Requested file" << file.fileName() << "is outside the public folder."; HttpReply *reply = RestResource::createErrorReply(HttpReply::Forbidden); reply->setClientId(m_clientList.key(socket)); sendHttpReply(reply); @@ -171,7 +172,7 @@ bool WebServer::verifyFile(QSslSocket *socket, const QString &fileName) // make sure we can read the file if (!file.isReadable()) { - qCWarning(dcWebServer) << "Requested file" << file.fileName() << "is not readable."; + qCWarning(dcWebServer()) << "Requested file" << file.fileName() << "is not readable."; HttpReply *reply = RestResource::createErrorReply(HttpReply::Forbidden); reply->setClientId(m_clientList.key(socket)); reply->setPayload("403 Forbidden. File not readable"); @@ -234,7 +235,7 @@ void WebServer::incomingConnection(qintptr socketDescriptor) foreach (WebServerClient *client, m_webServerClients) { if (client->address() == socket->peerAddress()) { if (client->connections().count() >= 50) { - qCWarning(dcWebServer()) << QString("Maximum connections for this client reached: rejecting connection from client %1:%2").arg(socket->peerAddress().toString()).arg(socket->peerPort()); + qCWarning(dcWebServer()).noquote() << QString("Maximum connections for this client reached: rejecting connection from client %1:%2").arg(socket->peerAddress().toString()).arg(socket->peerPort()); socket->close(); delete socket; return; @@ -255,7 +256,7 @@ void WebServer::incomingConnection(qintptr socketDescriptor) QUuid clientId = QUuid::createUuid(); m_clientList.insert(clientId, socket); - qCDebug(dcWebServer()) << QString("Webserver client %1:%2 connected").arg(socket->peerAddress().toString()).arg(socket->peerPort()); + qCDebug(dcWebServer()).noquote() << QString("Webserver client %1:%2 connected").arg(socket->peerAddress().toString()).arg(socket->peerPort()); if (m_configuration.sslEnabled) { // configure client connection @@ -283,7 +284,7 @@ void WebServer::readClient() // Check client if (clientId.isNull()) { - qCWarning(dcWebServer) << "Client not recognized"; + qCWarning(dcWebServer()) << "Client not recognized"; socket->close(); return; } @@ -293,7 +294,7 @@ void WebServer::readClient() HttpRequest request; if (m_incompleteRequests.contains(socket)) { - qCDebug(dcWebServer) << "Append data to incomlete request"; + qCDebug(dcWebServer()) << "Append data to incomlete request"; request = m_incompleteRequests.take(socket); request.appendData(data); } else { @@ -306,9 +307,11 @@ void WebServer::readClient() return; } + qCDebug(dcWebServerTraffic()) << "Received request from" << clientId.toString() << socket->peerAddress().toString() << request; + // Check if the request is valid if (!request.isValid()) { - qCWarning(dcWebServer) << "Got invalid request:" << request.url().path(); + qCWarning(dcWebServer()) << "Got invalid request:" << request.url().path(); HttpReply *reply = RestResource::createErrorReply(HttpReply::BadRequest); reply->setClientId(clientId); sendHttpReply(reply); @@ -318,7 +321,7 @@ void WebServer::readClient() // Check HTTP version if (request.httpVersion() != "HTTP/1.1" && request.httpVersion() != "HTTP/1.0") { - qCWarning(dcWebServer) << "HTTP version is not supported." << request.httpVersion(); + qCWarning(dcWebServer()) << "HTTP version is not supported." << request.httpVersion(); HttpReply *reply = RestResource::createErrorReply(HttpReply::HttpVersionNotSupported); reply->setClientId(clientId); sendHttpReply(reply); @@ -326,8 +329,7 @@ void WebServer::readClient() return; } - qCDebug(dcWebServer) << QString("Got valid request from %1:%2").arg(socket->peerAddress().toString()).arg(socket->peerPort()); - qCDebug(dcWebServer) << request.methodString() << request.url().path(); + qCDebug(dcWebServer()).noquote() << QString("Got valid request from %1:%2").arg(socket->peerAddress().toString()).arg(socket->peerPort()) << request.methodString() << request.url().path() << request.urlQuery().toString(); // Reset timout foreach (WebServerClient *webserverClient, m_webServerClients) { @@ -410,7 +412,7 @@ void WebServer::readClient() // Check server.xml call if (request.url().path() == "/server.xml" && request.method() == HttpRequest::Get) { - qCDebug(dcWebServer) << "Server XML request call"; + qCDebug(dcWebServer()) << "Server XML request call"; HttpReply *reply = RestResource::createSuccessReply(); reply->setHeader(HttpReply::ContentTypeHeader, "text/xml"); reply->setPayload(createServerXmlDocument(socket->localAddress())); @@ -424,8 +426,9 @@ void WebServer::readClient() // Request for a file... if (request.method() == HttpRequest::Get) { // Check if the webinterface dir does exist, otherwise a filerequest is not relevant + // FIXME: return a default webpage containing server information if (!QDir(m_configuration.publicFolder).exists()) { - qCWarning(dcWebServer) << "Webinterface folder" << m_configuration.publicFolder << "does not exist."; + qCWarning(dcWebServer()) << "Webinterface folder" << m_configuration.publicFolder << "does not exist."; HttpReply *reply = RestResource::createErrorReply(HttpReply::NotFound); reply->setClientId(clientId); sendHttpReply(reply); @@ -439,7 +442,7 @@ void WebServer::readClient() QFile file(path); if (file.open(QFile::ReadOnly | QFile::Truncate)) { - qCDebug(dcWebServer) << "Load file" << file.fileName(); + qCDebug(dcWebServer()) << "Load file" << file.fileName(); HttpReply *reply = RestResource::createSuccessReply(); // Check content type @@ -476,7 +479,7 @@ void WebServer::readClient() } // Reject everything else... - qCWarning(dcWebServer) << "Unknown message received."; + qCWarning(dcWebServer()) << "Unknown message received."; HttpReply *reply = RestResource::createErrorReply(HttpReply::NotImplemented); reply->setClientId(clientId); sendHttpReply(reply); @@ -492,7 +495,7 @@ void WebServer::onDisconnected() if (client->address() == socket->peerAddress()) { client->removeConnection(socket); if (client->connections().isEmpty()) { - qCDebug(dcWebServer) << "Delete client" << client->address().toString(); + qCDebug(dcWebServer()) << "Delete client" << client->address().toString(); m_webServerClients.removeAll(client); client->deleteLater(); } @@ -500,7 +503,7 @@ void WebServer::onDisconnected() } } - qCDebug(dcWebServer) << QString("Webserver client disonnected %1:%2").arg(socket->peerAddress().toString()).arg(socket->peerPort()); + qCDebug(dcWebServer()).noquote() << QString("Webserver client disonnected %1:%2").arg(socket->peerAddress().toString()).arg(socket->peerPort()); // clean up QUuid clientId = m_clientList.key(socket); @@ -514,7 +517,7 @@ void WebServer::onDisconnected() void WebServer::onEncrypted() { QSslSocket* socket = static_cast(sender()); - qCDebug(dcWebServer()) << QString("Encrypted connection %1:%2 successfully established.").arg(socket->peerAddress().toString()).arg(socket->peerPort()); + qCDebug(dcWebServer()).noquote() << QString("Encrypted connection %1:%2 successfully established.").arg(socket->peerAddress().toString()).arg(socket->peerPort()); connect(socket, SIGNAL(readyRead()), this, SLOT(readClient())); connect(socket, SIGNAL(disconnected()), this, SLOT(onDisconnected())); connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(onError(QAbstractSocket::SocketError))); @@ -524,15 +527,21 @@ void WebServer::onEncrypted() void WebServer::onError(QAbstractSocket::SocketError error) { - Q_UNUSED(error) QSslSocket* socket = static_cast(sender()); - qCWarning(dcWebServer()) << QString("Client socket error %1:%2 ->").arg(socket->peerAddress().toString()).arg(socket->peerPort()) << socket->errorString(); + switch (error) { + case QAbstractSocket::RemoteHostClosedError: + qCDebug(dcWebServer()).noquote() << QString("Client socket error %1:%2 ->").arg(socket->peerAddress().toString()).arg(socket->peerPort()) << socket->errorString(); + break; + default: + qCWarning(dcWebServer()).noquote() << QString("Client socket error %1:%2 ->").arg(socket->peerAddress().toString()).arg(socket->peerPort()) << socket->errorString(); + break; + } } void WebServer::onAsyncReplyFinished() { HttpReply *reply = qobject_cast(sender()); - qCDebug(dcWebServer) << "Async reply finished"; + qCDebug(dcWebServer()) << "Async reply finished"; // check if the reply timeouted if (reply->timedOut()) { @@ -818,13 +827,13 @@ QList WebServerClient::connections() /*! Adds a new connection (\a socket) to this \l{WebServerClient}. A \l{WebServerClient} * can have up to 50 connecections. The connection will timout and closed if the client - * does not use the connection for 12 seconds. + * does not use the connection for 65 seconds. */ void WebServerClient::addConnection(QSslSocket *socket) { QTimer *timer = new QTimer(this); timer->setSingleShot(true); - timer->setInterval(12000); + timer->setInterval(65000); connect(timer, &QTimer::timeout, this, &WebServerClient::onTimout); m_runningConnections.insert(timer, socket); @@ -858,7 +867,8 @@ void WebServerClient::onTimout() { QTimer *timer = static_cast(sender()); QSslSocket *socket = m_runningConnections.value(timer); - qCDebug(dcWebServer) << QString("Client connection timout %1:%2 -> closing connection").arg(socket->peerAddress().toString()).arg(socket->peerPort()); + qCDebug(dcWebServer()).noquote() << QString("Client connection timout %1:%2 -> closing connection").arg(socket->peerAddress().toString()).arg(socket->peerPort()); + removeConnection(socket); socket->close(); } diff --git a/libnymea/loggingcategories.cpp b/libnymea/loggingcategories.cpp index 562aff45..0db6205f 100644 --- a/libnymea/loggingcategories.cpp +++ b/libnymea/loggingcategories.cpp @@ -33,6 +33,7 @@ Q_LOGGING_CATEGORY(dcLogEngine, "LogEngine") Q_LOGGING_CATEGORY(dcTcpServer, "TcpServer") Q_LOGGING_CATEGORY(dcTcpServerTraffic, "TcpServerTraffic") Q_LOGGING_CATEGORY(dcWebServer, "WebServer") +Q_LOGGING_CATEGORY(dcWebServerTraffic, "WebServerTraffic") Q_LOGGING_CATEGORY(dcDebugServer, "DebugServer") Q_LOGGING_CATEGORY(dcWebSocketServer, "WebSocketServer") Q_LOGGING_CATEGORY(dcWebSocketServerTraffic, "WebSocketServerTraffic") diff --git a/libnymea/loggingcategories.h b/libnymea/loggingcategories.h index 72bb9bd1..cbebf13f 100644 --- a/libnymea/loggingcategories.h +++ b/libnymea/loggingcategories.h @@ -41,6 +41,7 @@ Q_DECLARE_LOGGING_CATEGORY(dcLogEngine) Q_DECLARE_LOGGING_CATEGORY(dcTcpServer) Q_DECLARE_LOGGING_CATEGORY(dcTcpServerTraffic) Q_DECLARE_LOGGING_CATEGORY(dcWebServer) +Q_DECLARE_LOGGING_CATEGORY(dcWebServerTraffic) Q_DECLARE_LOGGING_CATEGORY(dcDebugServer) Q_DECLARE_LOGGING_CATEGORY(dcWebSocketServer) Q_DECLARE_LOGGING_CATEGORY(dcWebSocketServerTraffic) diff --git a/server/main.cpp b/server/main.cpp index 4e52fe10..6cf2d25e 100644 --- a/server/main.cpp +++ b/server/main.cpp @@ -111,6 +111,7 @@ int main(int argc, char *argv[]) "TcpServer", "TcpServerTraffic", "WebServer", + "WebServerTraffic", "DebugServer", "WebSocketServer", "WebSocketServerTraffic",