Add Uri with support for regexUri and globUri (#3441)

* Add Uri with support for staticUri, regexUri and globUri

* Add newline to end of files

* Update example

* Suppress gcc warnings (unused params)
This commit is contained in:
Bob
2020-01-20 14:21:01 +01:00
committed by Me No Dev
parent c09ec5bd3d
commit cfe8526ec8
8 changed files with 182 additions and 54 deletions

View File

@ -0,0 +1,66 @@
#ifndef URI_BRACES_H
#define URI_BRACES_H
#include "Uri.h"
class UriBraces : public Uri {
public:
explicit UriBraces(const char *uri) : Uri(uri) {};
explicit UriBraces(const String &uri) : Uri(uri) {};
Uri* clone() const override final {
return new UriBraces(_uri);
};
void initPathArgs(std::vector<String> &pathArgs) override final {
int numParams = 0, start = 0;
do {
start = _uri.indexOf("{}", start);
if (start > 0) {
numParams++;
start += 2;
}
} while (start > 0);
pathArgs.resize(numParams);
}
bool canHandle(const String &requestUri, std::vector<String> &pathArgs) override final {
if (Uri::canHandle(requestUri, pathArgs))
return true;
size_t uriLength = _uri.length();
unsigned int pathArgIndex = 0;
unsigned int requestUriIndex = 0;
for (unsigned int i = 0; i < uriLength; i++, requestUriIndex++) {
char uriChar = _uri[i];
char requestUriChar = requestUri[requestUriIndex];
if (uriChar == requestUriChar)
continue;
if (uriChar != '{')
return false;
i += 2; // index of char after '}'
if (i >= uriLength) {
// there is no char after '}'
pathArgs[pathArgIndex] = requestUri.substring(requestUriIndex);
return pathArgs[pathArgIndex].indexOf("/") == -1; // path argument may not contain a '/'
}
else
{
char charEnd = _uri[i];
int uriIndex = requestUri.indexOf(charEnd, requestUriIndex);
if (uriIndex < 0)
return false;
pathArgs[pathArgIndex] = requestUri.substring(requestUriIndex, uriIndex);
requestUriIndex = (unsigned int) uriIndex;
}
pathArgIndex++;
}
return requestUriIndex >= requestUri.length();
}
};
#endif

View File

@ -0,0 +1,22 @@
#ifndef URI_GLOB_H
#define URI_GLOB_H
#include "Uri.h"
#include <fnmatch.h>
class UriGlob : public Uri {
public:
explicit UriGlob(const char *uri) : Uri(uri) {};
explicit UriGlob(const String &uri) : Uri(uri) {};
Uri* clone() const override final {
return new UriGlob(_uri);
};
bool canHandle(const String &requestUri, __attribute__((unused)) std::vector<String> &pathArgs) override final {
return fnmatch(_uri.c_str(), requestUri.c_str(), 0) == 0;
}
};
#endif

View File

@ -0,0 +1,44 @@
#ifndef URI_REGEX_H
#define URI_REGEX_H
#include "Uri.h"
#include <regex>
class UriRegex : public Uri {
public:
explicit UriRegex(const char *uri) : Uri(uri) {};
explicit UriRegex(const String &uri) : Uri(uri) {};
Uri* clone() const override final {
return new UriRegex(_uri);
};
void initPathArgs(std::vector<String> &pathArgs) override final {
std::regex rgx((_uri + "|").c_str());
std::smatch matches;
std::string s{""};
std::regex_search(s, matches, rgx);
pathArgs.resize(matches.size() - 1);
}
bool canHandle(const String &requestUri, std::vector<String> &pathArgs) override final {
if (Uri::canHandle(requestUri, pathArgs))
return true;
unsigned int pathArgIndex = 0;
std::regex rgx(_uri.c_str());
std::smatch matches;
std::string s(requestUri.c_str());
if (std::regex_search(s, matches, rgx)) {
for (size_t i = 1; i < matches.size(); ++i) { // skip first
pathArgs[pathArgIndex] = String(matches[i].str().c_str());
pathArgIndex++;
}
return true;
}
return false;
}
};
#endif