call_if_match implementation (untested)

FossilOrigin-Name: 1edbe4f7555dce7630f91ba8e8ad23739686550757a9a7707ac1aaab86d8ef40
This commit is contained in:
nekobit 2022-09-29 03:07:09 +00:00
parent f5ee768e46
commit 8289aa3db4
2 changed files with 51 additions and 2 deletions

View file

@ -16,6 +16,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include <algorithm>
#include "request.h"
using namespace HTTP;
@ -28,5 +29,50 @@ Request::Request(Type type, const std::string url, RequestCallback_t func)
bool Request::call_if_match(Type type, const std::string& string)
{
// Before doing anything, check if the type (POST, GET...) are the same
if (type != this->type) return false;
std::vector<std::string> args{};
// Current point of `string'
size_t curr = std::string::npos;
size_t n, n_last = std::string::npos;
bool match = true;
while((n = url.find(':', n)) != std::string::npos)
{
// Compare range from start to found point
if (!std::equal(url.begin() + n_last,
string.begin() + n_last,
string.begin() + (n-1)))
return false;
// Peek next character to know where to stop (often a '/')
size_t next_char_dist = url.find(n+1, n);
if (next_char_dist != std::string::npos)
{
// Push string
args.push_back(string.substr(n, next_char_dist));
// Seek n past next_char
n += next_char_dist;
}
else {
// Out of bounds, last argument
args.push_back(string.substr(n));
}
n_last = n;
}
// If previous loop couldn't find anything, check if strings aren't fully equal
if (n == std::string::npos &&
n_last == std::string::npos &&
url != string)
{
// ... if so, this doesn't match
return false;
}
callback(args);
return true;
}

View file

@ -29,11 +29,14 @@ namespace HTTP
* @brief A HTTP Request structure
*
* A very simple format is used for the URL to match paremeters.
* If a ':' character is in place, then it will read until the next '/' character
* If a ':' character is in place, then it will read until the next character (often '/')
* or until the next end of line.
*
* Example: /api/v1/user/:/haters
* /api/v1/user/:/dislike_user/:
*
* Example 2: /api/v1/user/:/dislike_user/:
*
* Example 3: /lets/get/:_fails/or/wins_:
*/
class Request
{