summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJon Bergli Heier <snakebite@jvnv.net>2010-12-27 18:45:20 +0100
committerJon Bergli Heier <snakebite@jvnv.net>2010-12-27 18:45:20 +0100
commit263097e22bdf0a56007644e4d19605371dc79a8f (patch)
tree1ed40707f9714e178ed07abf834b1a13c33bddc0
parentcd8874addb61e11cef83d4be31110ed670b58884 (diff)
Basic directory listing for HTTP.
-rw-r--r--httpd.cpp48
-rw-r--r--httpd.h2
-rw-r--r--music.cpp41
-rw-r--r--music.h20
4 files changed, 103 insertions, 8 deletions
diff --git a/httpd.cpp b/httpd.cpp
index 5de9948..3d25a0e 100644
--- a/httpd.cpp
+++ b/httpd.cpp
@@ -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)) {
diff --git a/httpd.h b/httpd.h
index f5a3414..34866aa 100644
--- a/httpd.h
+++ b/httpd.h
@@ -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;
diff --git a/music.cpp b/music.cpp
index 39a5936..3f44bf5 100644
--- a/music.cpp
+++ b/music.cpp
@@ -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) {
+}
diff --git a/music.h b/music.h
index 8ce93c1..4e790d8 100644
--- a/music.h
+++ b/music.h
@@ -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