diff options
author | Jon Bergli Heier <snakebite@jvnv.net> | 2010-12-27 20:48:35 +0100 |
---|---|---|
committer | Jon Bergli Heier <snakebite@jvnv.net> | 2010-12-27 20:48:35 +0100 |
commit | 1a8f351248c38445189a397035e8a2cb3182ea6a (patch) | |
tree | 507c96dc5fc1e158f799cdeb13cfab382a7a0534 | |
parent | 263097e22bdf0a56007644e4d19605371dc79a8f (diff) |
Added HTTPRequest and HTTPResponse classes.
-rw-r--r-- | SConstruct | 1 | ||||
-rw-r--r-- | http.cpp | 46 | ||||
-rw-r--r-- | http.h | 27 | ||||
-rw-r--r-- | httpd.cpp | 36 | ||||
-rw-r--r-- | music.cpp | 9 | ||||
-rw-r--r-- | music.h | 4 |
6 files changed, 95 insertions, 28 deletions
@@ -5,6 +5,7 @@ env = Environment(CPPPATH = ['.'], CCFLAGS = ['-pthread'], LINKFLAGS = ['-pthrea conf = Configure(env) conf.CheckLib('boost_system') conf.CheckLib('boost_filesystem') +conf.CheckLib('boost_regex') env = conf.Finish() if GetOption('release'): diff --git a/http.cpp b/http.cpp new file mode 100644 index 0000000..8d69f93 --- /dev/null +++ b/http.cpp @@ -0,0 +1,46 @@ +#include "http.h" + +#include <boost/format.hpp> +#include <boost/algorithm/string.hpp> +#include <boost/algorithm/string/regex.hpp> + +#include <vector> + +HTTPRequest::HTTPRequest(std::istream& is) { + std::string line, firstline; + std::getline(is, firstline); + + 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; + + while(is.good()) { + std::string line; + std::getline(is, line); + boost::trim(line); + if(!line.size()) continue; + std::vector<std::string> v; + boost::algorithm::split_regex(v, line, boost::regex(": ")); + headers[v[0]] = v[1]; + } +} + +HTTPResponse::HTTPResponse() { + httpver = "1.1"; +} + +void HTTPResponse::add_header(std::string key, std::string value) { + headers[key] = value; +} + +void HTTPResponse::write_headers(std::ostream& os) { + os << boost::format("HTTP/%s %d %s\r\n") % httpver % code % status; + for(HTTPHeaders::iterator it = headers.begin(); it != headers.end(); it++) { + os << boost::format("%s: %s\r\n") % it->first % it->second; + } + os << "\r\n"; +} @@ -0,0 +1,27 @@ +#ifndef HTTP_H +#define HTTP_H + +#include <iostream> +#include <string> +#include <map> + +typedef std::map<std::string, std::string> HTTPHeaders; + +class HTTPRequest { + public: + std::string type, path, httpver; + HTTPHeaders headers; + HTTPRequest(std::istream& is); +}; + +class HTTPResponse { + public: + HTTPHeaders headers; + int code; + std::string httpver, status; + HTTPResponse(); + void add_header(std::string key, std::string value); + void write_headers(std::ostream& os); +}; + +#endif @@ -1,5 +1,6 @@ #include "httpd.h" #include "music.h" +#include "http.h" #include <boost/bind.hpp> #include <boost/algorithm/string/split.hpp> @@ -17,42 +18,29 @@ void HTTPConnection::handle_write(const boost::system::error_code& error, size_t 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); + HTTPRequest req(is); boost::asio::streambuf b; std::ostream os(&b); - MusicListing *ml = music::find(path); + HTTPResponse res; + + MusicListing *ml = music::find(req.path); if(ml) { - os << "HTTP/1.1 200 OK\r\n"; - os << "content-type: text/html\r\n"; - os << "\r\n"; + res.code = 200; + res.status = "OK"; + res.add_header("content-type", "text/html"); + res.write_headers(os); ml->render(os); } else { - os << "HTTP/1.1 404 Not Found\r\n"; - os << "\r\n"; + res.code = 404; + res.status = "Not Found"; + res.write_headers(os); } 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) { @@ -1,6 +1,7 @@ #include "music.h" #include <boost/format.hpp> +#include <boost/algorithm/string/predicate.hpp> namespace music { @@ -10,7 +11,11 @@ void init(const fs::path root) { root_directory = new MusicDirectory(root); } -MusicListing *find(const std::string path, MusicDirectory& root) { +MusicListing *find(std::string path, MusicDirectory& root) { + // remove trailing slash + if(boost::algorithm::ends_with(path, "/")) + path = path.substr(0, path.size()-1); + fs::path full_path = root_directory->path / path; if(root.path == full_path) return &root; @@ -29,7 +34,7 @@ MusicListing *find(const std::string path, MusicDirectory& root) { return NULL; } -MusicListing *find(const std::string path) { +MusicListing *find(std::string path) { return find(path, *root_directory); } @@ -35,8 +35,8 @@ class MusicDirectory : public MusicListing { 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); + MusicListing *find(std::string path, MusicDirectory& root); + MusicListing *find(std::string path); }; #endif |