Advertisement
aircampro

crow mustache bbs webserver example

Dec 16th, 2023 (edited)
873
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.00 KB | Software | 0 0
  1. //   example webserver in C++ using crow and mustache bbs message board and other methods are shown
  2. //
  3. //    config.json
  4. //    ========================
  5. //    "db_host": "localhost",
  6. //    "db_user": "mysqluser",
  7. //    "db_pass": "mysqlpass",
  8. //    "db_name": "bbs"
  9.  
  10. //    html mustache = bbs.html
  11. //    ========================
  12. //<!DOCTYPE html>
  13. //<html lang="en">
  14. //  <head>
  15. //    <meta charset="UTF-8">
  16. //    <title>This is the ACP BBS</title>
  17. //      <style type="text/css" media="screen, handheld, print, tv" >
  18. //      <!--
  19. //      .b3-2 h2, .b3-2 h3, .b3-2 p { border: solid; border-width: 2px 4px 4px 2px;
  20. //      padding: 5px; margin: 0px 0px 4px; }
  21. //      .b3-2 h2 { border-color: blue; border-style: dashed; }
  22. //      .b3-2 h3 { border-top-color: lightgreen; border-right-color: plum;
  23. //      border-bottom-color: plum; border-left-color: lightgreen; border-style: double; border-top-style: solid; border-width: thick }
  24. //      .b3-2 p { border-color: mediumpurple transparent;  }
  25. //      -->
  26. //      </style>
  27. //  </head>
  28. //  <body>
  29. //    <div class=b3-2>
  30. //    <h3>ACP Builitin Board</h3>
  31. //    <ul>
  32. //      {{# posts}}
  33. //      <li>{{id}}: {{text}}</li>
  34. //      {{/ posts}}
  35. //    </ul>
  36. //    <p>Type you're message here</p>
  37. //    <form action="/post" method="post">
  38. //      <input type="text" name="text"><input type="submit">
  39. //    </form>
  40. //  </div>
  41. //  </body>
  42. //</html>
  43. #include <iostream>
  44. #include <string>
  45.    
  46. #include <memory>
  47. #include <mysql_connection.h>
  48. #include <mysql_driver.h>
  49. #include <cppconn/prepared_statement.h>
  50. #include <cppconn/resultset.h>
  51. #include "crow_all.h"
  52. #include "crow.h"
  53. #include "cpplinq.hpp"
  54.  
  55. #include <boost/algorithm/string.hpp>
  56. #include <boost/lexical_cast.hpp>
  57. #include <boost/optional.hpp>
  58. #include <boost/optional/optional_io.hpp>
  59.  
  60. #include <chrono>
  61. #include "fmt/format.h"
  62. #include <fmt/chrono.h>
  63. #include <fmt/time.h>
  64.  
  65. struct date {
  66.     int y, m, d;
  67.  
  68.     date(int y, int m, int d)
  69.         : y(y), m(m), d(d)
  70.     {}
  71.  
  72.     std::ostream &operator<<(std::ostream &o, date const&rhs)
  73.     {
  74.         return o << rhs.y << '/' << rhs.m << '/' << rhs.d;
  75.     }
  76. };
  77.  
  78. int
  79. main() {
  80.   std::ifstream conf("config.json");
  81.   if (!conf) {
  82.     std::cerr << "config.json not found" << std::endl;
  83.     return 1;
  84.   }
  85.   std::string json = {
  86.     std::istreambuf_iterator<char>(conf),
  87.     std::istreambuf_iterator<char>()};
  88.   crow::json::rvalue config = crow::json::load(json);
  89.  
  90.   auto driver = sql::mysql::get_mysql_driver_instance();
  91.   auto raw_con = driver->connect(
  92.     (std::string) config["db_host"].s(),
  93.     (std::string) config["db_user"].s(),
  94.     (std::string) config["db_pass"].s());
  95.   auto con = std::unique_ptr<sql::Connection>(raw_con);
  96.   con->setSchema((std::string) config["db_name"].s());
  97.  
  98.   crow::SimpleApp app;
  99.   crow::mustache::set_base(".");
  100.  
  101.   // if you want to create it when you start this program uncomment this
  102.   //
  103.   // auto st = " CREATE TABLE bbs (
  104.   //            id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
  105.   //            text VARCHAR(100),
  106.   //            created TIMESTAMP DEFAULT NOW()
  107.   //            ) ENGINE=InnoDB DEFAULT CHARSET=utf8;";
  108.   // auto stmt = std::unique_ptr<sql::PreparedStatement>(
  109.   //    con->prepareStatement(st));
  110.   // stmt->executeUpdate();          
  111.  
  112.   CROW_ROUTE(app, "/")
  113.   ([&]{
  114.     auto stmt = std::unique_ptr<sql::PreparedStatement>(
  115.       con->prepareStatement("select * from bbs order by created"));
  116.     auto res = std::unique_ptr<sql::ResultSet>(
  117.       stmt->executeQuery());
  118.     int n = 0;
  119.     crow::mustache::context ctx;
  120.     while (res->next()) {
  121.       ctx["posts"][n]["id"] = res->getInt("id");
  122.       ctx["posts"][n]["text"] = res->getString("text");
  123.       n++;
  124.     }
  125.     return crow::mustache::load("bbs.html").render(ctx);
  126.   });
  127.  
  128.   CROW_ROUTE(app, "/post")
  129.       .methods("POST"_method)
  130.   ([&](const crow::request& req, crow::response& res){
  131.     crow::query_string params(req.body);
  132.     auto stmt = std::unique_ptr<sql::PreparedStatement>(
  133.       con->prepareStatement("insert into bbs(text) values(?)"));
  134.     stmt->setString(1, params.get("text"));
  135.     stmt->executeUpdate();
  136.     res = crow::response(302);
  137.     res.set_header("Location", "/");
  138.     res.end();
  139.   });
  140.  
  141.   // simple json response get the config credentials
  142.   CROW_ROUTE(app, "/json_data")
  143.   ([&]{
  144.         crow::json::wvalue x;
  145.         x["db_pass"] = (std::string) config["db_pass"].s();
  146.         x["db_host"] = (std::string) config["db_host"].s();
  147.         x["db_name"] = (std::string) config["db_name"].s();
  148.         x["db_user"] = (std::string) config["db_user"].s();
  149.         return x;
  150.   });
  151.  
  152.   CROW_ROUTE(app, "/sumfun/<int>")
  153.   ([&] (int count){
  154.        using namespace cpplinq;
  155.        int ints[] = {3,1,4,1,5,10,12,9,2,6,5,4,12,66,99,20,21,65,67,76,34,75,18};
  156.  
  157.        // Computes the sum of all chosen numbers in the sequence above
  158.        auto x =
  159.             from_array(ints)
  160.         >>  where ([](int i) {return i % count == 0;})     // Keep only numbers with the modulus of the arguemnt passed
  161.         >>  sum ()                                         // Sum those numbers
  162.         ;
  163.         std::ostringstream os;
  164.         os << x << "You selected from our memory array! : ";
  165.         return crow::response(os.str());
  166.   });
  167.  
  168.   CROW_ROUTE(app, "/params")
  169.   ([&](const crow::request& req){
  170.           std::ostringstream os;
  171.           os << "Params: " << req.url_params << "\n\n";
  172.           os << "The key 'my_key' was " << (req.url_params.get("my_key") == nullptr ? "not " : "") << "found.\n";
  173.           if(req.url_params.get("get_this_double") != nullptr) {
  174.               double countD = boost::lexical_cast<double>(req.url_params.get("get_this_double"));
  175.               os << "The value of 'get_this_value' is " <<  countD << '\n';
  176.           }
  177.           auto count = req.url_params.get_list("value_list");
  178.           os << "The key 'count' contains " << count.size() << " value(s).\n";
  179.           for(const auto& countVal : count) {
  180.               os << " - " << countVal << '\n';
  181.           }
  182.           return crow::response{os.str()};
  183.    });
  184.  
  185.    //      * curl {ip}:40081/mul/4/7
  186.    CROW_ROUTE(app, "/mul/<int>/<int>")
  187.    ([&](const crow::request& req, crow::response& res, int a, int b){
  188.         std::ostringstream os;
  189.         os << a*b;
  190.         res.write(os.str());
  191.         res.end();
  192.    });
  193.  
  194.    //      * curl -d '{"add1":13,"add2":7}' {ip}:40081/add_json  
  195.    CROW_ROUTE(app, "/add_json")
  196.         .methods(crow::HTTPMethod::POST)
  197.    ([&](const crow::request& req){
  198.         auto x = crow::json::load(req.body);
  199.         if (!x)
  200.             return crow::response(400);
  201.         auto sum = x["add1"].i()+x["add2"].i();
  202.         std::ostringstream os;
  203.         os << sum;
  204.         return crow::response{os.str()};
  205.    });
  206.  
  207.    CROW_ROUTE(app, "/getLatLong")
  208.         .methods("GET"_method)
  209.    ([&](const crow::request& req){
  210.         crow::json::wvalue x;
  211.         auto params = req.url_params;
  212.         auto param_longitude = atof(params.get("longitude"));
  213.         auto param_latitude = atof(params.get("latitude"));
  214.         x["lat"] = param_latitude;
  215.         x["lon"] = param_longitude;
  216.         return x;
  217.    });
  218.  
  219.    //      * curl {ip}:40081/mustache_page
  220.    CROW_ROUTE(app, "/mustashe_page")
  221.    ([&]{
  222.         auto page = crow::mustache::load("mustache.html");
  223.         return page.render();
  224.    });
  225.    
  226.    //      * curl -d '{"year":2023,"month":7,"day":12}' {ip}:40081/date_json  
  227.    CROW_ROUTE(app, "/date_json")
  228.         .methods(crow::HTTPMethod::POST)
  229.    ([&](const crow::request& req){
  230.         auto x = crow::json::load(req.body);
  231.         if (!x)
  232.             return crow::response(400);
  233.         auto yr = x["year"].i();
  234.         auto mon = x["month"].i();
  235.         auto dy = x["day"].i();
  236.         std::string fmt_date = fmt::format("Date sent is {}", date{dy, mon, yr});
  237.         return crow::response{fmt_date};
  238.    });
  239.  
  240.    //      * curl {ip}:40081/date_time_server  
  241.    CROW_ROUTE(app, "/date_time_server")
  242.    ([&]{
  243.         std::ostringstream os;
  244.         auto sc_now = std::chrono::system_clock::now();
  245.         auto tm_now = std::chrono::system_clock::to_time_t(sc_now);
  246.         fmt::print("{:%Y-%m-%d}\n", *std::localtime(&tm_now));
  247.         os << "date : " << fmt::format("{:%Y-%m-%d}\n", *std::localtime(&tm_now));
  248.         auto tm_now2  = std::time(nullptr);
  249.         fmt::print("{:%H:%I:%S}\n", *std::localtime(&tm_now2));
  250.         os << " time : " << fmt::format("{:%H:%I:%S}\n", *std::localtime(&tm_now2));
  251.         return crow::response{os.str()};
  252.    });
  253.  
  254.    //      * curl -d '{"pad":123,"by":6'} {ip}:40081/pad_json  
  255.    CROW_ROUTE(app, "/pad_json")
  256.         .methods(crow::HTTPMethod::POST)
  257.    ([&](const crow::request& req){
  258.         auto x = crow::json::load(req.body);
  259.         if (!x)
  260.             return crow::response(400);
  261.         auto tag = x["pad"].i();
  262.         auto by_int = x["by"].i();
  263.         fmt::print("{:0{}d}\n", tag, by_int);
  264.         std::string fmt_tag = fmt::format("{:0{}d}\n", tag, by_int);
  265.         return crow::response{fmt_tag};
  266.    });
  267.    
  268.   app.port(40081)
  269.     //.multithreaded()
  270.     .run();
  271. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement