aircampro

rest api webserver example

Jun 18th, 2021 (edited)
150
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.71 KB | None | 0 0
  1. // Rest Webserver :
  2. //
  3. // install dependancy library first
  4. // gunzip libmicrohttpd-0.9.68.tar.gz
  5. // tar -xvzf libmicrohttpd-0.9.68.tar
  6. // cd libmicrohttpd-0.9.68
  7. // mkdir build
  8. // cd build
  9. // ../configure
  10. // make
  11. // sudo make install
  12. //
  13. // unzip libhttpserver-master.zip
  14. // cd libhttpserver-master
  15. // ./bootstrap
  16. // mkdir build
  17. // cd build
  18. // ./../configure CXX='g++-7'
  19. // make
  20. // sudo make install
  21. //
  22. // export LD_LIBRARY_PATH=/usr/local/lib
  23. //
  24. // compiles with
  25. // g++-7 -std=c++17 webserver_rest.cpp -o webserver_rest -lhttpserver
  26. //
  27. // Ref Lecture :: OTUS.ru by Marat Seifullin
  28. //
  29. #include <httpserver.hpp>
  30. #include <iostream>
  31. #include <string>
  32. #include <regex>
  33. #include <mutex>
  34. #include <unordered_map>
  35.  
  36. // define the colors
  37. #define RED "\033[31m"
  38. #define GREEN "\033[32m"
  39. #define YELLOW "\033[33m"
  40. #define BLUE "\033[34m"
  41. #define WHITE "\033[37m"
  42.  
  43. //#define SINGLE_URL
  44.  
  45. using namespace std;
  46.  
  47. std::unordered_map<int, std::string> redirectUrls;
  48. std::mutex mtx;
  49. int g_counter = 0;
  50.  
  51. std::string savedUrl;
  52. regex pattern(".*http:.*");
  53. regex pattern2(".*https:.*");
  54.  
  55. class Save_resource: public httpserver::http_resource {
  56. public:
  57.     //const http_response render POST(const http_request& req)
  58.     const std::shared_ptr<httpserver::http_response> render_POST(const httpserver::http_request& req)
  59.     {
  60.         std::cout << GREEN << std::endl << "save resource::render " << std::endl;
  61.         std::string body = req.get_content();
  62.         std::string response_text;
  63.  
  64.         if ((regex_match(body, pattern)) or (regex_match(body, pattern2))) {
  65.             std::cout << YELLOW << "POST = " << BLUE << body << std::endl;
  66. #if defined(SINGLE_URL)
  67.             savedUrl = body;
  68.             response_text = " redirect " + savedUrl + "\n";
  69. #else
  70.             int currentNumber = ++g_counter;
  71.             mtx.lock();
  72.             redirectUrls[currentNumber] = body;
  73.             mtx.unlock();
  74.             response_text = " redirect " + body + "\n";
  75.             std::cout << YELLOW << "ID = " << BLUE << currentNumber << std::endl;
  76. #endif
  77.         } else {
  78.             std::cout << RED << "Error with url supplied " << std::endl;
  79.             response_text = " redirect fail wrong url format must start http: \n";
  80.         }
  81.  
  82.         httpserver::string_response* response = new httpserver::string_response(response_text, 200);
  83.         std::cout << RED << "save_resource::render " << std::endl;
  84.         return std::shared_ptr<httpserver::http_response>(response);
  85.     }
  86.    
  87. };
  88.  
  89. class Redirect_resource: public httpserver::http_resource {
  90. public:
  91.     //const http_response render GET(const httpserver::http_request& req) {
  92.     const std::shared_ptr<httpserver::http_response> render_GET(const httpserver::http_request& req) {
  93.         std::cout << GREEN << std::endl << "resource render " << std::endl;
  94. #if defined(SINGLE_URL)
  95.        httpserver::string_response* response = new httpserver::string_response("",302);
  96.        response->with_header("Location",savedUrl);
  97.        std::cout << RED << "redirect resource render " << savedUrl << std::endl;
  98. #else
  99.         std::string value = req.get_path_piece(1);
  100.         int inValid = 0;
  101.         std::string respUrl;
  102.         httpserver::string_response* response;
  103.  
  104.         std::cout << YELLOW << "value : " << BLUE << value << std::endl;
  105.         int id = 0;
  106.         try {
  107.             id = std::stoi(value);
  108.         }
  109.         catch (...) {
  110.             response = new httpserver::string_response("Invalid key : " + value,400);
  111.             std::cout << RED << "Invalid Key : " << BLUE << value << std::endl;    
  112.             inValid = 1;    
  113.         }
  114.  
  115.         if (inValid == 0) {
  116.            std::cout << YELLOW << "value : " << GREEN << value << std::endl;
  117.            mtx.lock();
  118.            auto search = redirectUrls.find(id);
  119.            if (search == redirectUrls.end()) {
  120.                 inValid = 2;          
  121.            }  
  122.            else
  123.            {
  124.                 respUrl = redirectUrls[id];                     /* url found then save to re-direct it */        
  125.            }
  126.            mtx.unlock();        
  127.         }
  128.  
  129.         if (inValid== 0) {                        /* set the sucess message outside the mutex */
  130.                response = new httpserver::string_response("",302);
  131.                response->with_header("Location",respUrl);
  132.                std::cout << GREEN << "Valid Key redirect : " << BLUE << value << " " << respUrl << std::endl;
  133.         }
  134.         else if (inValid== 2)                      /* set the not found message outside the mutex */
  135.         {
  136.                response = new httpserver::string_response("",302);
  137.                response->with_header("Location","/error");
  138.                std::cout << RED << "Invalid Key not found : " << BLUE << value << std::endl;
  139.         }      
  140. #endif
  141.  
  142.         return std::shared_ptr<httpserver::http_response>(response);
  143.     }
  144. };
  145.  
  146. class Error_resource: public httpserver::http_resource {
  147.  public:  
  148.     //const http_response render GET(const httpserver::http_request& req ) {
  149.     const std::shared_ptr<httpserver::http_response> render_GET(const httpserver::http_request& req ) {
  150.         std::cout << GREEN << std::endl << "Error Resource:: render" << std::endl;
  151.         httpserver::string_response* response = new httpserver::string_response("Requested resource not found",404);
  152.  
  153.         std::cout << RED << "error resource render" << std::endl;
  154.         return std::shared_ptr<httpserver::http_response>(response);
  155.     }
  156. };
  157.  
  158. int main(int argc, char** argv) {
  159.  
  160.     httpserver::webserver ws = httpserver::create_webserver(8080).
  161.     max_threads(8).
  162.     max_connections(200);
  163.  
  164.     bool successStatus = false;
  165.  
  166.     Save_resource sr;
  167.     successStatus = ws.register_resource("/save",&sr);
  168.     if (successStatus==false){
  169.         std::cout << WHITE << "saved url" << std::endl;
  170.         return 1;
  171.     }
  172.  
  173.     Redirect_resource rdr;
  174.     successStatus = ws.register_resource("/redirect",&rdr, true);
  175.     if (successStatus==false){
  176.         std::cout << WHITE << " redirect " << std::endl;
  177.         return 1;
  178.     }
  179.  
  180.     Error_resource err;
  181.     successStatus = ws.register_resource("/error",&err);
  182.     if (successStatus==false){
  183.         std::cout << WHITE << " error " << std::endl;
  184.         return 1;
  185.     }
  186.  
  187.     ws.start(true);
  188.     return(0);
  189. }
  190. //
  191. // =================== To test ======================================
  192. //
  193. // make shell script call it shell_to_do_url.sh
  194. // add this line
  195. // curl -d $1 -X POST http://localhost:8080/save
  196. // then
  197. // chmod +x shell_to_do_url.sh
  198. // ./shell_to_do_url.sh https://aircamuk.pro
  199. // where the argument is you're url you want to redirect to
  200. //
  201. // test from browser
  202. // 127.0.0.1:8080/redirect
  203. // 127.0.0.1:8080/redirect/<number you assigned>
Add Comment
Please, Sign In to add comment