diff --git a/CMakeLists.txt b/CMakeLists.txt index f44a16e3..a0c13d65 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,9 +5,9 @@ if (POLICY CMP0177) endif() project(PIP) set(PIP_MAJOR 5) -set(PIP_MINOR 0) +set(PIP_MINOR 1) set(PIP_REVISION 0) -set(PIP_SUFFIX _beta) +set(PIP_SUFFIX ) set(PIP_COMPANY SHS) set(PIP_DOMAIN org.SHS) diff --git a/libs/http_server/microhttpd_server_p.cpp b/libs/http_server/microhttpd_server_p.cpp index 5470141a..23529d3f 100644 --- a/libs/http_server/microhttpd_server_p.cpp +++ b/libs/http_server/microhttpd_server_p.cpp @@ -93,8 +93,8 @@ bool MicrohttpdServerConnection::ready() { req.setMethod(method); req.setPath(path); req.setBody(body); - req.headers() = headers; - req.arguments() = args; + req.headers() = headers; + req.queryArguments() = args; rep.setCode(Code::BadRequest); if (server->callback) rep = server->callback(req); MicrohttpdServer::addFixedHeaders(rep); @@ -150,14 +150,14 @@ void log_callback(void * cls, const char * fmt, va_list ap) { int iterate_post(void * conn_cls, - MHD_ValueKind kind, - const char * key, - const char * filename, - const char * content_type, - const char * transfer_encoding, - const char * data, - uint64_t off, - size_t size) { + MHD_ValueKind kind, + const char * key, + const char * filename, + const char * content_type, + const char * transfer_encoding, + const char * data, + uint64_t off, + size_t size) { MicrohttpdServerConnection * conn = (MicrohttpdServerConnection *)conn_cls; if (!conn) return MHD_NO; conn->post[PIString::fromUTF8(key)] = PIString::fromUTF8(data); @@ -195,13 +195,13 @@ int args_iterate(void * cls, MHD_ValueKind kind, const char * key, const char * int answer_callback(void * cls, - MHD_Connection * connection, - const char * url, - const char * method, - const char * version, - const char * upload_data, - size_t * upload_data_size, - void ** con_cls) { + MHD_Connection * connection, + const char * url, + const char * method, + const char * version, + const char * upload_data, + size_t * upload_data_size, + void ** con_cls) { MicrohttpdServer * server = (MicrohttpdServer *)cls; Method m = Method::Unknown; diff --git a/libs/http_server/pihttpserver.cpp b/libs/http_server/pihttpserver.cpp index 9208425d..b80dfd7b 100644 --- a/libs/http_server/pihttpserver.cpp +++ b/libs/http_server/pihttpserver.cpp @@ -7,20 +7,25 @@ PIHTTPServer::PIHTTPServer() { setRequestCallback([this](const PIHTTP::MessageConst & r) -> PIHTTP::MessageMutable { PIHTTP::MessageMutable reply; reply.setCode(PIHTTP::Code::NotFound); - auto in_path = r.path().split("/"); - in_path.removeAll(""); - auto it = functions.makeReverseIterator(); - bool found = false; + auto in_path = splitPath(r.path()); + auto it = endpoints.makeReverseIterator(); + bool found = false; while (it.next()) { - if (it.value().function) { - if (it.value().method == r.method()) { - if (it.value().match(in_path)) { - reply = it.value().function(r); + for (const auto & ep: it.value()) { + if (ep.function && ep.method == r.method()) { + PIMap ext_args; + if (ep.match(in_path, ext_args)) { + auto & r_mut(static_cast(const_cast(r))); + r_mut.pathArguments() = ext_args; + r_mut.arguments() = r_mut.pathArguments(); + r_mut.arguments() << r_mut.queryArguments(); + reply = ep.function(r); found = true; break; } } } + if (found) break; } if (!found && unhandled) reply = unhandled(r); auto hit = reply_headers.makeIterator(); @@ -36,12 +41,13 @@ PIHTTPServer::~PIHTTPServer() { } -void PIHTTPServer::registerPath(const PIString & path, PIHTTP::Method method, RequestFunction functor) { - auto & ep(functions[path + PIString::fromNumber(static_cast(method))]); - ep.path = path.split("/"); +bool PIHTTPServer::registerPath(const PIString & path, PIHTTP::Method method, RequestFunction functor) { + Endpoint ep; + if (!ep.create(path)) return false; ep.method = method; ep.function = functor; - ep.path.removeAll(""); + endpoints[ep.priority] << ep; + return true; } @@ -51,40 +57,143 @@ void PIHTTPServer::registerUnhandled(RequestFunction functor) { void PIHTTPServer::unregisterPath(const PIString & path, PIHTTP::Method method) { - auto pl = path.split("/"); - pl.removeAll(""); - auto it = functions.makeIterator(); + auto pl = splitPath(path); + auto it = endpoints.makeIterator(); while (it.next()) { - if (it.value().method == method) { - if (it.value().path == pl) { - functions.remove(it.key()); - break; - } - } + it.value().removeWhere([&pl, method](const Endpoint & ep) { return ep.path == pl && ep.method == method; }); } + endpoints.removeWhere([](uint, const PIVector & epl) { return epl.isEmpty(); }); } void PIHTTPServer::unregisterPath(const PIString & path) { - auto pl = path.split("/"); - pl.removeAll(""); - auto it = functions.makeIterator(); - PIStringList keys; + auto pl = splitPath(path); + auto it = endpoints.makeIterator(); while (it.next()) { - if (it.value().path == pl) { - keys << it.key(); - } + it.value().removeWhere([&pl](const Endpoint & ep) { return ep.path == pl; }); } - for (const auto & k: keys) - functions.remove(k); + endpoints.removeWhere([](uint, const PIVector & epl) { return epl.isEmpty(); }); } -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; +PIStringList PIHTTPServer::splitPath(const PIString & path) { + auto ret = path.split("/"); + ret.removeAll({}); + return ret; +} + + +PIHTTPServer::PathElement::PathElement(const PIString & reg) { + source = reg; + if (reg == "*"_a) { + type = Type::AnyOne; + } else if (reg == "**"_a) { + type = Type::AnyMany; + } else if (reg.contains('*')) { + type = Type::AnyPart; + parts = reg.split('*'); + } else if (reg.contains('{')) { + type = Type::Arguments; + int ind = 0, eind = 0, pind = 0; + for (;;) { + ind = reg.find('{', ind); + if (ind < 0) break; + eind = reg.find('}', ind + 1); + if (eind < 0) break; + arguments.insert(arguments.size_s(), reg.mid(ind + 1, eind - ind - 1)); + if (ind == 0) + parts << PIString(); + else { + if (ind > pind) + parts << reg.mid(pind, ind - pind); + else if (parts.isNotEmpty()) { + piCout << "[PIHTTPServer] Warning: sequential arguments, ignoring this path!"; + type = Type::Invalid; + return; + } + } + ind = pind = eind + 1; + } + if (eind < reg.size_s() - 1) parts << reg.mid(eind + 1); + } +} + + +bool PIHTTPServer::PathElement::match(const PIString & in, PIMap & ext_args) const { + // piCout << "match" << source << "with" << in; + if (type == Type::AnyOne) return true; + if (type == Type::AnyPart) { + int ind = 0; + for (const auto & m: parts) { + ind = in.find(m, ind); + if (ind < 0) return false; + } + return true; + } + if (type == Type::Arguments) { + int ind = 0, eind = 0; + for (int i = 0; i < parts.size_s(); ++i) { + const auto & m(parts[i]); + if (m.isNotEmpty()) { + ind = in.find(m, eind); + if (ind < 0) return false; + } + if (i > 0) { + ext_args[arguments.value(i - 1)] = in.mid(eind, ind - eind); + } + eind = ind + m.size_s(); + } + if (parts.size() == arguments.size()) { + ext_args[arguments.value(arguments.size_s() - 1)] = in.mid(eind); + } + return true; + } + return source == in; +} + + +uint PIHTTPServer::PathElement::priority() const { + switch (type) { + case Type::Fixed: return 0x10000; break; + case Type::Arguments: return 0x1000; break; + case Type::AnyPart: return 0x100; break; + case Type::AnyOne: return 0x10; break; + case Type::AnyMany: return 0x1; break; + default: break; + } + return 0; +} + + +bool PIHTTPServer::Endpoint::create(const PIString & p) { + path = splitPath(p); + prepared_path.clear(); + priority = 0; + for (const auto & i: path) { + PathElement pe(i); + prepared_path << pe; + path_types |= pe.type; + priority += pe.priority(); + } + return !path_types[PathElement::Type::Invalid]; +} + + +bool PIHTTPServer::Endpoint::match(const PIStringList & in_path, PIMap & ext_args) const { + if (path_types[PathElement::Type::AnyMany]) { + int any_ind = path.indexOf("**"_a); + for (int i = 0; i < any_ind; ++i) { + if (!prepared_path[i].match(in_path[i], ext_args)) return false; + } + int si = prepared_path.size_s() - 1, ii = in_path.size_s() - 1; + for (; si > any_ind && ii >= 0; --si, --ii) { + if (!prepared_path[si].match(in_path[ii], ext_args)) return false; + } + } else { + if (in_path.size() != prepared_path.size()) return false; + for (int i = 0; i < prepared_path.size_s(); ++i) { + if (!prepared_path[i].match(in_path[i], ext_args)) return false; + } } return true; } diff --git a/libs/main/http_common/pihttptypes.cpp b/libs/main/http_common/pihttptypes.cpp index 924732f7..d7c0d2e5 100644 --- a/libs/main/http_common/pihttptypes.cpp +++ b/libs/main/http_common/pihttptypes.cpp @@ -59,14 +59,26 @@ PIHTTP::MessageMutable & PIHTTP::MessageMutable::removeHeader(const PIString & h } -PIHTTP::MessageMutable & PIHTTP::MessageMutable::addArgument(const PIString & arg, const PIString & value) { - m_arguments[arg] = value; +PIHTTP::MessageMutable & PIHTTP::MessageMutable::addQueryArgument(const PIString & arg, const PIString & value) { + m_query_arguments[arg] = value; return *this; } -PIHTTP::MessageMutable & PIHTTP::MessageMutable::removeArgument(const PIString & arg) { - m_arguments.remove(arg); +PIHTTP::MessageMutable & PIHTTP::MessageMutable::removeQueryArgument(const PIString & arg) { + m_query_arguments.remove(arg); + return *this; +} + + +PIHTTP::MessageMutable & PIHTTP::MessageMutable::addPathArgument(const PIString & arg, const PIString & value) { + m_path_arguments[arg] = value; + return *this; +} + + +PIHTTP::MessageMutable & PIHTTP::MessageMutable::removePathArgument(const PIString & arg) { + m_path_arguments.remove(arg); return *this; } diff --git a/libs/main/http_common/pihttptypes.h b/libs/main/http_common/pihttptypes.h index 96fc30a2..734cfd59 100644 --- a/libs/main/http_common/pihttptypes.h +++ b/libs/main/http_common/pihttptypes.h @@ -61,8 +61,16 @@ public: //! ~russian Возвращает все заголовки сообщения const PIMap & headers() const { return m_headers; } - //! ~english Gets all message arguments - //! ~russian Возвращает все аргументы сообщения + //! ~english Gets URL query arguments + //! ~russian Возвращает URL query аргументы + const PIMap & queryArguments() const { return m_query_arguments; } + + //! ~english Gets URL path arguments + //! ~russian Возвращает URL path аргументы + const PIMap & pathArguments() const { return m_path_arguments; } + + //! ~english Gets all message arguments (query + path) + //! ~russian Возвращает все аргументы сообщения (query + path) const PIMap & arguments() const { return m_arguments; } protected: @@ -71,7 +79,7 @@ protected: PIString m_path; PIByteArray m_body; PIMap m_headers; - PIMap m_arguments; + PIMap m_query_arguments, m_path_arguments, m_arguments; }; @@ -96,7 +104,11 @@ public: MessageMutable & setBody(PIByteArray b); const PIMap & headers() const { return m_headers; } + PIMap & arguments() { return m_arguments; } const PIMap & arguments() const { return m_arguments; } + const PIMap & queryArguments() const { return m_query_arguments; } + const PIMap & pathArguments() const { return m_path_arguments; } + PIMap & headers() { return m_headers; } //! ~english Adds a header to the message @@ -107,15 +119,29 @@ public: //! ~russian Удаляет заголовок из сообщения MessageMutable & removeHeader(const PIString & header); - PIMap & arguments() { return m_arguments; } + //! ~english Gets reference to URL query arguments + //! ~russian Возвращает ссылку на URL query аргументы + PIMap & queryArguments() { return m_query_arguments; } - //! ~english Adds an argument to the message - //! ~russian Добавляет аргумент к сообщению - MessageMutable & addArgument(const PIString & arg, const PIString & value); + //! ~english Adds an URL query argument to the message + //! ~russian Добавляет URL query аргумент к сообщению + MessageMutable & addQueryArgument(const PIString & arg, const PIString & value); - //! ~english Removes an argument from the message - //! ~russian Удаляет аргумент из сообщения - MessageMutable & removeArgument(const PIString & arg); + //! ~english Removes an URL query argument from the message + //! ~russian Удаляет URL query аргумент из сообщения + MessageMutable & removeQueryArgument(const PIString & arg); + + //! ~english Gets reference to URL path arguments + //! ~russian Возвращает ссылку на URL path аргументы + PIMap & pathArguments() { return m_path_arguments; } + + //! ~english Adds an URL path argument to the message + //! ~russian Добавляет URL path аргумент к сообщению + MessageMutable & addPathArgument(const PIString & arg, const PIString & value); + + //! ~english Removes an URL path argument from the message + //! ~russian Удаляет URL query path из сообщения + MessageMutable & removePathArgument(const PIString & arg); //! ~english Creates message from HTTP status code //! ~russian Создает сообщение из HTTP-статус кода diff --git a/libs/main/http_server/pihttpserver.h b/libs/main/http_server/pihttpserver.h index 166507ae..fadad0db 100644 --- a/libs/main/http_server/pihttpserver.h +++ b/libs/main/http_server/pihttpserver.h @@ -17,23 +17,23 @@ public: //! ~english Registers handler for specific path and HTTP method //! ~russian Регистрирует обработчик для указанного пути и HTTP метода - void registerPath(const PIString & path, PIHTTP::Method method, RequestFunction functor); + bool registerPath(const PIString & path, PIHTTP::Method method, RequestFunction functor); //! ~english Registers handler for specific path and HTTP method //! ~russian Регистрирует обработчик для указанного пути и HTTP метода template - void + bool registerPath(const PIString & path, PIHTTP::Method method, T * o, PIHTTP::MessageMutable (T::*function)(const PIHTTP::MessageConst &)) { - registerPath(path, method, [o, function](const PIHTTP::MessageConst & m) { return (o->*function)(m); }); + return registerPath(path, method, [o, function](const PIHTTP::MessageConst & m) { return (o->*function)(m); }); } - //! ~english Registers handler for unhandled requests - //! ~russian Регистрирует обработчик для необработанных запросов + //! ~english Registers handler for unregistered pathes + //! ~russian Регистрирует обработчик для незарегистрированных путей void registerUnhandled(RequestFunction functor); - //! ~english Registers handler for unhandled requests - //! ~russian Регистрирует обработчик для необработанных запросов + //! ~english Registers handler for unregistered pathes + //! ~russian Регистрирует обработчик для незарегистрированных путей template void registerUnhandled(T * o, PIHTTP::MessageMutable (T::*function)(const PIHTTP::MessageConst &)) { registerUnhandled([o, function](const PIHTTP::MessageConst & m) { return (o->*function)(m); }); @@ -61,14 +61,43 @@ public: 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 arguments; + + PathElement(const PIString & reg = {}); + + bool match(const PIString & in, PIMap & ext_args) const; + uint priority() const; + }; + struct Endpoint { - bool match(const PIStringList & in_path) const; PIStringList path; PIHTTP::Method method = PIHTTP::Method::Unknown; RequestFunction function; + PIFlags path_types; + PIVector prepared_path; + uint priority = 0; + + bool create(const PIString & p); + bool match(const PIStringList & in_path, PIMap & ext_args) const; }; + + static PIStringList splitPath(const PIString & path); + PIMap reply_headers; - PIMap functions; + PIMap> endpoints; RequestFunction unhandled; }; diff --git a/libs/main/types/piflags.h b/libs/main/types/piflags.h index 64fe7799..6b166543 100644 --- a/libs/main/types/piflags.h +++ b/libs/main/types/piflags.h @@ -60,7 +60,7 @@ public: //! \~english Constructor with flags = Enum "e" //! \~russian Создает флаги со значением = Enum "e" - PIFlags(Enum e): flags(e) { ; } + PIFlags(Enum e): flags((int)e) { ; } //! \~english Constructor with flags = int "i" //! \~russian Создает флаги со значением = int "i" @@ -80,9 +80,9 @@ public: //! \~russian Устанавливает флаг "e" в "on" PIFlags & setFlag(const Enum & e, bool on = true) { if (on) - flags |= e; + flags |= (int)e; else - flags &= ~e; + flags &= ~(int)e; return *this; } @@ -98,7 +98,7 @@ public: //! \~english Assign operator //! \~russian Оператор присваивания - void operator=(const Enum & e) { flags = e; } + void operator=(const Enum & e) { flags = (int)e; } //! \~english Assign operator //! \~russian Оператор присваивания @@ -110,7 +110,7 @@ public: //! \~english Compare operator //! \~russian Оператор сравнения - bool operator==(const Enum & e) { return flags == e; } + bool operator==(const Enum & e) { return flags == (int)e; } //! \~english Compare operator //! \~russian Оператор сравнения @@ -122,7 +122,7 @@ public: //! \~english Compare operator //! \~russian Оператор сравнения - bool operator!=(const Enum & e) { return flags != e; } + bool operator!=(const Enum & e) { return flags != (int)e; } //! \~english Compare operator //! \~russian Оператор сравнения @@ -134,7 +134,7 @@ public: //! \~english Compare operator //! \~russian Оператор сравнения - bool operator>(const Enum & e) { return flags > e; } + bool operator>(const Enum & e) { return flags > (int)e; } //! \~english Compare operator //! \~russian Оператор сравнения @@ -146,7 +146,7 @@ public: //! \~english Compare operator //! \~russian Оператор сравнения - bool operator<(const Enum & e) { return flags < e; } + bool operator<(const Enum & e) { return flags < (int)e; } //! \~english Compare operator //! \~russian Оператор сравнения @@ -158,7 +158,7 @@ public: //! \~english Compare operator //! \~russian Оператор сравнения - bool operator>=(const Enum & e) { return flags >= e; } + bool operator>=(const Enum & e) { return flags >= (int)e; } //! \~english Compare operator //! \~russian Оператор сравнения @@ -170,7 +170,7 @@ public: //! \~english Compare operator //! \~russian Оператор сравнения - bool operator<=(const Enum & e) { return flags <= e; } + bool operator<=(const Enum & e) { return flags <= (int)e; } //! \~english Compare operator //! \~russian Оператор сравнения @@ -182,7 +182,7 @@ public: //! \~english Bit-wise AND operator //! \~russian Оператор побитового И - void operator&=(const Enum & e) { flags &= e; } + void operator&=(const Enum & e) { flags &= (int)e; } //! \~english Bit-wise AND operator //! \~russian Оператор побитового И @@ -194,7 +194,7 @@ public: //! \~english Bit-wise OR operator //! \~russian Оператор побитового ИЛИ - void operator|=(const Enum & e) { flags |= e; } + void operator|=(const Enum & e) { flags |= (int)e; } //! \~english Bit-wise OR operator //! \~russian Оператор побитового ИЛИ @@ -206,7 +206,7 @@ public: //! \~english Bit-wise XOR operator //! \~russian Оператор побитового исключающего ИЛИ - void operator^=(const Enum & e) { flags ^= e; } + void operator^=(const Enum & e) { flags ^= (int)e; } //! \~english Bit-wise XOR operator //! \~russian Оператор побитового исключающего ИЛИ @@ -222,7 +222,7 @@ public: //! \~english Bit-wise AND operator //! \~russian Оператор побитового И PIFlags operator&(Enum e) const { - PIFlags tf(flags & e); + PIFlags tf(flags & (int)e); return tf; } @@ -243,7 +243,7 @@ public: //! \~english Bit-wise OR operator //! \~russian Оператор побитового ИЛИ PIFlags operator|(Enum e) const { - PIFlags tf(flags | e); + PIFlags tf(flags | (int)e); return tf; } @@ -264,7 +264,7 @@ public: //! \~english Bit-wise XOR operator //! \~russian Оператор побитового исключающего ИЛИ PIFlags operator^(Enum e) const { - PIFlags tf(flags ^ e); + PIFlags tf(flags ^ (int)e); return tf; } @@ -277,7 +277,7 @@ public: //! \~english Test flag operator //! \~russian Оператор проверки флага - bool operator[](Enum e) const { return (flags & e) == e; } + bool operator[](Enum e) const { return (flags & (int)e) == (int)e; } //! \~english Implicity conversion to \c int //! \~russian Оператор неявного преобразования в \c int diff --git a/main.cpp b/main.cpp index dd358052..2ef6ef8b 100644 --- a/main.cpp +++ b/main.cpp @@ -80,12 +80,69 @@ void piDeserializeJSON(S & v, const PIJSON & js) { piDeserializeJSON(v.re, js["re"]); } +PIKbdListener kbd; + int main(int argc, char * argv[]) { + PIHTTPServer server; + server.listen({"127.0.0.1:7777"}); + // server.setBasicAuthRealm("pip"); + // server.setBasicAuthEnabled(true); + // server.setBasicAuthCallback([](const PIString & u, const PIString & p) -> bool { + // piCout << "basic auth" << u << p; + // return (u == "u" && p == "p"); + auto reg = [&server](const PIString & path) { + server.registerPath(path, Method::Get, [path](const PIHTTP::MessageConst & msg) -> PIHTTP::MessageMutable { + piCout << "\nserver rec:\n\tpath: %1\n\t url: %2\n\t args: %3\n\tQ args: %4\n\tP args: %5"_a.arg(path) + .arg(msg.path()) + .arg(piStringify(msg.arguments())) + .arg(piStringify(msg.queryArguments())) + .arg(piStringify(msg.pathArguments())); + return MessageMutable().setCode(Code::Accepted); + }); + }; + // }); + + reg("/*/3/get"); + reg("/*/{ID}/get"); + reg("/api/{ID}/get"); + reg("/api/1/get"); + server.unregisterPath("*/{ID}/get"); + // reg("/api/1/bort{bortID}/get"); + // reg("/api/**"); + // reg("/api/1/bort2/get"); + // reg("/api/**/bort2/get"); + + /*server.registerPath("api/{ID}/bort{bortID}/get", Method::Get, [](const PIHTTP::MessageConst & msg) -> PIHTTP::MessageMutable { + piCout << "server rec:\n\tpath: %1\n\targs: %2\n\tQ args: %3\n\tP args: %4\n"_a.arg(msg.path()) + .arg(piStringify(msg.arguments())) + .arg(piStringify(msg.queryArguments())) + .arg(piStringify(msg.pathArguments())); + return MessageMutable().setCode(Code::Accepted); + }); + server.registerPath("sendMessage", Method::Post, [](const PIHTTP::MessageConst & msg) -> PIHTTP::MessageMutable { + return MessageMutable().setCode(Code::Accepted); + }); + server.registerUnhandled([](const PIHTTP::MessageConst & msg) -> PIHTTP::MessageMutable { + PIHTTP::MessageMutable ret; + piCout << "server rec:\n\tpath: %1\n\tmethod: %2\n\targs: %3\n\theaders: %4\n\tbody: %5\n"_a.arg(msg.path()) + .arg(PIHTTP::methodName(msg.method())) + .arg(piStringify(msg.arguments())) + .arg(PIStringList(msg.headers().map([](PIString k, PIString v) { return k + " = " + v; })).join("\n\t\t ")) + .arg(PIString::fromUTF8(msg.body())); + ret.setCode(PIHTTP::Code::BadRequest); + ret.setBody(PIByteArray::fromAscii("hello client! 0123456789")); + return ret; + });*/ + kbd.enableExitCapture('Q'); + WAIT_FOR_EXIT; + return 0; + // PIRegularExpression pire("привет"_u8, PIRegularExpression::CaseInsensitive); // PIString subj = "the dog ПриВет sat on the cat"_u8; // PIRegularExpression pire("^(?\\d\\d)/(?\\d\\d)/(?\\d\\d\\d\\d)$"_u8); // PIString subj = "08/12/1985"_u8; + PIString pat = "*.Exe"; PIRegularExpression re_g = PIRegularExpression::fromGlob(pat, PIRegularExpression::CaseInsensitive); PIRegularExpression re_p = PIRegularExpression::fromPOSIX(pat, PIRegularExpression::CaseInsensitive); @@ -231,32 +288,6 @@ int main(int argc, char * argv[]) { // piCout << "512:" << sha5xx(src, initial_512, 64).toHex(); return 0;*/ - /*PIHTTPServer server; - server.listen({"127.0.0.1:7777"}); - // server.setBasicAuthRealm("pip"); - // server.setBasicAuthEnabled(true); - // server.setBasicAuthCallback([](const PIString & u, const PIString & p) -> bool { - // piCout << "basic auth" << u << p; - // return (u == "u" && p == "p"); - // }); - server.registerPath("sendMessage", Method::Post, [](const PIHTTP::MessageConst & msg) -> PIHTTP::MessageMutable { - return MessageMutable().setCode(Code::Accepted); - }); - server.registerUnhandled([](const PIHTTP::MessageConst & msg) -> PIHTTP::MessageMutable { - PIHTTP::MessageMutable ret; - piCout << "server rec:\n\tpath: %1\n\tmethod: %2\n\targs: %3\n\theaders: %4\n\tbody: %5\n"_a.arg(msg.path()) - .arg(PIHTTP::methodName(msg.method())) - .arg(piStringify(msg.arguments())) - .arg(PIStringList(msg.headers().map([](PIString k, PIString v) { return k + " = " + v; })).join("\n\t\t ")) - .arg(PIString::fromUTF8(msg.body())); - ret.setCode(PIHTTP::Code::BadRequest); - ret.setBody(PIByteArray::fromAscii("hello client! 0123456789")); - piSleep(5.); - return ret; - }); - kbd.waitForFinish(); - return 0;*/ - /*PIHTTP::MessageMutable req; req.setBody(PIByteArray::fromAscii("hello server!")).addArgument("a0", "val.0").addArgument("a~r1", "знач,1"_u8); auto * c = PIHTTPClient::create("http://u:p@127.0.0.1:7777/api", PIHTTP::Method::Get, req);