summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVegard Storheil Eriksen <zyp@jvnv.net>2011-01-02 16:13:15 +0100
committerVegard Storheil Eriksen <zyp@jvnv.net>2011-01-02 16:13:15 +0100
commit4a0d339854536f65b9418c79b617bb718062905f (patch)
treec7b80fee61114197269beb37af7dc345c81336db
parent1ec379a805fdc4e7e076f1f59fa054bde8cf89c2 (diff)
Decoupled HTTP::Connection from handler.
-rw-r--r--http_connection.cpp26
-rw-r--r--http_connection.h30
-rw-r--r--httpd.cpp21
-rw-r--r--httpd.h4
-rw-r--r--main.cpp20
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
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 <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;
diff --git a/main.cpp b/main.cpp
index ccca2ad..c66c6ec 100644
--- a/main.cpp
+++ b/main.cpp
@@ -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>();