You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I saw that a generic HTTP routing helper library for the http_s struct was on your wishlist. I've been developing a collection of higher-level abstractions for Facil.io called Sencillo, which adds (among other things) a route handler to Facil.io.
Sencillo's route handler does quite a bit that is far outside the scope of Facil.io (https://github.com/epixoip/sencillo/blob/main/sencillo.h#L1030-L1166), therefore a modified implementation that is more inline with Facil.io's goals is provided below for your consideration:
bool http_path_matches(http_s *request, char *__route) {
// make a mutable copy of the route
char *route = strdup(__route);
if (!route) {
FIO_LOG_ERROR("Failed to allocate memory!");
return false;
}
char *path = fiobj_obj2cstr(request->path).data;
// truncate the path at the query string delimiter,
// as we only care about the path itself and the
// query string is parsed by http_parse_query()
path = strtok(path, "?");
// does the route contain any inline path variables?
if (strchr(route, ':') == null) {
// no - perform direct string comparison
if (strcmp(route, path) == 0) {
free(route);
return true;
} else {
free(route);
return false;
}
}
int route_part_cnt = 0;
int path_part_cnt = 0;
// count the number of parts in the route and the path
for (int i = 0; route[i]; route[i] == '/' ? route_part_cnt++, i++ : i++);
for (int i = 0; path[i]; path[i] == '/' ? path_part_cnt++, i++ : i++);
// do we have an equal number of parts?
if (route_part_cnt != path_part_cnt) {
return false;
}
char *route_parts[route_part_cnt];
char *path_parts[path_part_cnt];
char *route_remaining;
char *path_remaining;
int matches = 0;
// loop through each part
char *route_next_part = strtok_r(route, "/", &route_remaining);
char *path_next_part = strtok_r(path, "/", &path_remaining);
while (route_next_part && path_next_part) {
// if the route part is an inline variable, extract the variable name and its value
if (route_next_part[0] == ':') {
route_parts[matches] = route_next_part + 1;
path_parts[matches++] = path_next_part;
} else {
// the route part is literal, does it match the path part?
if (strcmp(route_next_part, path_next_part)) {
free(route);
return false;
}
}
route_next_part = strtok_r(null, "/", &route_remaining);
path_next_part = strtok_r(null, "/", &path_remaining);
}
free(route);
// add the inline path variable names and values to the request params
for (int i = 0; i < matches; i++) {
http_add2hash(request->params, route_parts[i], strlen(route_parts[i]), path_parts[i], strlen(path_parts[i]), 1);
}
return true;
}
There are a couple ways you could implement http_path_matches depending on the desired experience.
First, you could create macros for simple conditionals:
I saw that a generic HTTP routing helper library for the http_s struct was on your wishlist. I've been developing a collection of higher-level abstractions for Facil.io called Sencillo, which adds (among other things) a route handler to Facil.io.
Sencillo's route handler does quite a bit that is far outside the scope of Facil.io (https://github.com/epixoip/sencillo/blob/main/sencillo.h#L1030-L1166), therefore a modified implementation that is more inline with Facil.io's goals is provided below for your consideration:
There are a couple ways you could implement
http_path_matches
depending on the desired experience.First, you could create macros for simple conditionals:
Use of these macros would be straightforward:
Another way would be to create macros that map each route to a function:
Which could simply be incorporated as:
The text was updated successfully, but these errors were encountered: