Remove all JSON marshalling code from QObjectHandler.
This commit is contained in:
@@ -21,9 +21,6 @@
|
||||
*/
|
||||
|
||||
#include <QGenericArgument>
|
||||
#include <QJsonParseError>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QMetaMethod>
|
||||
|
||||
#include <QHttpEngine/QObjectHandler>
|
||||
@@ -36,75 +33,6 @@ QObjectHandlerPrivate::QObjectHandlerPrivate(QObjectHandler *handler)
|
||||
{
|
||||
}
|
||||
|
||||
void QObjectHandlerPrivate::invokeSlot(QHttpSocket *socket, const QString &path)
|
||||
{
|
||||
Method m = map.value(path);
|
||||
QVariantMap parameters;
|
||||
|
||||
// If data was supplied, decode it as JSON
|
||||
if (socket->bytesAvailable()) {
|
||||
QJsonParseError error;
|
||||
QJsonDocument document = QJsonDocument::fromJson(socket->readAll(), &error);
|
||||
|
||||
// Ensure that the document is valid
|
||||
if (error.error != QJsonParseError::NoError) {
|
||||
socket->writeError(QHttpSocket::BadRequest);
|
||||
return;
|
||||
}
|
||||
|
||||
parameters = document.object().toVariantMap();
|
||||
}
|
||||
|
||||
QVariantMap retVal;
|
||||
|
||||
// Invoke the slot
|
||||
if (m.oldSlot) {
|
||||
|
||||
// Obtain the slot index
|
||||
int index = m.receiver->metaObject()->indexOfSlot(m.slot.method + 1);
|
||||
if (index == -1) {
|
||||
socket->writeError(QHttpSocket::InternalServerError);
|
||||
return;
|
||||
}
|
||||
|
||||
QMetaMethod method = m.receiver->metaObject()->method(index);
|
||||
|
||||
// Ensure the parameters are correct
|
||||
QList<QByteArray> params = method.parameterTypes();
|
||||
if (params.count() > 0 && params.at(0) != "QHttpSocket*" ||
|
||||
params.count() > 1 && params.at(1) != "QVariantMap" ||
|
||||
params.count() > 2 ||
|
||||
method.returnType() != QMetaType::QVariantMap) {
|
||||
socket->writeError(QHttpSocket::InternalServerError);
|
||||
return;
|
||||
}
|
||||
|
||||
// Invoke the method
|
||||
if (!m.receiver->metaObject()->method(index).invoke(
|
||||
m.receiver,
|
||||
Q_RETURN_ARG(QVariantMap, retVal),
|
||||
Q_ARG(QHttpSocket*, socket),
|
||||
Q_ARG(QVariantMap, parameters))) {
|
||||
socket->writeError(QHttpSocket::InternalServerError);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
void *args[3] = {
|
||||
&retVal,
|
||||
&socket,
|
||||
¶meters
|
||||
};
|
||||
m.slot.slotObj->call(m.receiver, args);
|
||||
}
|
||||
|
||||
// Convert the return value to JSON and write it to the socket
|
||||
QByteArray data = QJsonDocument(QJsonObject::fromVariantMap(retVal)).toJson();
|
||||
socket->setHeader("Content-Length", QByteArray::number(data.length()));
|
||||
socket->setHeader("Content-Type", "application/json");
|
||||
socket->write(data);
|
||||
socket->close();
|
||||
}
|
||||
|
||||
QObjectHandler::QObjectHandler(QObject *parent)
|
||||
: QHttpHandler(parent),
|
||||
d(new QObjectHandlerPrivate(this))
|
||||
@@ -119,31 +47,48 @@ void QObjectHandler::process(QHttpSocket *socket, const QString &path)
|
||||
return;
|
||||
}
|
||||
|
||||
// Ensure the method is accepted
|
||||
QObjectHandlerPrivate::Method m = d->map.value(path);
|
||||
if (!(m.acceptedMethods & socket->method())) {
|
||||
// TODO: accept header
|
||||
socket->writeError(QHttpSocket::MethodNotAllowed);
|
||||
return;
|
||||
}
|
||||
|
||||
// If the slot has finished receiving all of the data, jump directly to
|
||||
// invokeSlot(), otherwise, wait until we have the rest of it
|
||||
if (socket->bytesAvailable() >= socket->contentLength()) {
|
||||
d->invokeSlot(socket, path);
|
||||
// Invoke the slot
|
||||
if (m.oldSlot) {
|
||||
|
||||
// Obtain the slot index
|
||||
int index = m.receiver->metaObject()->indexOfSlot(m.slot.method + 1);
|
||||
if (index == -1) {
|
||||
socket->writeError(QHttpSocket::InternalServerError);
|
||||
return;
|
||||
}
|
||||
|
||||
QMetaMethod method = m.receiver->metaObject()->method(index);
|
||||
|
||||
// Ensure the parameter is correct
|
||||
QList<QByteArray> params = method.parameterTypes();
|
||||
if (params.count() != 1 || params.at(0) != "QHttpSocket*") {
|
||||
socket->writeError(QHttpSocket::InternalServerError);
|
||||
return;
|
||||
}
|
||||
|
||||
// Invoke the method
|
||||
if (!m.receiver->metaObject()->method(index).invoke(
|
||||
m.receiver, Q_ARG(QHttpSocket*, socket))) {
|
||||
socket->writeError(QHttpSocket::InternalServerError);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
connect(socket, &QHttpSocket::readChannelFinished, [this, socket, path]() {
|
||||
d->invokeSlot(socket, path);
|
||||
});
|
||||
void *args[] = {
|
||||
Q_NULLPTR,
|
||||
&socket
|
||||
};
|
||||
m.slot.slotObj->call(m.receiver, args);
|
||||
}
|
||||
}
|
||||
|
||||
void QObjectHandler::registerMethod(const QString &name, QObject *receiver, const char *method, int acceptedStatusCodes)
|
||||
void QObjectHandler::registerMethod(const QString &name, QObject *receiver, const char *method)
|
||||
{
|
||||
d->map.insert(name, QObjectHandlerPrivate::Method(receiver, method, acceptedStatusCodes));
|
||||
d->map.insert(name, QObjectHandlerPrivate::Method(receiver, method));
|
||||
}
|
||||
|
||||
void QObjectHandler::registerMethodImpl(const QString &name, QObject *receiver, QtPrivate::QSlotObjectBase *slotObj, int acceptedStatusCodes)
|
||||
void QObjectHandler::registerMethodImpl(const QString &name, QObject *receiver, QtPrivate::QSlotObjectBase *slotObj)
|
||||
{
|
||||
d->map.insert(name, QObjectHandlerPrivate::Method(receiver, slotObj, acceptedStatusCodes));
|
||||
d->map.insert(name, QObjectHandlerPrivate::Method(receiver, slotObj));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user