Update webserver debug output, add WebServerTraffic category and fix favicons for debugserver
This commit is contained in:
parent
b9dda16af9
commit
e51508ee33
@ -11,5 +11,18 @@
|
||||
<file>favicons/favicon-196x196.png</file>
|
||||
<file>favicons/favicon.ico</file>
|
||||
<file>favicons/favicon.svg</file>
|
||||
<file>favicons/mstile-70x70.png</file>
|
||||
<file>favicons/mstile-144x144.png</file>
|
||||
<file>favicons/mstile-150x150.png</file>
|
||||
<file>favicons/mstile-310x150.png</file>
|
||||
<file>favicons/mstile-310x310.png</file>
|
||||
<file>favicons/apple-touch-icon-152x152.png</file>
|
||||
<file>favicons/apple-touch-icon-144x144.png</file>
|
||||
<file>favicons/apple-touch-icon-57x57.png</file>
|
||||
<file>favicons/apple-touch-icon-60x60.png</file>
|
||||
<file>favicons/apple-touch-icon-72x72.png</file>
|
||||
<file>favicons/apple-touch-icon-76x76.png</file>
|
||||
<file>favicons/apple-touch-icon-114x114.png</file>
|
||||
<file>favicons/apple-touch-icon-120x120.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
||||
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -151,7 +151,7 @@ void RestServer::asyncReplyFinished()
|
||||
HttpReply *reply = qobject_cast<HttpReply*>(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);
|
||||
|
||||
@ -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<QSslSocket *>(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<QSslSocket *>(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<HttpReply*>(sender());
|
||||
qCDebug(dcWebServer) << "Async reply finished";
|
||||
qCDebug(dcWebServer()) << "Async reply finished";
|
||||
|
||||
// check if the reply timeouted
|
||||
if (reply->timedOut()) {
|
||||
@ -818,13 +827,13 @@ QList<QSslSocket *> 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<QTimer *>(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();
|
||||
}
|
||||
|
||||
|
||||
@ -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")
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -111,6 +111,7 @@ int main(int argc, char *argv[])
|
||||
"TcpServer",
|
||||
"TcpServerTraffic",
|
||||
"WebServer",
|
||||
"WebServerTraffic",
|
||||
"DebugServer",
|
||||
"WebSocketServer",
|
||||
"WebSocketServerTraffic",
|
||||
|
||||
Reference in New Issue
Block a user