add files
This commit is contained in:
@@ -0,0 +1,125 @@
|
||||
#include "piliterals_string.h"
|
||||
#include "piserverendpoint_p.h"
|
||||
|
||||
|
||||
PIStringList PIHTTP::ServerEndpoint::splitPath(const PIString & path) {
|
||||
auto ret = path.split("/");
|
||||
ret.removeAll({});
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
PIHTTP::ServerEndpoint::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 << "[PIHTTP::ServerEndpoint] 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 PIHTTP::ServerEndpoint::PathElement::match(const PIString & in, PIMap<PIString, PIString> & 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 PIHTTP::ServerEndpoint::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 PIHTTP::ServerEndpoint::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 PIHTTP::ServerEndpoint::match(const PIStringList & in_path, PIMap<PIString, PIString> & 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;
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
//! \~\file piserverendpoint_p.h
|
||||
//! \~\ingroup HTTP
|
||||
//! \~\brief
|
||||
//! \~english Shared HTTP message container types
|
||||
//! \~russian Общие типы контейнеров HTTP-сообщений
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Shared HTTP message container types
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef piserverendpoint_p_h
|
||||
#define piserverendpoint_p_h
|
||||
|
||||
#include "pip_export.h"
|
||||
#include "pistringlist.h"
|
||||
|
||||
|
||||
namespace PIHTTP {
|
||||
|
||||
|
||||
struct PIP_EXPORT ServerEndpoint {
|
||||
struct PIP_EXPORT 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;
|
||||
};
|
||||
|
||||
PIStringList path;
|
||||
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);
|
||||
};
|
||||
|
||||
|
||||
}; // namespace PIHTTP
|
||||
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user