From b6799df1af5dd20ecd7cfc0e36b54b8f12361e41 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Wed, 10 Aug 2011 22:31:42 +0300 Subject: [PATCH] Add an example of Http::Server usage --- .gitignore | 1 + Build | 9 +++++ examples/minihttpd.cpp | 92 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 102 insertions(+) create mode 100644 examples/minihttpd.cpp diff --git a/.gitignore b/.gitignore index d16c915..8c908ea 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ /httpget /libmspnet.a /libmspnet.so +/minihttpd /mspnet.pc /netcat /pc-32-windows diff --git a/Build b/Build index 47032c4..01d3a84 100644 --- a/Build +++ b/Build @@ -45,4 +45,13 @@ package "mspnet" library "mspnet"; }; }; + + program "minihttpd" + { + source "examples/minihttpd.cpp"; + build_info + { + library "mspnet"; + }; + }; }; diff --git a/examples/minihttpd.cpp b/examples/minihttpd.cpp new file mode 100644 index 0000000..b59b0f9 --- /dev/null +++ b/examples/minihttpd.cpp @@ -0,0 +1,92 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; +using namespace Msp; + +class MiniHttpd: public RegisteredApplication +{ +private: + FS::Path root; + Http::Server server; + IO::EventDispatcher event_disp; + +public: + MiniHttpd(int, char **); + +private: + virtual void tick(); + + void request(const Http::Request &, Http::Response &); +}; + +MiniHttpd::MiniHttpd(int argc, char **argv): + root(FS::getcwd()), + server(8080) +{ + if(argc>1) + root /= argv[1]; + server.signal_request.connect(sigc::mem_fun(this, &MiniHttpd::request)); + server.use_event_dispatcher(&event_disp); +} + +void MiniHttpd::tick() +{ + event_disp.tick(); +} + +void MiniHttpd::request(const Http::Request &req, Http::Response &resp) +{ + IO::print("%s requests \"%s\"\n", req.get_header("-Client-Host"), c_escape(req.get_path())); + + FS::Path path = root/req.get_path().substr(1); + if(FS::descendant_depth(path, root)<0) + { + resp = Http::Response(Http::FORBIDDEN); + resp.add_content("You do not have permission to access the requested resource\n"); + return; + } + + try + { + IO::BufferedFile file(path.str()); + resp = Http::Response(Http::OK); + if(FS::extpart(path.str())==".html") + resp.set_header("Content-Type", "text/html"); + char buf[1024]; + while(1) + { + unsigned len = file.read(buf, sizeof(buf)); + if(!len) + break; + resp.add_content(string(buf, len)); + } + } + catch(const IO::file_not_found &) + { + resp = Http::Response(Http::NOT_FOUND); + resp.add_content("The requested resource was not found\n"); + } + catch(const exception &e) + { + resp = Http::Response(Http::INTERNAL_ERROR); + resp.add_content(format("An exception occurred while trying to retrieve %s:\n", req.get_path())); + resp.add_content(format(" type: %s\n", Debug::demangle(typeid(e).name()))); + resp.add_content(format(" what(): %s\n", e.what())); + } + catch(...) + { + resp = Http::Response(Http::INTERNAL_ERROR); + resp.add_content("Something horrible happened and I can't even tell what it was!\n"); + } +} -- 2.43.0