fix tests and http reply

This commit is contained in:
Simon Stürz 2015-09-05 15:11:08 +02:00 committed by Michael Zanetti
parent fad59b5411
commit b11206cbc8
10 changed files with 58 additions and 46 deletions

View File

@ -170,6 +170,7 @@ HttpReply::HttpReply(const HttpReply::HttpStatusCode &statusCode, const HttpRepl
void HttpReply::setHttpStatusCode(const HttpReply::HttpStatusCode &statusCode)
{
m_statusCode = statusCode;
m_reasonPhrase = getHttpReasonPhrase(m_statusCode);
packReply();
}

View File

@ -101,7 +101,6 @@ HttpReply *DevicesResource::proccessGetRequest(const HttpRequest &request, const
if (urlTokens.count() == 5 && urlTokens.at(4) == "states")
return getDeviceStateValues(m_device);
// /api/v1/devices/{deviceId}/states/{stateTypeId}
if (urlTokens.count() >= 6 && urlTokens.at(4) == "states") {
StateTypeId stateTypeId = StateTypeId(urlTokens.at(5));
@ -152,7 +151,6 @@ HttpReply *DevicesResource::proccessPutRequest(const HttpRequest &request, const
HttpReply *DevicesResource::proccessPostRequest(const HttpRequest &request, const QStringList &urlTokens)
{
// POST /api/v1/devices
if (urlTokens.count() == 3)
return addConfiguredDevice(request.payload());
@ -199,7 +197,6 @@ HttpReply *DevicesResource::proccessOptionsRequest(const HttpRequest &request, c
{
Q_UNUSED(request)
Q_UNUSED(urlTokens)
qCDebug(dcRest) << "process options request\n" << request;
return RestResource::createCorsSuccessReply();
}
@ -263,7 +260,6 @@ HttpReply *DevicesResource::removeDevice(Device *device) const
if (result == DeviceManager::DeviceErrorNoError) {
HttpReply *reply = createSuccessReply();
reply->setCloseConnection(true);
return reply;
}
return createErrorReply(HttpReply::Forbidden);

View File

@ -82,6 +82,7 @@ RestResource::~RestResource()
HttpReply *RestResource::createSuccessReply()
{
HttpReply *reply = new HttpReply(HttpReply::Ok, HttpReply::TypeSync);
reply->setPayload("200 Ok");
reply->setHeader(HttpReply::ContentTypeHeader, "application/json; charset=\"utf-8\";");
return reply;
}
@ -90,12 +91,12 @@ HttpReply *RestResource::createCorsSuccessReply()
{
HttpReply *reply = RestResource::createSuccessReply();
reply->setHeader(HttpReply::ContentTypeHeader, "text/plain");
reply->setRawHeader("Accept","text/plain");
reply->setRawHeader("Accept","application/json");
reply->setRawHeader("Allow", "PUT, POST, GET, DELETE, OPTIONS");
reply->setRawHeader("Access-Control-Allow-Methods", "PUT, POST, GET, DELETE, OPTIONS");
reply->setHeader(HttpReply::ContentLenghtHeader, QByteArray::number(0));
reply->setRawHeader("Access-Control-Allow-Headers", "Origin, Content-Type, Accept");
reply->setRawHeader("Access-Control-Max-Age", "1728000");
//reply->setCloseConnection(true);
return reply;
}
@ -111,6 +112,7 @@ HttpReply *RestResource::createErrorReply(const HttpReply::HttpStatusCode &statu
HttpReply *RestResource::createAsyncReply()
{
HttpReply *reply = new HttpReply(HttpReply::Ok, HttpReply::TypeAsync);
reply->setPayload(QByteArray::number(reply->httpStatusCode()) + " " + reply->httpReasonPhrase());
return reply;
}

View File

@ -113,10 +113,8 @@ void RestServer::processHttpRequest(const QUuid &clientId, const HttpRequest &re
// check CORS call for main resource
if (request.method() == HttpRequest::Options && urlTokens.count() == 3) {
qCDebug(dcRest) << "process options request\n" << request;
HttpReply *reply = RestResource::createCorsSuccessReply();
reply->setClientId(clientId);
qCDebug(dcRest) << reply->data();
m_webserver->sendHttpReply(reply);
reply->deleteLater();
return;

View File

@ -182,9 +182,11 @@ HttpReply *RulesResource::removeRule(const RuleId &ruleId) const
RuleEngine::RuleError status = GuhCore::instance()->removeRule(ruleId);
if (status == RuleEngine::RuleErrorNoError)
return createSuccessReply();
if (status == RuleEngine::RuleErrorNoError) {
HttpReply *reply = createSuccessReply();
reply->setHeader(HttpReply::ContentLenghtHeader, "0");
return reply;
}
return createErrorReply(HttpReply::InternalServerError);
}

View File

@ -1,3 +1,4 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* *
* Copyright (C) 2015 Simon Stuerz <simon.stuerz@guh.guru> *
@ -141,11 +142,12 @@ void WebServer::sendHttpReply(HttpReply *reply)
// send raw data
reply->packReply();
qCDebug(dcWebServer) << "respond" << reply->httpStatusCode() << reply->httpReasonPhrase();
socket->write(reply->data());
// close the connection if wanted
if (reply->closeConnection())
socket->close();
// // close the connection if wanted
// if (reply->closeConnection())
// socket->close();
}
@ -255,7 +257,6 @@ void WebServer::incomingConnection(qintptr socketDescriptor)
emit clientConnected(clientId);
}
void WebServer::readClient()
{
if (!m_enabled)
@ -268,7 +269,6 @@ void WebServer::readClient()
if (clientId.isNull()) {
qCWarning(dcWebServer) << "Client not recognized";
socket->close();
socket->deleteLater();
return;
}
@ -350,6 +350,9 @@ void WebServer::readClient()
if (file.fileName().endsWith(".html")) {
reply->setHeader(HttpReply::ContentTypeHeader, "text/html; charset=\"utf-8\";");
}
if (file.fileName().endsWith(".css")) {
reply->setHeader(HttpReply::ContentTypeHeader, "text/css; charset=\"utf-8\";");
}
reply->setPayload(file.readAll());
reply->setClientId(clientId);
sendHttpReply(reply);
@ -369,15 +372,30 @@ void WebServer::readClient()
void WebServer::onDisconnected()
{
QSslSocket* socket = static_cast<QSslSocket *>(sender());
qCDebug(dcConnection) << "Webserver client disonnected.";
// remove connection from server client
foreach (WebServerClient *client, m_webServerClients) {
if (client->address() == socket->peerAddress()) {
client->removeConnection(socket);
qCDebug(dcWebServer) << "connection count" << client->connections().count();
if (client->connections().isEmpty()) {
m_webServerClients.removeAll(client);
qCDebug(dcWebServer) << "delete client" << client->address().toString();
client->deleteLater();
}
break;
}
}
qCDebug(dcConnection) << QString("Webserver client disonnected %1:%2").arg(socket->peerAddress().toString()).arg(socket->peerPort());
// clean up
QUuid clientId = m_clientList.key(socket);
m_clientList.remove(clientId);
m_incompleteRequests.remove(socket);
socket->deleteLater();
emit clientDisconnected(clientId);
socket->deleteLater();
}
void WebServer::onEncrypted()
@ -405,6 +423,7 @@ bool WebServer::startServer()
m_enabled = false;
return false;
}
if (m_useSsl) {
qCDebug(dcConnection) << "Started webserver on" << QString("https://%1:%2").arg(serverAddress().toString()).arg(m_port);
} else {
@ -444,17 +463,24 @@ void WebServerClient::addConnection(QSslSocket *socket)
{
QTimer *timer = new QTimer(this);
timer->setSingleShot(true);
timer->setInterval(6000);
timer->setInterval(9500);
connect(timer, &QTimer::timeout, this, &WebServerClient::onTimout);
m_runningConnections.insert(timer, socket);
m_connections.append(socket);
connect(socket, SIGNAL(disconnected()), this, SLOT(onDisconnected()));
timer->start();
}
void WebServerClient::removeConnection(QSslSocket *socket)
{
QTimer *timer = m_runningConnections.key(socket);
m_runningConnections.remove(timer);
m_connections.removeAll(socket);
timer->deleteLater();
}
void WebServerClient::resetTimout(QSslSocket *socket)
{
QTimer *timer = 0;
@ -466,22 +492,10 @@ void WebServerClient::resetTimout(QSslSocket *socket)
void WebServerClient::onTimout()
{
QTimer *timer = static_cast<QTimer *>(sender());
QSslSocket *socket = m_runningConnections.take(timer);
QSslSocket *socket = m_runningConnections.value(timer);
qCDebug(dcWebServer) << QString("Client connection timout %1:%2 -> closing connection").arg(socket->peerAddress().toString()).arg(socket->peerPort());
socket->close();
timer->deleteLater();
}
void WebServerClient::onDisconnected()
{
QSslSocket *socket = static_cast<QSslSocket *>(sender());
if (!m_runningConnections.values().contains(socket))
return;
QTimer *timer = m_runningConnections.key(socket);
m_runningConnections.remove(timer);
timer->deleteLater();
}
}

View File

@ -50,6 +50,7 @@ public:
QList<QSslSocket *> connections();
void addConnection(QSslSocket *socket);
void removeConnection(QSslSocket *socket);
void resetTimout(QSslSocket *socket);
@ -60,7 +61,7 @@ private:
private slots:
void onTimout();
void onDisconnected();
};

View File

@ -297,19 +297,19 @@ void TestRestDeviceClasses::discoverDevices()
qDebug() << data;
statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
reply->deleteLater();
QCOMPARE(statusCode, expectedStatusCode);
jsonDoc = QJsonDocument::fromJson(data, &error);
QCOMPARE(error.error, QJsonParseError::NoError);
reply->deleteLater();
QVariantMap response = jsonDoc.toVariant().toMap();
DeviceId deviceId = DeviceId(response.value("id").toString());
QVERIFY2(!deviceId.isNull(), "got invalid device id");
// REMOVE added device
request = QNetworkRequest(QUrl(QString("http://localhost:3333/api/v1/devices/%1").arg(deviceId.toString())));
qDebug() << request.url().toString();
clientSpy.clear();
reply = nam->deleteResource(request);
clientSpy.wait();

View File

@ -419,7 +419,7 @@ void TestRestDevices::editDevices()
QNetworkRequest request(QUrl(QString("http://localhost:3333/api/v1/devices")));
QNetworkReply *reply = nam->post(request, QJsonDocument::fromVariant(params).toJson());
QNetworkReply *reply = nam->post(request, QJsonDocument::fromVariant(params).toJson(QJsonDocument::Compact));
clientSpy.wait();
QCOMPARE(clientSpy.count(), 1);

View File

@ -160,7 +160,7 @@ void TestRestDeviceClasses::setPluginConfiguration()
request.setUrl(QUrl(QString("http://localhost:3333/api/v1/plugins/%1/configuration").arg(pluginId.toString())));
QNetworkReply *reply = nam->get(request);
clientSpy.wait();
QVERIFY2(clientSpy.count() == 1, "expected exactly 1 response from webserver");
QCOMPARE(clientSpy.count(), 1);
int statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
reply->deleteLater();
@ -184,7 +184,7 @@ void TestRestDeviceClasses::setPluginConfiguration()
request.setUrl(QUrl(QString("http://localhost:3333/api/v1/plugins/%1/configuration").arg(pluginId.toString())));
reply = nam->put(request, QJsonDocument::fromVariant(newConfigurations).toJson(QJsonDocument::Compact));
clientSpy.wait();
QVERIFY2(clientSpy.count() == 1, "expected exactly 1 response from webserver");
QCOMPARE(clientSpy.count(), 1);
statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
QCOMPARE(statusCode, expectedStatusCode);
reply->deleteLater();
@ -197,7 +197,7 @@ void TestRestDeviceClasses::setPluginConfiguration()
request.setUrl(QUrl(QString("http://localhost:3333/api/v1/plugins/%1/configuration").arg(pluginId.toString())));
reply = nam->get(request);
clientSpy.wait();
QVERIFY2(clientSpy.count() == 1, "expected exactly 1 response from webserver");
QCOMPARE(clientSpy.count(), 1);
statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
QCOMPARE(statusCode, expectedStatusCode);
data = reply->readAll();
@ -211,14 +211,12 @@ void TestRestDeviceClasses::setPluginConfiguration()
// verify new configurations
verifyParams(newConfigurations, checkConfigurations);
restartServer();
// check new configurations after restart
clientSpy.clear();
request.setUrl(QUrl(QString("http://localhost:3333/api/v1/plugins/%1/configuration").arg(pluginId.toString())));
reply = nam->get(request);
clientSpy.wait();
QVERIFY2(clientSpy.count() == 1, "expected exactly 1 response from webserver");
QCOMPARE(clientSpy.count(), 1);
statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
QCOMPARE(statusCode, 200);
data = reply->readAll();