From 1a8f351248c38445189a397035e8a2cb3182ea6a Mon Sep 17 00:00:00 2001 From: Jon Bergli Heier Date: Mon, 27 Dec 2010 20:48:35 +0100 Subject: Added HTTPRequest and HTTPResponse classes. --- SConstruct | 1 + http.cpp | 46 ++++++++++++++++++++++++++++++++++++++++++++++ http.h | 27 +++++++++++++++++++++++++++ httpd.cpp | 36 ++++++++++++------------------------ music.cpp | 9 +++++++-- music.h | 4 ++-- 6 files changed, 95 insertions(+), 28 deletions(-) create mode 100644 http.cpp create mode 100644 http.h diff --git a/SConstruct b/SConstruct index 23aacb8..07e2a04 100644 --- a/SConstruct +++ b/SConstruct @@ -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 +#include +#include + +#include + +HTTPRequest::HTTPRequest(std::istream& is) { + std::string line, firstline; + std::getline(is, firstline); + + 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; + + while(is.good()) { + std::string line; + std::getline(is, line); + boost::trim(line); + if(!line.size()) continue; + std::vector 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"; +} diff --git a/http.h b/http.h new file mode 100644 index 0000000..f7aec59 --- /dev/null +++ b/http.h @@ -0,0 +1,27 @@ +#ifndef HTTP_H +#define HTTP_H + +#include +#include +#include + +typedef std::map 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 diff --git a/httpd.cpp b/httpd.cpp index 3d25a0e..8eac976 100644 --- a/httpd.cpp +++ b/httpd.cpp @@ -1,5 +1,6 @@ #include "httpd.h" #include "music.h" +#include "http.h" #include #include @@ -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 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) { diff --git a/music.cpp b/music.cpp index 3f44bf5..5ff9ec9 100644 --- a/music.cpp +++ b/music.cpp @@ -1,6 +1,7 @@ #include "music.h" #include +#include 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); } diff --git a/music.h b/music.h index 4e790d8..0e51003 100644 --- a/music.h +++ b/music.h @@ -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 -- cgit v1.2.3