Guest User

Untitled

a guest
May 4th, 2020
52
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.08 KB | None | 0 0
  1. #include <boost/beast/core.hpp>
  2. #include <boost/beast/http.hpp>
  3. #include <boost/beast/version.hpp>
  4. #include <boost/asio.hpp>
  5. #include <chrono>
  6. #include <cstdlib>
  7. #include <ctime>
  8. #include <iostream>
  9. #include <memory>
  10. #include <string>
  11.  
  12. namespace beast = boost::beast;         // from <boost/beast.hpp>
  13. namespace http = beast::http;           // from <boost/beast/http.hpp>
  14. namespace net = boost::asio;            // from <boost/asio.hpp>
  15. using tcp = boost::asio::ip::tcp;       // from <boost/asio/ip/tcp.hpp>
  16.  
  17. class http_connection : public std::enable_shared_from_this<http_connection>
  18. {
  19. public:
  20.     http_connection(tcp::socket socket)
  21.         : socket_(std::move(socket))
  22.     {
  23.     }
  24.  
  25.     // Initiate the asynchronous operations associated with the connection.
  26.     void
  27.     start()
  28.     {
  29.         read_request();
  30.     }
  31.  
  32. private:
  33.     // The socket for the currently connected client.
  34.     tcp::socket socket_;
  35.  
  36.     // The buffer for performing reads.
  37.     beast::flat_buffer buffer_{8192};
  38.  
  39.     // The request message.
  40.     http::request<http::dynamic_body> request_;
  41.  
  42.     // The response message.
  43.     http::response<http::dynamic_body> response_;
  44.  
  45.     // Asynchronously receive a complete request message.
  46.     void
  47.     read_request()
  48.     {
  49.         auto self = shared_from_this();
  50.  
  51.         http::async_read(
  52.             socket_,
  53.             buffer_,
  54.             request_,
  55.             [self](beast::error_code ec,
  56.                 std::size_t bytes_transferred)
  57.             {
  58.                 boost::ignore_unused(bytes_transferred);
  59.                 if(!ec)
  60.                     self->process_request();
  61.             });
  62.     }
  63.  
  64.     // Determine what needs to be done with the request message.
  65.     void
  66.     process_request()
  67.     {
  68.         write_response();
  69.     }
  70.  
  71.     // Asynchronously transmit the response message.
  72.     void
  73.     write_response()
  74.     {
  75.         //         // The response message.
  76.         http::response<boost::beast::http::dynamic_body> response_;        
  77.         response_.version(request_.version());
  78.         response_.set(http::field::server, "Beast");
  79.         response_.keep_alive(false);
  80.         response_.result(boost::beast::http::status::not_found);
  81.         response_.set(boost::beast::http::field::content_type, "text/plain");
  82.         boost::beast::ostream(response_.body()) << "File not found\r\n";
  83.  
  84.         if (!socket_.is_open()) {
  85.             return;
  86.         }
  87.  
  88.         response_.prepare_payload();
  89.  
  90.         auto self(shared_from_this());
  91.  
  92.         boost::beast::http::async_write(
  93.                 socket_,
  94.                 response_,
  95.                 [self](boost::beast::error_code ec, std::size_t)
  96.                 {
  97.                     // self->socket_.shutdown(tcp::socket::shutdown_send, ec);
  98.                     // self->deadline_.cancel();
  99.                 });
  100.     }
  101. };
  102.  
  103. // "Loop" forever accepting new connections.
  104. void
  105. http_server(tcp::acceptor& acceptor, tcp::socket& socket)
  106. {
  107.   acceptor.async_accept(socket,
  108.       [&](beast::error_code ec)
  109.       {
  110.           if(!ec)
  111.               std::make_shared<http_connection>(std::move(socket))->start();
  112.           http_server(acceptor, socket);
  113.       });
  114. }
  115.  
  116. int
  117. main(int argc, char* argv[])
  118. {
  119.     try
  120.     {
  121.         // Check command line arguments.
  122.         if(argc != 3)
  123.         {
  124.             std::cerr << "Usage: " << argv[0] << " <address> <port>\n";
  125.             std::cerr << "  For IPv4, try:\n";
  126.             std::cerr << "    receiver 0.0.0.0 80\n";
  127.             std::cerr << "  For IPv6, try:\n";
  128.             std::cerr << "    receiver 0::0 80\n";
  129.             return EXIT_FAILURE;
  130.         }
  131.  
  132.         auto const address = net::ip::make_address(argv[1]);
  133.         unsigned short port = static_cast<unsigned short>(std::atoi(argv[2]));
  134.  
  135.         net::io_service ioc{1};
  136.  
  137.         tcp::acceptor acceptor{ioc, {address, port}};
  138.         tcp::socket socket{ioc};
  139.         http_server(acceptor, socket);
  140.  
  141.         ioc.run();
  142.     }
  143.     catch(std::exception const& e)
  144.     {
  145.         std::cerr << "Error: " << e.what() << std::endl;
  146.         return EXIT_FAILURE;
  147.     }
  148. }
Add Comment
Please, Sign In to add comment