/* SPDX-License-Identifier: GPL-3.0-or-later */ /* Copyright 2022 Ivan Polyakov */ #include "app.h" #include #include /*! * \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; }