From 017235e15ccdfca901d63793c5544626e730ec48 Mon Sep 17 00:00:00 2001 From: Howaner Date: Tue, 2 Sep 2014 20:02:52 +0200 Subject: [WebAdmin] Code improvements. --- src/WebAdmin.cpp | 150 +++++++++++++++++++++++++++++++++---------------------- src/WebAdmin.h | 10 +++- 2 files changed, 99 insertions(+), 61 deletions(-) diff --git a/src/WebAdmin.cpp b/src/WebAdmin.cpp index 35a6d401c..341c64236 100644 --- a/src/WebAdmin.cpp +++ b/src/WebAdmin.cpp @@ -131,7 +131,7 @@ bool cWebAdmin::Start(void) m_TemplateScript.RegisterAPILibs(); if (!m_TemplateScript.LoadFile(FILE_IO_PREFIX "webadmin/template.lua")) { - LOGERROR("Could not load WebAdmin template \"%s\". WebAdmin disabled!", FILE_IO_PREFIX "webadmin/template.lua"); + LOGWARN("Could not load WebAdmin template \"%s\". WebAdmin disabled!", FILE_IO_PREFIX "webadmin/template.lua"); m_TemplateScript.Close(); m_HTTPServer.Stop(); return false; @@ -348,6 +348,94 @@ void cWebAdmin::HandleRootRequest(cHTTPConnection & a_Connection, cHTTPRequest & +void cWebAdmin::HandleFileRequest(cHTTPConnection & a_Connection, cHTTPRequest & a_Request) +{ + AString FileURL = a_Request.GetURL(); + std::replace(FileURL.begin(), FileURL.end(), '\\', '/'); + + // Remove all leading backslashes: + if (FileURL[0] == '/') + { + size_t FirstCharToRead = FileURL.find_first_not_of('/'); + if (FirstCharToRead != AString::npos) + { + FileURL = FileURL.substr(FirstCharToRead); + } + } + + // Remove all "../" strings: + ReplaceString(FileURL, "../", ""); + + bool LoadedSuccessfull = false; + AString Content = "

404 Not Found

"; + AString Path = Printf(FILE_IO_PREFIX "webadmin/files/%s", FileURL.c_str()); + if (cFile::IsFile(Path)) + { + cFile File(Path, cFile::fmRead); + AString FileContent; + if (File.IsOpen() && (File.ReadRestOfFile(FileContent) != -1)) + { + LoadedSuccessfull = true; + Content = FileContent; + } + } + + // Find content type (The currently method is very bad. We should change it later) + AString ContentType = "text/html"; + size_t LastPointPosition = Path.find_last_of('.'); + if (LoadedSuccessfull && (LastPointPosition != AString::npos) && (LastPointPosition < Path.length())) + { + AString FileExtension = Path.substr(LastPointPosition + 1); + ContentType = GetContentTypeFromFileExt(FileExtension); + } + + // Send the response: + cHTTPResponse Resp; + Resp.SetContentType(ContentType); + a_Connection.Send(Resp); + a_Connection.Send(Content); + a_Connection.FinishResponse(); +} + + + + + +AString cWebAdmin::GetContentTypeFromFileExt(const AString & a_FileExtension) +{ + static bool IsInitialized = false; + static std::map ContentTypeMap; + if (!IsInitialized) + { + // Initialize the ContentTypeMap: + ContentTypeMap["png"] = "image/png"; + ContentTypeMap["fif"] = "image/fif"; + ContentTypeMap["gif"] = "image/gif"; + ContentTypeMap["jpeg"] = "image/jpeg"; + ContentTypeMap["jpg"] = "image/jpeg"; + ContentTypeMap["jpe"] = "image/jpeg"; + ContentTypeMap["tiff"] = "image/tiff"; + ContentTypeMap["ico"] = "image/ico"; + ContentTypeMap["csv"] = "image/comma-separated-values"; + ContentTypeMap["css"] = "text/css"; + ContentTypeMap["js"] = "text/javascript"; + ContentTypeMap["txt"] = "text/plain"; + ContentTypeMap["rtx"] = "text/richtext"; + ContentTypeMap["xml"] = "text/xml"; + } + + AString FileExtension = StrToLower(a_FileExtension); + if (ContentTypeMap.find(a_FileExtension) == ContentTypeMap.end()) + { + return "text/html"; + } + return ContentTypeMap[FileExtension]; +} + + + + + sWebAdminPage cWebAdmin::GetPage(const HTTPRequest & a_Request) { sWebAdminPage Page; @@ -414,6 +502,7 @@ AString cWebAdmin::GetDefaultPage(void) + AString cWebAdmin::GetBaseURL( const AString& a_URL) { return GetBaseURL(StringSplit(a_URL, "/")); @@ -560,64 +649,7 @@ void cWebAdmin::OnRequestFinished(cHTTPConnection & a_Connection, cHTTPRequest & } else { - AString FileURL = URL; - std::replace(FileURL.begin(), FileURL.end(), '\\', '/'); - - // Remove all backsplashes on the first place: - if (FileURL[0] == '/') - { - size_t FirstCharToRead = FileURL.find_first_not_of('/'); - if (FirstCharToRead != AString::npos) - { - FileURL = FileURL.substr(FirstCharToRead); - } - } - - // Remove all "../" strings: - ReplaceString(FileURL, "../", ""); - - bool LoadedSuccessfull = false; - AString Content = "

404 Not Found

"; - AString Path = Printf(FILE_IO_PREFIX "webadmin/files/%s", FileURL.c_str()); - if (cFile::IsFile(Path)) - { - cFile File(Path, cFile::fmRead); - AString FileContent; - if (File.IsOpen() && (File.ReadRestOfFile(FileContent) != -1)) - { - LoadedSuccessfull = true; - Content = FileContent; - } - } - - // Find content type (The currently method is very bad. We should change it later) - AString ContentType = "text/html"; - size_t LastPointPosition = Path.find_last_of('.'); - if (LoadedSuccessfull && (LastPointPosition != AString::npos) && (LastPointPosition < Path.length())) - { - const AString & FileExtension = StrToLower(Path.substr(LastPointPosition + 1)); - if (FileExtension == "png") ContentType = "image/png"; - if (FileExtension == "fif") ContentType = "image/fif"; - if (FileExtension == "gif") ContentType = "image/gif"; - if (FileExtension == "jpeg") ContentType = "image/jpeg"; - if (FileExtension == "jpg") ContentType = "image/jpeg"; - if (FileExtension == "jpe") ContentType = "image/jpeg"; - if (FileExtension == "tiff") ContentType = "image/tiff"; - if (FileExtension == "ico") ContentType = "image/ico"; - if (FileExtension == "csv") ContentType = "text/comma-separated-values"; - if (FileExtension == "css") ContentType = "text/css"; - if (FileExtension == "js") ContentType = "text/javascript"; - if (FileExtension == "txt") ContentType = "text/plain"; - if (FileExtension == "rtx") ContentType = "text/richtext"; - if (FileExtension == "xml") ContentType = "text/xml"; - } - - // Send the response: - cHTTPResponse Resp; - Resp.SetContentType(ContentType); - a_Connection.Send(Resp); - a_Connection.Send(Content); - a_Connection.FinishResponse(); + HandleFileRequest(a_Connection, a_Request); } // Delete any request data assigned to the request: diff --git a/src/WebAdmin.h b/src/WebAdmin.h index a59c69096..d6baa2ef9 100644 --- a/src/WebAdmin.h +++ b/src/WebAdmin.h @@ -116,7 +116,7 @@ public: /** Stops the HTTP server, if it was started. */ void Stop(void); - /** Loads the login template. Returns true if the loading success, false if not. */ + /** Loads the login template. Returns true if the loading succeeds, false if not. */ bool LoadLoginTemplate(void); void AddPlugin(cWebPlugin * a_Plugin); @@ -149,6 +149,9 @@ public: /** Returns the prefix needed for making a link point to the webadmin root from the given URL ("../../../webadmin"-style) */ static AString GetBaseURL(const AStringVector & a_URLSplit); + /** Returns the content type from the file extension. If the extension isn't in the list, the function returns "text/html" */ + AString GetContentTypeFromFileExt(const AString & a_FileExtension); + protected: /** Common base class for request body data handlers */ class cRequestData @@ -208,7 +211,7 @@ protected: /** The Lua template script to provide templates: */ cLuaState m_TemplateScript; - /** The template who provide the login side: */ + /** The template that provides the login site: */ AString m_LoginTemplate; /** The HTTP server which provides the underlying HTTP parsing, serialization and events */ @@ -220,6 +223,9 @@ protected: /** Handles requests for the root page */ void HandleRootRequest(cHTTPConnection & a_Connection, cHTTPRequest & a_Request); + /** Handles requests for a file */ + void HandleFileRequest(cHTTPConnection & a_Connection, cHTTPRequest & a_Request); + // cHTTPServer::cCallbacks overrides: virtual void OnRequestBegun (cHTTPConnection & a_Connection, cHTTPRequest & a_Request) override; virtual void OnRequestBody (cHTTPConnection & a_Connection, cHTTPRequest & a_Request, const char * a_Data, size_t a_Size) override; -- cgit v1.2.3