diff options
author | Jon Bergli Heier <snakebite@jvnv.net> | 2010-12-27 18:45:20 +0100 |
---|---|---|
committer | Jon Bergli Heier <snakebite@jvnv.net> | 2010-12-27 18:45:20 +0100 |
commit | 263097e22bdf0a56007644e4d19605371dc79a8f (patch) | |
tree | 1ed40707f9714e178ed07abf834b1a13c33bddc0 | |
parent | cd8874addb61e11cef83d4be31110ed670b58884 (diff) |
Basic directory listing for HTTP.
-rw-r--r-- | httpd.cpp | 48 | ||||
-rw-r--r-- | httpd.h | 2 | ||||
-rw-r--r-- | music.cpp | 41 | ||||
-rw-r--r-- | music.h | 20 |
4 files changed, 103 insertions, 8 deletions
@@ -1,6 +1,11 @@ #include "httpd.h" +#include "music.h" #include <boost/bind.hpp> +#include <boost/algorithm/string/split.hpp> +#include <boost/algorithm/string/classification.hpp> +#include <boost/algorithm/string/predicate.hpp> +#include <boost/format.hpp> #include <iostream> @@ -10,12 +15,53 @@ HTTPConnection::HTTPConnection(boost::asio::io_service& io_service) : socket(io_ 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<std::string> 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() { - std::cout << "kake" << std::endl; + 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)) { @@ -12,7 +12,9 @@ class HTTPConnection : public boost::enable_shared_from_this<HTTPConnection> { private: HTTPConnection(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; public: typedef boost::shared_ptr<HTTPConnection> pointer; @@ -1,6 +1,6 @@ #include "music.h" -#include <iostream> +#include <boost/format.hpp> namespace music { @@ -10,7 +10,41 @@ void init(const fs::path root) { root_directory = new MusicDirectory(root); } -}; +MusicListing *find(const std::string path, MusicDirectory& root) { + fs::path full_path = root_directory->path / path; + if(root.path == full_path) + return &root; + + for(MusicDirectories::iterator it = root.directories.begin(); it != root.directories.end(); it++) { + MusicListing *ml = find(path, *it); + if(ml) return ml; + } + for(MusicTracks::iterator it = root.tracks.begin(); it != root.tracks.end(); it++) { + std::string rel_path = it->path.string().substr(root_directory->path.string().size()); + std::cout << rel_path << std::endl; + if(rel_path == path) + return &(*it); + } + + return NULL; +} + +MusicListing *find(const std::string path) { + return find(path, *root_directory); +} + +}; // namespace music + +void MusicDirectory::render(std::ostream& os) { + for(MusicDirectories::iterator it = directories.begin(); it != directories.end(); it++) { + std::string rel_path = it->path.string().substr(music::root_directory->path.string().size()); + os << boost::format("<a href=\"%s\">%s</a><br />") % rel_path % rel_path; + } + for(MusicTracks::iterator it = tracks.begin(); it != tracks.end(); it++) { + std::string rel_path = it->path.string().substr(music::root_directory->path.string().size()); + os << boost::format("<a href=\"%s\">%s</a><br />") % rel_path % rel_path; + } +} MusicTrack::MusicTrack(const fs::path path) { std::cout << path << std::endl; @@ -32,3 +66,6 @@ MusicDirectory::MusicDirectory(const fs::path root) { } } } + +void MusicTrack::render(std::ostream& os) { +} @@ -3,30 +3,40 @@ #include <boost/filesystem.hpp> #include <vector> +#include <iostream> namespace fs = boost::filesystem; -class MusicTrack { +class MusicListing { public: - MusicTrack(const fs::path path); fs::path path; + virtual void render(std::ostream& os) = 0; +}; + +class MusicTrack : public MusicListing { + public: + MusicTrack(const fs::path path); + virtual void render(std::ostream& os); }; class MusicDirectory; typedef std::vector<MusicDirectory> MusicDirectories; typedef std::vector<MusicTrack> MusicTracks; -class MusicDirectory { +class MusicDirectory : public MusicListing { public: - MusicDirectory(const fs::path root); - fs::path path; MusicDirectories directories; MusicTracks tracks; + + MusicDirectory(const fs::path root); + virtual void render(std::ostream& os); }; namespace music { extern MusicDirectory *root_directory; void init(const fs::path root); + MusicListing *find(const std::string path, MusicDirectory& root); + MusicListing *find(const std::string path); }; #endif |