121 lines
4.6 KiB
C++
121 lines
4.6 KiB
C++
//! \addtogroup HTTP
|
||
//! \{
|
||
//! \file pihttpserver.h
|
||
//! \brief High-level HTTP server implementation
|
||
//! \~english High-level HTTP server with path-based routing and handler registration
|
||
//! \~russian Высокоуровневый HTTP сервер с маршрутизацией по путям и регистрацией обработчиков
|
||
//! \details
|
||
//! \~english Provides path-based request routing and handler management
|
||
//! \~russian Обеспечивает маршрутизацию запросов по путям и управление обработчиками
|
||
//! \}
|
||
|
||
#ifndef PIHTTPSERVER_H
|
||
#define PIHTTPSERVER_H
|
||
|
||
#include "microhttpd_server.h"
|
||
|
||
//! \~english HTTP server
|
||
//! \~russian HTTP сервер
|
||
class PIP_HTTP_SERVER_EXPORT PIHTTPServer: public MicrohttpdServer {
|
||
PIOBJECT_SUBCLASS(PIHTTPServer, MicrohttpdServer)
|
||
|
||
public:
|
||
//! \~english Constructs a new HTTP server
|
||
//! \~russian Создает новый HTTP сервер
|
||
PIHTTPServer();
|
||
//! \~english Destroys the HTTP server
|
||
//! \~russian Уничтожает HTTP сервер
|
||
virtual ~PIHTTPServer();
|
||
|
||
using RequestFunction = std::function<PIHTTP::MessageMutable(const PIHTTP::MessageConst &)>;
|
||
|
||
|
||
//! \~english Registers handler for specific path and HTTP method
|
||
//! \~russian Регистрирует обработчик для указанного пути и HTTP метода
|
||
bool registerPath(const PIString & path, PIHTTP::Method method, RequestFunction functor);
|
||
|
||
//! \~english Registers handler for specific path and HTTP method
|
||
//! \~russian Регистрирует обработчик для указанного пути и HTTP метода
|
||
template<typename T>
|
||
bool
|
||
registerPath(const PIString & path, PIHTTP::Method method, T * o, PIHTTP::MessageMutable (T::*function)(const PIHTTP::MessageConst &)) {
|
||
return registerPath(path, method, [o, function](const PIHTTP::MessageConst & m) { return (o->*function)(m); });
|
||
}
|
||
|
||
|
||
//! \~english Registers handler for unregistered pathes
|
||
//! \~russian Регистрирует обработчик для незарегистрированных путей
|
||
void registerUnhandled(RequestFunction functor);
|
||
|
||
//! \~english Registers handler for unregistered pathes
|
||
//! \~russian Регистрирует обработчик для незарегистрированных путей
|
||
template<typename T>
|
||
void registerUnhandled(T * o, PIHTTP::MessageMutable (T::*function)(const PIHTTP::MessageConst &)) {
|
||
registerUnhandled([o, function](const PIHTTP::MessageConst & m) { return (o->*function)(m); });
|
||
}
|
||
|
||
//! \~english Unregisters handler for specific path and method
|
||
//! \~russian Удаляет обработчик для указанного пути и метода
|
||
void unregisterPath(const PIString & path, PIHTTP::Method method);
|
||
|
||
//! \~english Unregisters all handlers for specific path
|
||
//! \~russian Удаляет все обработчики для указанного пути
|
||
void unregisterPath(const PIString & path);
|
||
|
||
|
||
//! \~english Adds header to all server responses
|
||
//! \~russian Добавляет заголовок ко всем ответам сервера
|
||
void addReplyHeader(const PIString & name, const PIString & value) { reply_headers[name] = value; }
|
||
|
||
//! \~english Removes header from server responses
|
||
//! \~russian Удаляет заголовок из ответов сервера
|
||
void removeReplyHeader(const PIString & name) { reply_headers.remove(name); }
|
||
|
||
//! \~english Clears all custom response headers
|
||
//! \~russian Очищает все пользовательские заголовки ответов
|
||
void clearReplyHeaders() { reply_headers.clear(); }
|
||
|
||
private:
|
||
struct PathElement {
|
||
enum class Type {
|
||
Invalid = 0x01,
|
||
Fixed = 0x02,
|
||
Arguments = 0x04,
|
||
AnyOne = 0x08,
|
||
AnyPart = 0x10,
|
||
AnyMany = 0x20
|
||
};
|
||
|
||
Type type = Type::Fixed;
|
||
PIString source;
|
||
PIStringList parts;
|
||
PIMap<int, PIString> arguments;
|
||
|
||
PathElement(const PIString & reg = {});
|
||
|
||
bool match(const PIString & in, PIMap<PIString, PIString> & ext_args) const;
|
||
uint priority() const;
|
||
};
|
||
|
||
struct Endpoint {
|
||
PIStringList path;
|
||
PIHTTP::Method method = PIHTTP::Method::Unknown;
|
||
RequestFunction function;
|
||
PIFlags<PathElement::Type> path_types;
|
||
PIVector<PathElement> prepared_path;
|
||
uint priority = 0;
|
||
|
||
bool create(const PIString & p);
|
||
bool match(const PIStringList & in_path, PIMap<PIString, PIString> & ext_args) const;
|
||
};
|
||
|
||
static PIStringList splitPath(const PIString & path);
|
||
|
||
PIMap<PIString, PIString> reply_headers;
|
||
PIMap<uint, PIVector<Endpoint>> endpoints;
|
||
RequestFunction unhandled;
|
||
};
|
||
|
||
|
||
#endif
|