1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
|
// Copyright (C) 2022 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include "apibehavior.h"
#include "types.h"
#include "utils.h"
#include <QtCore/QCoreApplication>
#include <QtHttpServer/QHttpServer>
#define SCHEME "http"
#define HOST "127.0.0.1"
#define PORT 49425
template<typename T>
void addCrudRoutes(QHttpServer &httpServer, const QString &apiPath, CrudApi<T> &api,
const SessionApi &sessionApi)
{
//! [GET paginated list example]
httpServer.route(
QString("%1").arg(apiPath), QHttpServerRequest::Method::Get,
[&api](const QHttpServerRequest &request) { return api.getPaginatedList(request); });
//! [GET paginated list example]
//! [GET single item example]
httpServer.route(QString("%1/<arg>").arg(apiPath), QHttpServerRequest::Method::Get,
[&api](qint64 itemId) { return api.getItem(itemId); });
//! [GET single item example]
//! [POST example]
httpServer.route(QString("%1").arg(apiPath), QHttpServerRequest::Method::Post,
[&api, &sessionApi](const QHttpServerRequest &request) {
if (!sessionApi.authorize(request)) {
return QHttpServerResponse(
QHttpServerResponder::StatusCode::Unauthorized);
}
return api.postItem(request);
});
//! [POST example]
httpServer.route(QString("%1/<arg>").arg(apiPath), QHttpServerRequest::Method::Put,
[&api, &sessionApi](qint64 itemId, const QHttpServerRequest &request) {
if (!sessionApi.authorize(request)) {
return QHttpServerResponse(
QHttpServerResponder::StatusCode::Unauthorized);
}
return api.updateItem(itemId, request);
});
httpServer.route(QString("%1/<arg>").arg(apiPath), QHttpServerRequest::Method::Patch,
[&api, &sessionApi](qint64 itemId, const QHttpServerRequest &request) {
if (!sessionApi.authorize(request)) {
return QHttpServerResponse(
QHttpServerResponder::StatusCode::Unauthorized);
}
return api.updateItemFields(itemId, request);
});
httpServer.route(QString("%1/<arg>").arg(apiPath), QHttpServerRequest::Method::Delete,
[&api, &sessionApi](qint64 itemId, const QHttpServerRequest &request) {
if (!sessionApi.authorize(request)) {
return QHttpServerResponse(
QHttpServerResponder::StatusCode::Unauthorized);
}
return api.deleteItem(itemId);
});
}
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
QCommandLineParser parser;
parser.addOptions({
{ "port", QCoreApplication::translate("main", "The port the server listens on."),
"port" },
});
parser.addHelpOption();
parser.process(app);
quint16 portArg = PORT;
if (!parser.value("port").isEmpty())
portArg = parser.value("port").toUShort();
auto colorFactory = std::make_unique<ColorFactory>();
auto colors = tryLoadFromFile<Color>(*colorFactory, ":/assets/colors.json");
CrudApi<Color> colorsApi(std::move(colors), std::move(colorFactory));
auto userFactory = std::make_unique<UserFactory>(SCHEME, HOST, portArg);
auto users = tryLoadFromFile<User>(*userFactory, ":/assets/users.json");
CrudApi<User> usersApi(std::move(users), std::move(userFactory));
auto sessionEntryFactory = std::make_unique<SessionEntryFactory>();
auto sessions = tryLoadFromFile<SessionEntry>(*sessionEntryFactory, ":/assets/sessions.json");
SessionApi sessionApi(std::move(sessions), std::move(sessionEntryFactory));
// Setup QHttpServer
QHttpServer httpServer;
httpServer.route("/", []() {
return "Qt Colorpalette example server. Please see documentation for API description";
});
addCrudRoutes(httpServer, "/api/unknown", colorsApi, sessionApi);
addCrudRoutes(httpServer, "/api/users", usersApi, sessionApi);
// Login resource
httpServer.route(
"/api/login", QHttpServerRequest::Method::Post,
[&sessionApi](const QHttpServerRequest &request) { return sessionApi.login(request); });
httpServer.route("/api/register", QHttpServerRequest::Method::Post,
[&sessionApi](const QHttpServerRequest &request) {
return sessionApi.registerSession(request);
});
httpServer.route("/api/logout", QHttpServerRequest::Method::Post,
[&sessionApi](const QHttpServerRequest &request) {
return sessionApi.logout(request);
});
// Images resource
httpServer.route("/img/faces/<arg>-image.jpg", QHttpServerRequest::Method::Get,
[](qint64 imageId, const QHttpServerRequest &) {
return QHttpServerResponse::fromFile(
QString(":/assets/img/%1-image.jpg").arg(imageId));
});
auto tcpserver = std::make_unique<QTcpServer>();
if (!tcpserver->listen(QHostAddress::Any, portArg) || !httpServer.bind(tcpserver.get())) {
qDebug() << QCoreApplication::translate("QHttpServerExample",
"Server failed to listen on a port.");
return 0;
}
quint16 port = tcpserver->serverPort();
tcpserver.release();
qDebug() << QCoreApplication::translate(
"QHttpServerExample",
"Running on http://127.0.0.1:%1/ (Press CTRL+C to quit)")
.arg(port);
return app.exec();
}
|