diff options
author | Vegard Storheil Eriksen <zyp@jvnv.net> | 2011-01-02 16:13:15 +0100 |
---|---|---|
committer | Vegard Storheil Eriksen <zyp@jvnv.net> | 2011-01-02 16:13:15 +0100 |
commit | 4a0d339854536f65b9418c79b617bb718062905f (patch) | |
tree | c7b80fee61114197269beb37af7dc345c81336db | |
parent | 1ec379a805fdc4e7e076f1f59fa054bde8cf89c2 (diff) |
Decoupled HTTP::Connection from handler.
-rw-r--r-- | http_connection.cpp | 26 | ||||
-rw-r--r-- | http_connection.h | 30 | ||||
-rw-r--r-- | httpd.cpp | 21 | ||||
-rw-r--r-- | httpd.h | 4 | ||||
-rw-r--r-- | 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 <boost/bind.hpp> #include <boost/spirit/include/qi.hpp> @@ -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 <string> -#include <vector> +#include <list> #include <map> #include <boost/asio.hpp> #include <boost/enable_shared_from_this.hpp> using boost::asio::ip::tcp; +#include <boost/function.hpp> + namespace HTTP { class Connection : public boost::enable_shared_from_this<Connection> { 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<Connection> p; + typedef boost::function<void (Connection::p)> Handler; - void start(); + void read_request(Handler callback); //! Request method. std::string method; @@ -42,9 +35,20 @@ namespace HTTP { //! Request headers. std::map<std::string, std::string> 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 @@ -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. + } +} @@ -9,8 +9,6 @@ #include <boost/function.hpp> namespace HTTP { - typedef boost::function<void (Connection::p)> 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<std::string, Handler> handlers; @@ -10,6 +10,23 @@ #include <boost/thread.hpp> +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<int>())); + + httpd.add_handler("files", &foo_handler); + telnet::Server telnetd(io_service, tcp::endpoint(tcp::v6(), config::vm["audist.telnetd_port"].as<int>())); std::size_t num_threads = config::vm["audist.threads"].as<std::size_t>(); |