#include "httpd.h" #include "music.h" #include #include #include #include #include #include HTTPConnection::HTTPConnection(boost::asio::io_service& io_service) : socket(io_service) { } void HTTPConnection::handle_write(const boost::system::error_code& error, size_t bytes_transferred) { } void HTTPConnection::handle_read(const boost::system::error_code& error, size_t bytes_transferred) { std::istream is(&buf); std::string line, firstline; std::getline(is, firstline); std::string type, path, httpver; std::vector splitvec; boost::algorithm::split(splitvec, firstline, boost::algorithm::is_space()); type = splitvec[0]; path = splitvec[1]; httpver = splitvec[2]; std::cout << boost::format("%s %s %s\n") % type % path % httpver; if(boost::algorithm::ends_with(path, "/")) path = path.substr(0, path.size()-1); boost::asio::streambuf b; std::ostream os(&b); MusicListing *ml = music::find(path); if(ml) { os << "HTTP/1.1 200 OK\r\n"; os << "content-type: text/html\r\n"; os << "\r\n"; ml->render(os); } else { os << "HTTP/1.1 404 Not Found\r\n"; os << "\r\n"; } boost::asio::write(socket, b); while(is.good()) { std::getline(is, line); std::cout << line << std::endl; } } HTTPConnection::pointer HTTPConnection::create(boost::asio::io_service& io_service) { return pointer(new HTTPConnection(io_service)); } void HTTPConnection::start() { boost::asio::async_read_until(socket, buf, "\r\n\r\n", boost::bind(&HTTPConnection::handle_read, shared_from_this(), boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); } HTTPServer::HTTPServer(boost::asio::io_service& io_service) : acceptor_(io_service, tcp::endpoint(tcp::v4(), 8000)) { start_accept(); } void HTTPServer::start_accept() { HTTPConnection::pointer new_connection = HTTPConnection::create(acceptor_.io_service()); acceptor_.async_accept(new_connection->socket, boost::bind(&HTTPServer::handle_accept, this, new_connection, boost::asio::placeholders::error)); } void HTTPServer::handle_accept(HTTPConnection::pointer new_connection, const boost::system::error_code& error) { if(!error) { new_connection->start(); start_accept(); } }