From 4a0d339854536f65b9418c79b617bb718062905f Mon Sep 17 00:00:00 2001 From: Vegard Storheil Eriksen Date: Sun, 2 Jan 2011 16:13:15 +0100 Subject: Decoupled HTTP::Connection from handler. --- http_connection.cpp | 26 ++++---------------------- http_connection.h | 30 +++++++++++++++++------------- httpd.cpp | 21 ++++++++++++++++++++- httpd.h | 4 ++-- main.cpp | 20 ++++++++++++++++++++ 5 files changed, 63 insertions(+), 38 deletions(-) diff --git a/http_connection.cpp b/http_connection.cpp index ef28089..0e9571c 100644 --- a/http_connection.cpp +++ b/http_connection.cpp @@ -1,7 +1,6 @@ #include "http_connection.h" #include "http.h" -#include "music.h" #include #include @@ -15,24 +14,7 @@ HTTP::Connection::Connection(boost::asio::io_service& io_service) : socket(io_se void HTTP::Connection::handle_write(const boost::system::error_code& error, size_t bytes_transferred) { } -void HTTP::Connection::foo_handler(HTTP::Connection::p connection) { - std::cout << "Handling!" << std::endl; - - HTTPResponse res(connection->socket); - - MusicListing::p ml = music::get(connection->path); - if(ml) { - res.code = 200; - res.status = "OK"; - - ml->render(connection, res); - } else { - res.code = 404; - res.status = "Not Found"; - } -} - -void HTTP::Connection::handle_read(const boost::system::error_code& error, size_t bytes_transferred) { +void HTTP::Connection::handle_read(const boost::system::error_code& error, size_t bytes_transferred, Handler callback) { if(!parse_request(buf)) { // Request parse error. std::cout << "Request parse error." << std::endl; @@ -54,7 +36,7 @@ void HTTP::Connection::handle_read(const boost::system::error_code& error, size_ std::cout << " " << it->first << " = " << it->second << std::endl; } - foo_handler(shared_from_this()); + callback(shared_from_this()); } void print(char c) { @@ -92,7 +74,7 @@ bool HTTP::Connection::parse_request(boost::asio::streambuf& buf) { method, path, args, version, headers); } -void HTTP::Connection::start() { +void HTTP::Connection::read_request(Handler callback) { boost::asio::async_read_until(socket, buf, "\r\n\r\n", boost::bind(&Connection::handle_read, shared_from_this(), - boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); + boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred, callback)); } diff --git a/http_connection.h b/http_connection.h index 8322721..9ceb8a5 100644 --- a/http_connection.h +++ b/http_connection.h @@ -2,31 +2,24 @@ #define HTTP_CONNECTION_H #include -#include +#include #include #include #include using boost::asio::ip::tcp; +#include + namespace HTTP { class Connection : public boost::enable_shared_from_this { friend class Server; - private: - Connection(boost::asio::io_service& io_service); - void handle_write(const boost::system::error_code& error, size_t bytes_transferred); - void handle_read(const boost::system::error_code& error, size_t bytes_transferred); - tcp::socket socket; - boost::asio::streambuf buf; - - //! Parse request headers. - bool parse_request(boost::asio::streambuf& buf); - public: typedef boost::shared_ptr p; + typedef boost::function Handler; - void start(); + void read_request(Handler callback); //! Request method. std::string method; @@ -42,9 +35,20 @@ namespace HTTP { //! Request headers. std::map headers; + + tcp::socket socket; + private: + Connection(boost::asio::io_service& io_service); + void handle_write(const boost::system::error_code& error, size_t bytes_transferred); + void handle_read(const boost::system::error_code& error, size_t bytes_transferred, Handler callback); - static void foo_handler(Connection::p connection); + boost::asio::streambuf buf; + + //! Parse request headers. + bool parse_request(boost::asio::streambuf& buf); }; + + typedef Connection::Handler Handler; }; #endif diff --git a/httpd.cpp b/httpd.cpp index d67533d..e2470c2 100644 --- a/httpd.cpp +++ b/httpd.cpp @@ -17,7 +17,26 @@ void HTTP::Server::start_accept() { void HTTP::Server::handle_accept(Connection::p new_connection, const boost::system::error_code& error) { if(!error) { - new_connection->start(); + new_connection->read_request(boost::bind(&Server::handle_request, this, _1)); start_accept(); } } + +void HTTP::Server::handle_request(Connection::p connection) { + std::string handler; + + if(connection->path.size()) { + // Pop first element of path. + handler = connection->path.front(); + connection->path.erase(connection->path.begin()); + } else { + handler = "index"; + } + + if(handlers.count(handler)) { + // Call handler. + handlers[handler](connection); + } else { + // Error 404. + } +} diff --git a/httpd.h b/httpd.h index 0fd601f..cee2093 100644 --- a/httpd.h +++ b/httpd.h @@ -9,8 +9,6 @@ #include namespace HTTP { - typedef boost::function Handler; - class Server { public: Server(boost::asio::io_service& io_service, const tcp::endpoint& endpoint); @@ -21,6 +19,8 @@ namespace HTTP { void start_accept(); void handle_accept(Connection::p new_connection, const boost::system::error_code& error); + void handle_request(Connection::p connection); + tcp::acceptor acceptor_; std::map handlers; diff --git a/main.cpp b/main.cpp index ccca2ad..c66c6ec 100644 --- a/main.cpp +++ b/main.cpp @@ -10,6 +10,23 @@ #include +void foo_handler(HTTP::Connection::p connection) { + std::cout << "Handling!" << std::endl; + + HTTPResponse res(connection->socket); + + MusicListing::p ml = music::get(connection->path); + if(ml) { + res.code = 200; + res.status = "OK"; + + ml->render(connection, res); + } else { + res.code = 404; + res.status = "Not Found"; + } +} + int main(int argc, char **argv) { try { config::init(); @@ -20,6 +37,9 @@ int main(int argc, char **argv) { boost::asio::io_service io_service; HTTP::Server httpd(io_service, tcp::endpoint(tcp::v6(), config::vm["audist.httpd_port"].as())); + + httpd.add_handler("files", &foo_handler); + telnet::Server telnetd(io_service, tcp::endpoint(tcp::v6(), config::vm["audist.telnetd_port"].as())); std::size_t num_threads = config::vm["audist.threads"].as(); -- cgit v1.2.3