91 lines
2.0 KiB
C++
91 lines
2.0 KiB
C++
#include "pihttpserver.h"
|
|
|
|
#include "piliterals_string.h"
|
|
|
|
|
|
PIHTTPServer::PIHTTPServer() {
|
|
setRequestCallback([this](const MicrohttpdServer::Request & r) -> MicrohttpdServer::Reply {
|
|
MicrohttpdServer::Reply rep;
|
|
rep.setCode(404);
|
|
auto in_path = r.path.split("/");
|
|
in_path.removeAll("");
|
|
auto it = functions.makeReverseIterator();
|
|
bool found = false;
|
|
while (it.next()) {
|
|
if (it.value().function) {
|
|
if (it.value().method == r.method) {
|
|
if (it.value().match(in_path)) {
|
|
rep = it.value().function(r);
|
|
found = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (!found && unhandled) rep = unhandled(r);
|
|
auto hit = reply_headers.makeIterator();
|
|
while (hit.next())
|
|
rep.addHeader(hit.key(), hit.value());
|
|
return rep;
|
|
});
|
|
}
|
|
|
|
|
|
PIHTTPServer::~PIHTTPServer() {
|
|
stop();
|
|
}
|
|
|
|
|
|
void PIHTTPServer::registerPath(const PIString & path, Method method, RequestFunction functor) {
|
|
auto & ep(functions[path + PIString::fromNumber((int)method)]);
|
|
ep.path = path.split("/");
|
|
ep.method = method;
|
|
ep.function = functor;
|
|
ep.path.removeAll("");
|
|
}
|
|
|
|
|
|
void PIHTTPServer::registerUnhandled(RequestFunction functor) {
|
|
unhandled = functor;
|
|
}
|
|
|
|
|
|
void PIHTTPServer::unregisterPath(const PIString & path, Method method) {
|
|
auto pl = path.split("/");
|
|
pl.removeAll("");
|
|
auto it = functions.makeIterator();
|
|
while (it.next()) {
|
|
if (it.value().method == method) {
|
|
if (it.value().path == pl) {
|
|
functions.remove(it.key());
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void PIHTTPServer::unregisterPath(const PIString & path) {
|
|
auto pl = path.split("/");
|
|
pl.removeAll("");
|
|
auto it = functions.makeIterator();
|
|
PIStringList keys;
|
|
while (it.next()) {
|
|
if (it.value().path == pl) {
|
|
keys << it.key();
|
|
}
|
|
}
|
|
for (const auto & k: keys)
|
|
functions.remove(k);
|
|
}
|
|
|
|
|
|
bool PIHTTPServer::Endpoint::match(const PIStringList & in_path) const {
|
|
if (in_path.size() != path.size()) return false;
|
|
for (int i = 0; i < path.size_s(); ++i) {
|
|
if (path[i] == "*"_a) continue;
|
|
if (path[i] != in_path[i]) return false;
|
|
}
|
|
return true;
|
|
}
|