DragonOsman

http_server.cpp

Jan 22nd, 2018
71
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.12 KB | None | 0 0
  1. #include "http_server.h"
  2. #include <boost/beast/core.hpp>
  3.  
  4. void fail(boost::system::error_code ec, const char *what)
  5. {
  6.     std::cerr << what << ": " << ec.message() << "\n";
  7. }
  8.  
  9. boost::beast::string_view mime_type(boost::beast::string_view path)
  10. {
  11.     using boost::beast::iequals;
  12.     const auto ext = [&path]
  13.     {
  14.         const auto pos = path.rfind(".");
  15.         if (pos == boost::beast::string_view::npos)
  16.         {
  17.             return boost::beast::string_view{};
  18.         }
  19.         return path.substr(pos);
  20.     }();
  21.     if (iequals(ext, ".htm"))
  22.     {
  23.         return "text/html";
  24.     }
  25.     if (iequals(ext, ".html"))
  26.     {
  27.         return "text/html";
  28.     }
  29.     if (iequals(ext, ".php"))
  30.     {
  31.         return "text/html";
  32.     }
  33.     if (iequals(ext, ".css"))
  34.     {
  35.         return "text/css";
  36.     }
  37.     if (iequals(ext, ".txt"))
  38.     {
  39.         return "text/plain";
  40.     }
  41.     if (iequals(ext, ".js"))
  42.     {
  43.         return "application/javascript";
  44.     }
  45.     if (iequals(ext, ".json"))
  46.     {
  47.         return "application/json";
  48.     }
  49.     if (iequals(ext, ".xml"))
  50.     {
  51.         return "application/xml";
  52.     }
  53.     if (iequals(ext, ".swf"))
  54.     {
  55.         return "application/x-shockwave-flash";
  56.     }
  57.     if (iequals(ext, ".flv"))
  58.     {
  59.         return "video/x-flv";
  60.     }
  61.     if (iequals(ext, ".png"))
  62.     {
  63.         return "image/png";
  64.     }
  65.     if (iequals(ext, ".jpe"))
  66.     {
  67.         return "image/jpeg";
  68.     }
  69.     if (iequals(ext, ".jpeg"))
  70.     {
  71.         return "image/jpeg";
  72.     }
  73.     if (iequals(ext, ".jpg"))
  74.     {
  75.         return "image/jpeg";
  76.     }
  77.     if (iequals(ext, ".gif"))
  78.     {
  79.         return "image/gif";
  80.     }
  81.     if (iequals(ext, ".bmp"))
  82.     {
  83.         return "image/bmp";
  84.     }
  85.     if (iequals(ext, ".ico"))
  86.     {
  87.         return "image/vnd.microsoft.icon";
  88.     }
  89.     if (iequals(ext, ".tiff"))
  90.     {
  91.         return "image/tiff";
  92.     }
  93.     if (iequals(ext, ".tif"))
  94.     {
  95.         return "image/tiff";
  96.     }
  97.     if (iequals(ext, ".svg"))
  98.     {
  99.         return "image/svg+xml";
  100.     }
  101.     if (iequals(ext, ".svgz"))
  102.     {
  103.         return "image/svg+xml";
  104.     }
  105.     return "application/text";
  106. }
  107.  
  108. std::string path_cat(boost::beast::string_view base, boost::beast::string_view path)
  109. {
  110.     if (base.empty())
  111.     {
  112.         return path.to_string();
  113.     }
  114.     std::string result = base.to_string();
  115. #if BOOST_MSVC
  116.     constexpr char path_separator = '\\';
  117.     if (result.back() == path_separator)
  118.     {
  119.         result.resize(result.size() - 1);
  120.     }
  121.     result.append(path.data(), path.size());
  122.     for (auto& c : result)
  123.     {
  124.         if (c == '/')
  125.         {
  126.             c = path_separator;
  127.         }
  128.     }
  129. #else
  130.     char constexpr path_separator = '/';
  131.     if (result.back() == path_separator)
  132.         result.resize(result.size() - 1);
  133.     result.append(path.data(), path.size());
  134. #endif
  135.     return result;
  136. }
  137.  
  138. void session::on_read(boost::system::error_code ec, std::size_t bytes_transferred)
  139. {
  140.     boost::ignore_unused(bytes_transferred);
  141.  
  142.     // This means they closed the connection
  143.     if (ec == http::error::end_of_stream)
  144.     {
  145.         return do_close();
  146.     }
  147.  
  148.     if (ec)
  149.     {
  150.         return fail(ec, "read");
  151.     }
  152.  
  153.     // Send the response
  154.     handle_request(doc_root_, std::move(req_), lambda_);
  155. }
  156.  
  157. void session::on_write(boost::system::error_code ec, std::size_t bytes_transferred, bool close)
  158. {
  159.     boost::ignore_unused(bytes_transferred);
  160.  
  161.     if (ec)
  162.     {
  163.         return fail(ec, "write");
  164.     }
  165.  
  166.     if (close)
  167.     {
  168.         // This means we should close the connection, usually because
  169.         // the response indicated the "Connection: close" semantic.
  170.         return do_close();
  171.     }
  172.  
  173.     // We're done with the response so delete it
  174.     res_ = nullptr;
  175.  
  176.     // Read another request
  177.     do_read();
  178. }
  179.  
  180. listener::listener(boost::asio::io_context& ioc, tcp::endpoint endpoint, const std::string &doc_root)
  181.     : acceptor_{ ioc }
  182.     , socket_{ ioc }
  183.     , doc_root_{ doc_root }
  184. {
  185.     boost::system::error_code ec;
  186.  
  187.     // Open the acceptor
  188.     acceptor_.open(endpoint.protocol(), ec);
  189.     if (ec)
  190.     {
  191.         fail(ec, "open");
  192.         return;
  193.     }
  194.  
  195.     // Bind to the server address
  196.     acceptor_.bind(endpoint, ec);
  197.     if (ec)
  198.     {
  199.         fail(ec, "bind");
  200.         return;
  201.     }
  202.  
  203.     // Start listening for connections
  204.     acceptor_.listen(boost::asio::socket_base::max_listen_connections, ec);
  205.     if (ec)
  206.     {
  207.         fail(ec, "listen");
  208.         return;
  209.     }
  210. }
  211.  
  212. void listener::on_accept(boost::system::error_code ec)
  213. {
  214.     if (ec)
  215.     {
  216.         fail(ec, "accept");
  217.     }
  218.     else
  219.     {
  220.         // Create the session and run it
  221.         std::make_shared<session>(std::move(socket_), doc_root_)->run();
  222.     }
  223.  
  224.     // Accept another connection
  225.     do_accept();
  226. }
Add Comment
Please, Sign In to add comment