...
This commit is contained in:
parent
76d8fb6916
commit
bd0654a8af
@ -60,42 +60,200 @@ public:
|
|||||||
template <traits::adc_input_char_range R>
|
template <traits::adc_input_char_range R>
|
||||||
AdcEndpointParser(const R& ept)
|
AdcEndpointParser(const R& ept)
|
||||||
{
|
{
|
||||||
|
fromRange(ept);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
|
||||||
std::string _proto, _host, _path;
|
|
||||||
int port;
|
|
||||||
|
|
||||||
template <traits::adc_input_char_range R>
|
template <traits::adc_input_char_range R>
|
||||||
bool parse(const R& ept)
|
requires std::ranges::contiguous_range<R>
|
||||||
|
bool fromRange(const R& ept)
|
||||||
{
|
{
|
||||||
|
_isValid = false;
|
||||||
|
|
||||||
// at least 'ws://a' (proto, proto-host delimiter and at least a single character of hostname)
|
// at least 'ws://a' (proto, proto-host delimiter and at least a single character of hostname)
|
||||||
if (std::ranges::size(ept) < 6) {
|
if (std::ranges::size(ept) < 6) {
|
||||||
return false;
|
return _isValid;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto found = std::ranges::search(ept, protoHostDelim);
|
if constexpr (std::is_array_v<std::remove_cvref_t<R>>) {
|
||||||
|
_endpoint = ept;
|
||||||
|
} else {
|
||||||
|
std::ranges::copy(ept, _endpoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto found = std::ranges::search(_endpoint, protoHostDelim);
|
||||||
if (found.empty()) {
|
if (found.empty()) {
|
||||||
return false;
|
return _isValid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool ok = false;
|
|
||||||
|
|
||||||
std::string_view proto{ept.begin(), found.begin()};
|
_proto = std::string_view{_endpoint.begin(), found.begin()};
|
||||||
for (auto& valid_proto : validProtoMarks) {
|
for (auto& valid_proto : validProtoMarks) {
|
||||||
ok = proto == valid_proto;
|
_isValid = _proto == valid_proto;
|
||||||
if (ok) {
|
if (_isValid) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ok) {
|
if (!_isValid) {
|
||||||
return ok;
|
return _isValid;
|
||||||
}
|
}
|
||||||
|
|
||||||
_proto.clear();
|
_isValid = false;
|
||||||
std::ranges::copy(proto, std::back_inserter(_proto));
|
|
||||||
|
_host = std::string_view{found.end(), _endpoint.end()};
|
||||||
|
if (_proto == protoMarkLocal) { // local proto allows only hostname
|
||||||
|
_path = std::string_view();
|
||||||
|
_port = -1;
|
||||||
|
} else {
|
||||||
|
auto f1 = std::ranges::search(_host, hostPortDelim);
|
||||||
|
std::string_view port_sv;
|
||||||
|
if (f1.empty()) { // no port, but is must be!
|
||||||
|
return _isValid;
|
||||||
|
} else {
|
||||||
|
_host = std::string_view(_host.begin(), f1.begin());
|
||||||
|
// port_sv = std::string_view(f1.end(), _endpoint.end());
|
||||||
|
port_sv = std::string_view(f1.end(), &*_endpoint.end());
|
||||||
|
|
||||||
|
f1 = std::ranges::search(port_sv, portPathDelim);
|
||||||
|
if (f1.empty()) {
|
||||||
|
_path = std::string_view();
|
||||||
|
} else {
|
||||||
|
port_sv = std::string_view(port_sv.begin(), f1.begin());
|
||||||
|
|
||||||
|
_path = std::string_view(f1.end(), &*_endpoint.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
// convert port string to int
|
||||||
|
auto end_ptr = port_sv.data() + port_sv.size();
|
||||||
|
|
||||||
|
auto [ptr, ec] = std::from_chars(port_sv.data(), end_ptr, _port);
|
||||||
|
if (ec != std::errc() || ptr != end_ptr) {
|
||||||
|
return _isValid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_isValid = true;
|
||||||
|
|
||||||
|
return _isValid;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool isValid() const
|
||||||
|
{
|
||||||
|
return _isValid;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <traits::adc_view_or_output_char_range R>
|
||||||
|
R proto() const
|
||||||
|
{
|
||||||
|
return part<R>(PROTO_PART);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string_view proto() const
|
||||||
|
{
|
||||||
|
return proto<std::string_view>();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <traits::adc_view_or_output_char_range R>
|
||||||
|
R host() const
|
||||||
|
{
|
||||||
|
return part<R>(HOST_PART);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string_view host() const
|
||||||
|
{
|
||||||
|
return host<std::string_view>();
|
||||||
|
}
|
||||||
|
|
||||||
|
int port() const
|
||||||
|
{
|
||||||
|
return _port;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <traits::adc_view_or_output_char_range R>
|
||||||
|
R path() const
|
||||||
|
{
|
||||||
|
return part<R>(PATH_PART);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string_view path() const
|
||||||
|
{
|
||||||
|
return path<std::string_view>();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool isLocal() const
|
||||||
|
{
|
||||||
|
return proto() == protoMarkLocal;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isTCP() const
|
||||||
|
{
|
||||||
|
return proto() == protoMarkTCP;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isTLS() const
|
||||||
|
{
|
||||||
|
return proto() == protoMarkTLS;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isUDP() const
|
||||||
|
{
|
||||||
|
return proto() == protoMarkUDP;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isWS() const
|
||||||
|
{
|
||||||
|
return proto() == protoMarkWS;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isWSS() const
|
||||||
|
{
|
||||||
|
return proto() == protoMarkWSS;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::string _endpoint;
|
||||||
|
std::string_view _proto, _host, _path;
|
||||||
|
int _port;
|
||||||
|
bool _isValid;
|
||||||
|
|
||||||
|
enum EndpointPart { PROTO_PART, HOST_PART, PATH_PART };
|
||||||
|
|
||||||
|
template <traits::adc_view_or_output_char_range R>
|
||||||
|
R part(EndpointPart what) const
|
||||||
|
{
|
||||||
|
R res;
|
||||||
|
|
||||||
|
if (!_isValid) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto part = _proto;
|
||||||
|
|
||||||
|
switch (what) {
|
||||||
|
case PROTO_PART:
|
||||||
|
part = _proto;
|
||||||
|
break;
|
||||||
|
case HOST_PART:
|
||||||
|
part = _host;
|
||||||
|
break;
|
||||||
|
case PATH_PART:
|
||||||
|
part = _path;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if constexpr (std::ranges::view<R>) {
|
||||||
|
return {part.begin(), part.end()};
|
||||||
|
} else {
|
||||||
|
std::ranges::copy(part, res);
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -184,15 +184,17 @@ public:
|
|||||||
|
|
||||||
// start accepting remote connections, create and start given network session
|
// start accepting remote connections, create and start given network session
|
||||||
// It must be assumed that this is asynchronous operation!!!
|
// It must be assumed that this is asynchronous operation!!!
|
||||||
template <interfaces::adc_netsession_c SessionT, typename... AccCtorArgTs>
|
template <interfaces::adc_netsession_c SessionT, typename... AcceptorCtorArgTs>
|
||||||
void start(const typename SessionT::netsession_ident_t& id,
|
void start(const typename SessionT::netsession_ident_t& id,
|
||||||
const typename SessionT::netsession_ctx_t& sess_ctx,
|
const typename SessionT::netsession_ctx_t& sess_ctx,
|
||||||
AccCtorArgTs&&... ctor_args)
|
AcceptorCtorArgTs&&... ctor_args)
|
||||||
{
|
{
|
||||||
auto acceptor =
|
if (!_isListening<SessionT>[this]) {
|
||||||
std::make_shared<typename SessionT::netservice_t::acceptor_t>(std::forward<AccCtorArgTs>(ctor_args)...);
|
auto acceptor = std::make_shared<typename SessionT::netservice_t::acceptor_t>(
|
||||||
|
std::forward<AcceptorCtorArgTs>(ctor_args)...);
|
||||||
|
|
||||||
doAccept<SessionT>(acceptor, id, sess_ctx);
|
doAccept<SessionT>(acceptor, id, sess_ctx);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -218,7 +220,7 @@ protected:
|
|||||||
server_ident_t _serverIdent;
|
server_ident_t _serverIdent;
|
||||||
|
|
||||||
template <typename SessionT, typename AT, typename IDT, typename CTXT>
|
template <typename SessionT, typename AT, typename IDT, typename CTXT>
|
||||||
void doAccept(std::shared_ptr<AT> acceptor, const IDT& id, CTXT& sess_ctx)
|
void doAccept(std::shared_ptr<AT> acceptor, const IDT& id, const CTXT& sess_ctx)
|
||||||
{
|
{
|
||||||
acceptor.asyncAccept([acceptor, &id, &sess_ctx, this](auto ec, typename SessionT::netservice_t srv) mutable {
|
acceptor.asyncAccept([acceptor, &id, &sess_ctx, this](auto ec, typename SessionT::netservice_t srv) mutable {
|
||||||
if (!ec) {
|
if (!ec) {
|
||||||
|
|||||||
@ -83,6 +83,13 @@ TEST_CASE("[ADC NET MESSAGE]")
|
|||||||
|
|
||||||
std::cout << "EPT: [" << ept.endpoint() << "]\n";
|
std::cout << "EPT: [" << ept.endpoint() << "]\n";
|
||||||
|
|
||||||
|
AdcEndpointParser prs(ee);
|
||||||
|
std::cout << "PROTO: [" << prs.proto() << "]\n";
|
||||||
|
std::cout << "HOST: [" << prs.host() << "]\n";
|
||||||
|
std::cout << "PORT: [" << prs.port() << "]\n";
|
||||||
|
std::cout << "PATH: [" << prs.path() << "]\n";
|
||||||
|
std::cout << std::boolalpha << "IS TLS: " << prs.isTLS() << "\n";
|
||||||
|
std::cout << std::boolalpha << "IS UDP: " << prs.isUDP() << "\n";
|
||||||
|
|
||||||
std::cout << "\n\n";
|
std::cout << "\n\n";
|
||||||
std::string bs;
|
std::string bs;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user