Advertisement
Viraax

Untitled

Mar 11th, 2021
846
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.33 KB | None | 0 0
  1. #include "Router.h"
  2. #include "WebServer.h"
  3. #include "../orm/Json.h"
  4.  
  5. using json = nlohmann::json;
  6.  
  7. void Router::parse(const std::string& directory)
  8. {
  9.     this->directory = directory;
  10.  
  11.     for (const auto& entry : fs::directory_iterator(directory))
  12.     {
  13.         if (fs::path(entry.path()).extension() == std::string_view(".json"))
  14.         {
  15.             std::fstream file(entry.path(), std::fstream::in);
  16.             std::string str {
  17.                 (std::istreambuf_iterator<char>(file)),
  18.                 std::istreambuf_iterator<char>()
  19.             };
  20.  
  21.             try {
  22.                 auto values = json::parse(str.c_str());
  23.  
  24.                 for (auto& value : values)
  25.                 {
  26.                     Route route;
  27.                     route.name = value["name"].get<std::string>();
  28.                     route.url = value["url"].get<std::string>();
  29.                     route.method = value["method"].get<std::string>();
  30.                     route.callback = value["callback"].get<std::string>();
  31.  
  32.                     if (value["middlewares"].is_array()) {
  33.                         route.middlewares = value["middlewares"].get<std::vector<std::string>>();
  34.                     }
  35.  
  36.                     routes.push_back(route);
  37.                 }
  38.             }
  39.             catch (std::exception& e) {
  40.                 std::cout << "Error while parsing routes file: " << entry.path() << std::endl;
  41.                 std::cout << e.what() << std::endl;
  42.             }
  43.         }
  44.     }
  45.  
  46. }
  47.  
  48. void Router::printRoutes()
  49. {
  50.     auto table = ORM::createDebugTable();
  51.  
  52.     table[0][0] = "Method";
  53.     table[0][1] = "Name";
  54.     table[0][2] = "URL";
  55.     table[0][3] = "Middlewares";
  56.     table[0][4] = "Controller";
  57.     table[0][5] = "Action";
  58.  
  59.     for (int i = 0; i < routes.size(); ++i)
  60.     {
  61.         table[i + 1][0] = routes[i].method;
  62.         table[i + 1][1] = routes[i].name;
  63.         table[i + 1][2] = routes[i].url;
  64.         table[i + 1][3] = Utils::join(routes[i].middlewares, ", ");
  65.  
  66.         auto parts = Utils::split(routes[i].callback, ".");
  67.         table[i + 1][4] = parts[0];
  68.         table[i + 1][5] = parts[1];
  69.     }
  70.  
  71.     std::cout << table;
  72. }
  73.  
  74. Response Router::dispatch(
  75.     Request& request,
  76.     WebServer* server
  77. )
  78. {
  79.     routes.erase(
  80.     std::remove_if(routes.begin(), routes.end(), [](const Route& route) {
  81.         return route.callback == "App.static_directory"
  82.             || route.callback == "App.static_file";
  83.     }),
  84.     routes.end());
  85.  
  86.     for (auto& mount_point : server->mount_points)
  87.     {
  88.         if (request.headers.url == mount_point.first) {
  89.             Route static_directory;
  90.             static_directory.name = mount_point.second;
  91.             static_directory.alias = mount_point.first;
  92.             static_directory.url = mount_point.first;
  93.             static_directory.method = "GET";
  94.             static_directory.callback = "App.static_directory";
  95.             routes.push_back(static_directory);
  96.         }
  97.         else if (request.headers.url.find(mount_point.first) != std::string::npos)
  98.         {
  99.             Route static_file;
  100.             auto filepath = request.headers.url.substr(mount_point.first.size() + 1, request.headers.url.size());
  101.             static_file.name = mount_point.second + '/' + filepath;
  102.             static_file.alias = mount_point.first + '/' + filepath;
  103.             static_file.url = "^" + mount_point.first + std::string("/([a-zA-Z0-9_\\-\\./\\ ]+)$");
  104.             static_file.method = "GET";
  105.             static_file.callback = "App.static_file";
  106.             routes.push_back(static_file);
  107.         }
  108.     }
  109.    
  110.     std::vector<std::string> urls;
  111.  
  112.     for (auto& route : routes)
  113.     {
  114.         std::smatch matches;
  115.         std::string str = route.url;
  116.         auto pattern = std::string("([a-zA-Z0-9_]+)");
  117.  
  118.         while (std::regex_search(str, matches, std::regex(":" + pattern))) {
  119.             for (auto it = matches.begin(); it != matches.end(); ++it) {
  120.                 if (it->str().at(0) != ':') {
  121.                     route.params[it->str()] = "";
  122.                     str = matches.suffix();
  123.                 }
  124.             }
  125.         }
  126.    
  127.         urls.push_back("^" + std::regex_replace(route.url, std::regex(":" + pattern), pattern) + "$");
  128.     }
  129.  
  130.     for (int i = 0; i < urls.size(); ++i)
  131.     {
  132.         std::smatch matches;
  133.  
  134.         if (std::regex_search(request.headers.url, matches, std::regex(urls[i])))
  135.         {
  136.             if (matches.size() > 0)
  137.             {
  138.                 if (request.headers.url == matches[0].str()
  139.                 && routes[i].method == request.headers.method)
  140.                 {
  141.                     routes[i].bindParams(matches);
  142.  
  143.                     auto target = Utils::split(routes[i].callback, ".");
  144.                     auto c = server->controllers.find(target[0]);
  145.  
  146.                     if (c != server->controllers.end())
  147.                     {
  148.                         auto method = c->second->methods.find(target[1]);
  149.  
  150.                         if (method != c->second->methods.end()) {
  151.                             request.params = routes[i].params;
  152.                             request.route = routes[i];
  153.  
  154.                             for (auto& name : routes[i].middlewares) {
  155.                                 auto middleware = server->middlewares.find(name);
  156.  
  157.                                 if (middleware != server->middlewares.end()) {
  158.                                     middleware->second->use(request);
  159.                                 }
  160.                             }
  161.  
  162.                             return c->second.get()->methods.at(method->first)(request);
  163.                         }
  164.                         else {
  165.                             ORM::logger.warn(
  166.                                 "Method %s on controller %s not found.",
  167.                                 target[1].c_str(),
  168.                                 target[0].c_str()
  169.                             );
  170.                         }
  171.                     }
  172.                     else {
  173.                         ORM::logger.warn(
  174.                             "Controller %s not found. %s",
  175.                             target[0].c_str(),
  176.                             routes[i].callback
  177.                         );
  178.                     }
  179.                 }
  180.             }
  181.         }
  182.     }
  183.  
  184.     std::fstream file("./views/Error.html");
  185.     std::string str((std::istreambuf_iterator<char>(file)),std::istreambuf_iterator<char>());
  186.  
  187.     std::regex error("\\$error");
  188.     std::regex name("\\$name");
  189.     std::regex version("\\$version");
  190.  
  191.     str = std::regex_replace(str, name, statusCodeToStr(StatusCode::NOT_FOUND));
  192.     str = std::regex_replace(str, error, std::to_string(int(StatusCode::NOT_FOUND)));
  193.     str = std::regex_replace(str, version, "OHMyServer 1.0");
  194.  
  195.     return Response(str, StatusCode::NOT_FOUND, "text/html");
  196. }
  197.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement