C and C++ web framework. http://rapida.vilor.one/docs
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

76 lines
1.9 KiB

/* SPDX-License-Identifier: GPL-3.0-or-later */
/* Copyright 2022 Ivan Polyakov */
#include "app.h"
#include <stdlib.h>
#include <string.h>
/*!
* \brief Selects a route handler based on requested path.
* \param app Application instance.
* \param req Request.
* \return Pointer to route handler.
*/
static rpd_route *routes_fabric(rpd_app *app, rpd_req *req);
int rpd_app_create(rpd_app *app)
{
app->running = app->routes_len = 0;
app->routes = NULL;
return 0;
}
int rpd_app_add_route(rpd_app *app, const char *path, rpd_route_cb cb,
void *userdata)
{
rpd_route route;
if (rpd_route_init(&route, path, cb, userdata))
return 1;
app->routes = (rpd_route *) realloc(app->routes, sizeof(rpd_route) * (app->routes_len + 1));
if (!app->routes)
return 2;
app->routes[app->routes_len++] = route;
return 0;
}
void rpd_app_handle_request(rpd_app *app, rpd_req *req, rpd_res *res)
{
rpd_route *route = routes_fabric(app, req);
if (!route) {
res->status = rpd_res_st_not_found;
return;
}
route->cb(req, res, route->userdata);
}
static rpd_route *routes_fabric(rpd_app *app, rpd_req *req)
{
const rpd_url *req_path, *route_path = 0;
req_path = &req->path;
for (int i = 0; i < app->routes_len; i++) {
route_path = &app->routes[i].path;
if (req_path->parts_len != route_path->parts_len)
continue;
int match = 1;
for (int j = 0; j < route_path->parts_len && match; j++) {
int cur_part_is_dyn = route_path->parts[i][0] == ':';
if (!cur_part_is_dyn && strcmp(req_path->parts[i], route_path->parts[i])) {
match = 0;
}
}
if (!match)
continue;
rpd_keyval_init(&req->params, 0);
rpd_url_params_parse_keys(&req->params, route_path);
rpd_url_params_parse_vals(&req->params, req_path, route_path);
return &app->routes[i];
}
return NULL;
}