From 2d37739c30009752f0468a7431821286309797c1 Mon Sep 17 00:00:00 2001 From: Thulinma Date: Wed, 3 Jun 2015 16:39:16 +0200 Subject: [PATCH] Added basic minimal HTTP server output. --- CMakeLists.txt | 1 + src/output/output_http_minimalserver.cpp | 69 ++++++++++++++++++++++++ src/output/output_http_minimalserver.h | 16 ++++++ 3 files changed, 86 insertions(+) create mode 100644 src/output/output_http_minimalserver.cpp create mode 100644 src/output/output_http_minimalserver.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 4842459f..594d1c30 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -308,6 +308,7 @@ endmacro() makeOutput(RTMP rtmp) makeOutput(OGG progressive_ogg http) makeOutput(FLV progressive_flv http) +makeOutput(HTTPMinimalServer http_minimalserver http) makeOutput(MP4 progressive_mp4 http) makeOutput(MP3 progressive_mp3 http) makeOutput(HSS hss http) diff --git a/src/output/output_http_minimalserver.cpp b/src/output/output_http_minimalserver.cpp new file mode 100644 index 00000000..ebdac0e7 --- /dev/null +++ b/src/output/output_http_minimalserver.cpp @@ -0,0 +1,69 @@ +#include "output_http_minimalserver.h" +#include + +namespace Mist { + OutHTTPMinimalServer::OutHTTPMinimalServer(Socket::Connection & conn) : HTTPOutput(conn){ + //resolve symlinks etc to a real path + char * rp = realpath(config->getString("webroot").c_str(), 0); + if (rp){ + resolved_path = rp; + resolved_path += "/"; + free(rp); + } + } + OutHTTPMinimalServer::~OutHTTPMinimalServer() {} + + void OutHTTPMinimalServer::init(Util::Config * cfg){ + HTTPOutput::init(cfg); + capa["name"] = "HTTPMinimalServer"; + capa["desc"] = "Serves static files over HTTP from a set folder"; + capa["url_rel"] = "/static/"; + capa["url_prefix"] = "/static/"; + cfg->addOption("webroot", JSON::fromString("{\"arg\":\"string\", \"short\":\"w\",\"long\":\"webroot\",\"help\":\"Root directory for static files to serve.\"}")); + capa["required"]["webroot"]["name"] = "Web root directory"; + capa["required"]["webroot"]["help"] = "Main directory where files are served from."; + capa["required"]["webroot"]["type"] = "str"; + capa["required"]["webroot"]["option"] = "--webroot"; + } + + void OutHTTPMinimalServer::onHTTP(){ + //determine actual file path for the request + std::string path = resolved_path + H.url.substr(8); + + //convert this to a real path with resolved symlinks etc + char * rp = realpath(path.c_str(), 0); + if (rp){ + path = rp; + free(rp); + } + + if (!rp || path.substr(0, resolved_path.size()) != resolved_path){ + if (!rp){ + WARN_MSG("URL %s does not exist: %s", H.url.c_str(), path.c_str()); + }else{ + WARN_MSG("URL %s is not inside webroot %s: %s", H.url.c_str(), resolved_path.c_str(), path.c_str()); + } + H.Clean(); + H.SetHeader("Server", "mistserver/" PACKAGE_VERSION); + H.SetBody("File not found"); + H.SendResponse("404", "OK", myConn); + return; + } + + + char buffer[4096]; + std::ifstream inFile(path.c_str()); + inFile.seekg(0, std::ios_base::end); + unsigned long long filesize = inFile.tellg(); + inFile.seekg(0, std::ios_base::beg); + H.Clean(); + H.SetHeader("Server", "mistserver/" PACKAGE_VERSION); + H.SetHeader("Content-Length", filesize); + H.SendResponse("200", "OK", myConn); + while (inFile.good()){ + inFile.read(buffer, 4096); + myConn.SendNow(buffer, inFile.gcount()); + } + } +} + diff --git a/src/output/output_http_minimalserver.h b/src/output/output_http_minimalserver.h new file mode 100644 index 00000000..a767db52 --- /dev/null +++ b/src/output/output_http_minimalserver.h @@ -0,0 +1,16 @@ +#include "output_http.h" + +namespace Mist { + class OutHTTPMinimalServer : public HTTPOutput { + public: + OutHTTPMinimalServer(Socket::Connection & conn); + ~OutHTTPMinimalServer(); + static void init(Util::Config * cfg); + void onHTTP(); + private: + std::string resolved_path; + }; +} + +typedef Mist::OutHTTPMinimalServer mistOut; +