SNode.C
Loading...
Searching...
No Matches
regex_utils.cpp
Go to the documentation of this file.
1/*
2 * SNode.C - a slim toolkit for network communication
3 * Copyright (C) Volker Christian <me@vchrist.at>
4 * 2020, 2021, 2022, 2023, 2024, 2025
5 *
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU Lesser General Public License as published
8 * by the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include "express/dispatcher/regex_utils.h"
21
22#include "express/Request.h"
23
24#ifndef DOXYGEN_SHOULD_SKIP_THIS
25
26#include <cstddef>
27#include <sstream>
28#include <utility>
29
30#endif /* DOXYGEN_SHOULD_SKIP_THIS */
31
32namespace express::dispatcher {
33
35 std::string s;
36
37 for (std::vector<std::string>::size_type i = 0; i < stringvec.size(); i++) {
38 if (!stringvec[i].empty() && stringvec[i].front() != ' ') {
39 s += "\\/" + stringvec[i];
40 }
41 }
42
43 return s;
44 }
45
46 std::vector<std::string> explode(const std::string& s, char delim) {
47 std::vector<std::string> result;
48 std::istringstream iss(s);
49
50 for (std::string token; std::getline(iss, token, delim);) {
51 result.push_back(std::move(token));
52 }
53
54 return result;
55 }
56
57#define PATH_REGEX ":[a-zA-Z0-9]+(\\‍(.+\\‍))?"
58 const std::regex& pathRegex() {
59 static const std::regex pathregex(PATH_REGEX);
60
61 return pathregex;
62 }
63
65 std::smatch smatch;
66
67 std::regex_search(cpath, smatch, pathRegex());
68
69 return smatch;
70 }
71
72 bool hasResult(const std::string& cpath) {
73 std::smatch smatch;
74
75 return std::regex_search(cpath, smatch, pathRegex());
76 }
77
78 bool matchFunction(const std::string& cpath, const std::string& reqpath) {
79 std::vector<std::string> explodedString = explode(cpath, '/');
80
81 for (std::vector<std::string>::size_type i = 0; i < explodedString.size(); i++) {
82 if (explodedString[i].front() == ':') {
83 const std::smatch smatch = matchResult(explodedString[i]);
84 std::string regex = "(.*)";
85
86 if (smatch.size() > 1) {
87 if (smatch[1] != "") {
88 regex = smatch[1];
89 }
90 }
91
92 explodedString[i] = regex;
93 }
94 }
95
96 const std::string regexPath = path_concat(explodedString);
97
98 return std::regex_match(reqpath, std::regex(regexPath));
99 }
100
101 void setParams(const std::string& cpath, Request& req) {
102 std::vector<std::string> explodedString = explode(cpath, '/');
103 std::vector<std::string> explodedReqString = explode(req.url, '/');
104
105 for (std::vector<std::string>::size_type i = 0; i < explodedString.size() && i < explodedReqString.size(); i++) {
106 if (explodedString[i].front() == ':') {
107 const std::smatch smatch = matchResult(explodedString[i]);
108 std::string regex = "(.*)";
109
110 if (smatch.size() > 1) {
111 if (smatch[1] != "") {
112 regex = smatch[1];
113 }
114 }
115
116 if (std::regex_match(explodedReqString[i], std::regex(regex))) {
117 std::string attributeName = smatch[0];
118 attributeName.erase(0, 1);
119 attributeName.erase((attributeName.length() - static_cast<std::size_t>(smatch[1].length())),
120 static_cast<std::size_t>(smatch[1].length()));
121
122 req.params[attributeName] = explodedReqString[i];
123 }
124 }
125 }
126 }
127
129 std::string result;
130
131 if (first.back() == '/' && second.front() == '/') {
132 result = first + second.substr(1);
133 } else if (first.back() != '/' && second.front() != '/') {
134 result = first + '/' + second;
135 } else {
136 result = first + second;
137 }
138
139 if (result.length() > 1 && result.back() == '/') {
140 result.pop_back();
141 }
142
143 return result;
144 }
145
146 bool checkForUrlMatch(const std::string& cpath, const std::string& reqpath) {
147 return hasResult(cpath) && matchFunction(cpath, reqpath);
148 }
149
150} // namespace express::dispatcher
bool checkForUrlMatch(const std::string &cpath, const std::string &reqpath)
void setParams(const std::string &cpath, express::Request &req)
std::smatch matchResult(const std::string &cpath)
bool hasResult(const std::string &cpath)
std::string path_concat(const std::vector< std::string > &stringvec)
bool matchFunction(const std::string &cpath, const std::string &reqpath)
std::string path_concat(const std::string &first, const std::string &second)
std::vector< std::string > explode(const std::string &s, char delim)
const std::regex & pathRegex()
#define PATH_REGEX