encapsulate HTTP response creation, add common headers

This commit is contained in:
Martin Rotter 2023-12-12 13:46:05 +01:00
parent e81c06be61
commit db57f48846
3 changed files with 54 additions and 27 deletions

View file

@ -48,16 +48,11 @@ void ApiServer::answerClient(QTcpSocket* socket, const HttpRequest& request) {
}
}
reply_message = QSL("HTTP/1.0 200 OK \r\n"
"Access-Control-Allow-Origin: *\r\n"
"Access-Control-Allow-Headers: *\r\n"
"Content-Type: application/json; charset=\"utf-8\"\r\n"
"Content-Length: %1"
"\r\n\r\n")
.arg(QString::number(json_data.size()))
.toLocal8Bit();
reply_message += json_data;
reply_message = generateHttpAnswer(200,
{{QSL("Access-Control-Allow-Origin"), QSL("*")},
{QSL("Access-Control-Allow-Headers"), QSL("*")},
{QSL("Content-Type"), QSL("application/json; charset=\"utf-8\"")}},
json_data);
#if !defined(NDEBUG)
IOFactory::writeFile("a.out", json_data);
@ -69,12 +64,10 @@ void ApiServer::answerClient(QTcpSocket* socket, const HttpRequest& request) {
}
QByteArray ApiServer::processCorsPreflight() const {
QString answer = QSL("HTTP/1.0 204 No Content\r\n"
"Access-Control-Allow-Origin: *\r\n"
"Access-Control-Allow-Headers: *\r\n"
"Access-Control-Allow-Methods: POST, GET, OPTIONS, DELETE\r\n\r\n");
return answer.toLocal8Bit();
return generateHttpAnswer(204,
{{QSL("Access-Control-Allow-Origin"), QSL("*")},
{QSL("Access-Control-Allow-Headers"), QSL("*")},
{QSL("Access-Control-Allow-Methods"), QSL("POST, GET, OPTIONS, DELETE")}});
}
QByteArray ApiServer::processHtmlPage() const {
@ -88,18 +81,14 @@ QByteArray ApiServer::processHtmlPage() const {
page = IOFactory::readFile(WEB_UI_FOLDER + QL1C('/') + WEB_UI_FILE);
}
QString answer = QSL("HTTP/1.0 200 OK\r\n"
"Access-Control-Allow-Origin: *\r\n"
"Access-Control-Allow-Headers: *\r\n"
"Access-Control-Allow-Methods: POST, GET, OPTIONS, DELETE\r\n"
"Content-Type: text/html; charset=\"utf-8\"\r\n"
"Content-Length: %1\r\n"
"\r\n")
.arg(QString::number(page.size()));
QByteArray data = generateHttpAnswer(200,
{{QSL("Access-Control-Allow-Origin"), QSL("*")},
{QSL("Access-Control-Allow-Headers"), QSL("*")},
{QSL("Access-Control-Allow-Methods"), QSL("POST, GET, OPTIONS, DELETE")},
{QSL("Content-Type"), QSL("text/html; charset=\"utf-8\"")}},
page);
QByteArray data = answer.toLocal8Bit();
return data + page;
return data;
}
ApiResponse ApiServer::processRequest(const ApiRequest& req) const {

View file

@ -4,6 +4,8 @@
#include "definitions/definitions.h"
#include <QDateTime>
HttpServer::HttpServer(QObject* parent) : QObject(parent), m_listenAddress(QHostAddress()), m_listenPort(0) {
connect(&m_httpServer, &QTcpServer::newConnection, this, &HttpServer::clientConnected);
@ -64,6 +66,35 @@ void HttpServer::setListenAddressPort(const QString& full_uri, bool start_handle
}
}
QByteArray HttpServer::generateHttpAnswer(int http_code,
const QList<HttpHeader>& headers,
const QByteArray& body) const {
QList<HttpHeader> my_headers = headers;
QByteArray answer = QSL("HTTP/1.0 %1 \r\n").arg(http_code).toLocal8Bit();
int body_length = body.size();
// Append body length.
if (body_length > 0) {
my_headers.append({QSL("Content-Length"), QString::number(body_length)});
}
// Append server ID and other common headers.
my_headers.append({QSL("Date"), QDateTime::currentDateTimeUtc().toString(Qt::DateFormat::RFC2822Date)});
my_headers.append({QSL("Server"), QSL(APP_LONG_NAME)});
for (const HttpHeader& header : my_headers) {
answer.append(QSL("%1: %2\r\n").arg(header.m_name, header.m_value).toLocal8Bit());
}
answer.append(QSL("\r\n").toLocal8Bit());
if (body_length > 0) {
answer.append(body);
}
return answer;
}
void HttpServer::clientConnected() {
QTcpSocket* socket = m_httpServer.nextPendingConnection();

View file

@ -35,6 +35,13 @@ class HttpServer : public QObject {
void setListenAddressPort(const QString& full_uri, bool start_handler);
protected:
struct HttpHeader {
QString m_name;
QString m_value;
};
QByteArray generateHttpAnswer(int http_code, const QList<HttpHeader>& headers, const QByteArray& body = {}) const;
struct HttpRequest {
bool readMethod(QTcpSocket* socket);
bool readUrl(QTcpSocket* socket);