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
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 = 1; 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; |
|
}
|
|
|