add microhttpd server

This commit is contained in:
2024-11-14 18:15:27 +03:00
parent ee34e8a72e
commit cdde340efe
12 changed files with 599 additions and 221 deletions

View File

@@ -0,0 +1,75 @@
#ifndef MICROHTTPD_SERVER_P_H
#define MICROHTTPD_SERVER_P_H
#include "pibase.h"
#include "piobject.h"
#include "pip_http_server_export.h"
struct MicrohttpdServerConnection;
class PIP_HTTP_SERVER_EXPORT MicrohttpdServer: public PIObject {
PIOBJECT(MicrohttpdServer)
friend struct MicrohttpdServerConnection;
public:
MicrohttpdServer();
virtual ~MicrohttpdServer();
enum class Method {
Unknown,
Get,
Head,
Post,
Put,
Delete,
Connect,
Options,
Trace,
Patch
};
struct PIP_HTTP_SERVER_EXPORT Request {
MicrohttpdServer::Method method;
PIString path;
PIByteArray body;
PIMap<PIString, PIString> headers;
PIMap<PIString, PIString> args;
};
class PIP_HTTP_SERVER_EXPORT Reply {
friend struct MicrohttpdServerConnection;
public:
void addHeader(const PIString & header, const PIString & value);
void removeHeader(const PIString & header);
void setBody(const PIByteArray & b);
void setCode(int c);
private:
void addFixedHeaders();
int code = 200;
PIByteArray body;
PIMap<PIString, PIString> headers;
};
void setWWWRoot(const PIString & path);
void setFavicon(const PIByteArray & im);
bool listen(PINetworkAddress addr);
bool listenAll(ushort port) { return listen({0, port}); }
bool isListen() const;
void stop();
void setRequestCallback(std::function<Reply(Request)> c) { callback = c; }
private:
PIByteArray getFile(PIString name);
PRIVATE_DECLARATION(PIP_HTTP_SERVER_EXPORT)
PIString www_root;
PIByteArray favicon;
std::function<Reply(Request)> callback;
};
#endif

View File

@@ -0,0 +1,33 @@
#ifndef PIHTTPSERVER_H
#define PIHTTPSERVER_H
#include "microhttpd_server_p.h"
#include "pip_http_server_export.h"
class PIP_HTTP_SERVER_EXPORT PIHTTPServer: public MicrohttpdServer {
PIOBJECT_SUBCLASS(PIHTTPServer, MicrohttpdServer)
public:
PIHTTPServer();
virtual ~PIHTTPServer();
using RequestFunction = std::function<MicrohttpdServer::Reply(const MicrohttpdServer::Request &)>;
void registerPath(const PIString & path, RequestFunction functor);
void addReplyHeader(const PIString & name, const PIString & value) { reply_headers[name] = value; }
void removeReplyHeader(const PIString & name) { reply_headers.remove(name); }
void clearReplyHeaders() { reply_headers.clear(); }
private:
struct Endpoint {
bool match(const PIStringList & in_path) const;
PIStringList path;
RequestFunction function;
};
PIMap<PIString, PIString> reply_headers;
PIMap<PIString, Endpoint> functions;
};
#endif

View File

@@ -553,6 +553,17 @@ uint PIString::hash() const {
}
PIByteArray PIString::toAscii() const {
if (isEmpty()) return PIByteArray();
PIByteArray ret;
ret.resize(size());
for (int i = 0; i < size_s(); ++i) {
ret[i] = uchar(at(i).ch);
}
return ret;
}
PIByteArray PIString::toSystem() const {
if (isEmpty()) return PIByteArray();
buildData(__syslocname__);

View File

@@ -1107,6 +1107,10 @@ public:
//! \~russian Тоже самое, что \a toUTF8().
PIByteArray toByteArray() const { return toUTF8(); }
//! \~english Returns \a PIByteArray contains \a dataAscii() of this string without terminating null-char.
//! \~russian Возвращает \a PIByteArray содержащий \a dataAscii() строки без завершающего нулевого байта.
PIByteArray toAscii() const;
//! \~english Returns \a PIByteArray contains \a data() of this string without terminating null-char.
//! \~russian Возвращает \a PIByteArray содержащий \a data() строки без завершающего нулевого байта.
PIByteArray toSystem() const;

View File

@@ -32,16 +32,9 @@
template<typename T>
class PIP_EXPORT PIProtectedVariable {
public:
//! \~english Sets value to copy of \"v\"
//! \~russian Устанавливает значение как копию \"v\"
void set(const T & v) {
PIMutexLocker _ml(mutex);
var = v;
}
//! \~english Sets value by moving \"v\"
//! \~russian Устанавливает значение перемещением \"v\"
void set(T && v) {
//! \~english Sets value to \"v\"
//! \~russian Устанавливает значение как \"v\"
void set(T v) {
PIMutexLocker _ml(mutex);
var = std::move(v);
}
@@ -64,10 +57,10 @@ public:
//! \~russian Разблокирует мьютекс
void unlock() { mutex.unlock(); }
//! \~english Sets value to copy of \"v\"
//! \~russian Устанавливает значение как копию \"v\"
PIProtectedVariable<T> & operator=(const T & v) {
set(v);
//! \~english Sets value to \"v\"
//! \~russian Устанавливает значение как \"v\"
PIProtectedVariable<T> & operator=(T v) {
set(std::move(v));
return *this;
}

View File

@@ -129,6 +129,20 @@ struct base64HelpStruct {
// clang-format on
bool PIByteArray::startsWith(const PIByteArray & o) const {
if (o.isEmpty()) return false;
if (size() < o.size()) return false;
return piCompareBinary(data(), o.data(), o.size());
}
bool PIByteArray::endsWith(const PIByteArray & o) const {
if (o.isEmpty()) return false;
if (size() < o.size()) return false;
return piCompareBinary(data(size() - o.size()), o.data(), o.size());
}
PIByteArray & PIByteArray::convertToBase64() {
return *this = toBase64();
}
@@ -396,6 +410,17 @@ PIByteArray PIByteArray::fromHex(PIString str) {
}
PIByteArray PIByteArray::fromAscii(const char * str) {
PIByteArray ret;
int ind = 0;
while (str[ind] != 0) {
ret.append(str[ind]);
++ind;
}
return ret;
}
PICout operator<<(PICout s, const PIByteArray & ba) {
s.space();
s.saveAndSetControls(0);

View File

@@ -340,6 +340,10 @@ public:
//! \~\sa \a every(), \a any(), \a contains(), \a indexWhere()
inline int entries(std::function<bool(uchar e)> test, ssize_t start = 0) const { return d.entries(test, start); }
bool startsWith(const PIByteArray & o) const;
bool endsWith(const PIByteArray & o) const;
//! \~english Returns the first index at which a given element `e`
//! can be found in the array, or `-1` if it is not present.
//! \~russian Возвращает первый индекс, по которому данный элемент `e`
@@ -1165,6 +1169,8 @@ public:
static PIByteArray fromHex(PIString str);
static PIByteArray fromAscii(const char * str);
//! \~english Return converted from Base 64 data
//! \~russian Возвращает массив из Base 64 представления
static PIByteArray fromBase64(const PIByteArray & base64);