diff --git a/src/main.cpp b/src/main.cpp index 6587548..c38a2c3 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,39 +1,88 @@ -#include -#include -#include +#include #include -#include #include -namespace beast = boost::beast; -namespace http = beast::http; -namespace net = boost::asio; -using tcp = net::ip::tcp; +class tcp_connection : public std::enable_shared_from_this { + public: + typedef std::shared_ptr pointer; + + static pointer create(boost::asio::io_context& io_context) { + return pointer(new tcp_connection(io_context)); + } + + boost::asio::ip::tcp::socket& socket() { + return socket_; + } + + void start() { + boost::asio::async_read_until(socket_, buffer_, "\r\n\r\n", + std::bind(&tcp_connection::handle_read, shared_from_this(), + boost::asio::placeholders::error, + boost::asio::placeholders::bytes_transferred)); + } + + private: + boost::asio::ip::tcp::socket socket_; + boost::asio::streambuf buffer_; + + explicit tcp_connection(boost::asio::io_context& io_context) : socket_(io_context) {} + + void handle_read(const boost::system::error_code& error, std::size_t bytes_transferred) { + if (!error) { + std::istream request_stream(&buffer_); + std::string request_line; + std::getline(request_stream, request_line); + + std::cout << "Received HTTP request line: " << request_line << std::endl; + + std::string header; + while (std::getline(request_stream, header) && header != "\r") { + std::cout << "Header: " << header << std::endl; + } + } + else { + std::cerr << "Error on receiving request: " << error.message() << std::endl; + } + } + +}; + +class tcp_server { + public: + explicit tcp_server(boost::asio::io_context& io_context, const int port): io_context_(io_context), acceptor_(io_context, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), port)) { + start_accept(); + } + + private: + boost::asio::io_context& io_context_; + boost::asio::ip::tcp::acceptor acceptor_; + + void start_accept() { + tcp_connection::pointer new_connection = tcp_connection::create(io_context_); + acceptor_.async_accept(new_connection->socket(), std::bind(&tcp_server::handle_accept, this, new_connection, boost::asio::placeholders::error)); + } + + void handle_accept(tcp_connection::pointer& new_connection, const boost::system::error_code& error) { + if (!error) + { + new_connection->start(); + } + start_accept(); + } +}; int main(int argc, char *argv[]) { - try { - net::io_context ioc; - tcp::acceptor acceptor{ioc, {tcp::v4(), 8080}}; - - std::cout << "Server is running on port 8080\n"; - - while (true) { - tcp::socket socket(ioc); - acceptor.accept(socket); - beast::flat_buffer buffer; - - http::request req; - http::read(socket, buffer, req); - - http::response res{http::status::found, 11}; - - res.set(http::field::location, "https://www.google.com"); - res.prepare_payload(); - - http::write(socket, res); - socket.shutdown(tcp::socket::shutdown_send); - } - } catch (std::exception e) { - std::cerr << "Error: " << e.what() << std::endl; + std::cout << "Starting server!" << std::endl; + try + { + boost::asio::io_context io_context; + tcp_server server(io_context, 9090); + io_context.run(); } + catch (std::exception& e) + { + std::cerr << e.what() << std::endl; + } + + return 0; } \ No newline at end of file