summaryrefslogblamecommitdiffstats
path: root/src/WebAdmin.h
blob: 6a7836613dc2032a68e5f410c3c42a1648b30120 (plain) (tree)
1
2
3
4
5
6
7
8
9




                                                                                                               

            
                              
                    
                            
                             






                         

                                                                                 

      
 


 





                          
  

            
 
 



                  

                                                                   
 



                                                                    
                       

                                                                         
                     

                                                                  
                         
 
                    
 
                                                                  
                                                                    
 
                                                                                                                  
                                                                        
 
                                 

                                                                  








                            
  


            
 
 
 



                           


                            
  
 
 



              
                 
                    
                                      
              
 
         
                    
 


                                                                    
                 






















                                                                                                             
                 


                                     
                                                            
 






                                                                                                                             


                 
                                                    
                                                    

 
                        
                                      
 
                                                                                                  
                        
 
                                                                                             
                         
 

                                                        
 


                                                              
 


                                                             
 

                                                                      
 


                                                                        
                                                             
 
                      
 


                                                                                                                         
 
                                                                                       
                                                                            
 

                                                                                                     







                                                                                    

                    









                                                                                 
                                                           






                                                                         

                                                 
                                                                    
 

                                                                                                     
                                                                    
 
            


















                                                                                                                
                                                                                   
                             
 

                                                                                                     
 

                                                          
 

                                                                                                   
 





                                                                  


                                                                                 
                                                                              
                                                                                                           
 
                                                 
                                                                                                       
 
                                          
                                                                                                       
 
                                             






                                                                                                                     
                                                                                                                        
                   
 
 
 
 


                                              
                    
      

// WebAdmin.h

// Declares the cWebAdmin class representing the admin interface over http protocol, and related services (API)

#pragma once

#include "Bindings/LuaState.h"
#include "IniFile.h"
#include "HTTP/HTTPServer.h"
#include "HTTP/HTTPMessage.h"





// Disable MSVC warnings:
#if defined(_MSC_VER)
#pragma warning(push)
#pragma warning(disable : 4355)  // 'this' : used in base member initializer list
#endif





// tolua_begin
struct HTTPFormData
{
	std::string Name;
	std::string Value;
	std::string Type;
};
// tolua_end




// tolua_begin
struct HTTPRequest
{
	typedef std::map<std::string, std::string> StringStringMap;
	typedef std::map<std::string, HTTPFormData> FormDataMap;

	/** The entire URL presented to the HTTP server. */
	AString URL;

	/** HTTP method used for the request ("GET", "POST" etc.) */
	AString Method;

	/** The Path part of the request's URL (excluding GET params). */
	AString Path;

	/** Name of the logged-in user. Empty if not logged in. */
	AString Username;

	// tolua_end

	/** Parameters given in the URL, after the questionmark */
	StringStringMap Params;  // >> EXPORTED IN MANUALBINDINGS <<

	/** Parameters posted as a part of a form - either in the URL (GET method) or in the body (POST method) */
	StringStringMap PostParams;  // >> EXPORTED IN MANUALBINDINGS <<

	/** Same as PostParams */
	FormDataMap FormData;  // >> EXPORTED IN MANUALBINDINGS <<
};  // tolua_export





// tolua_begin
struct HTTPTemplateRequest
{
	HTTPRequest Request;
};
// tolua_end





struct sWebAdminPage
{
	AString Content;
	AString PluginName;
	AString TabTitle;
	AString TabUrlPath;
	AString ContentType;
};





// tolua_begin
class cWebAdmin :
	// tolua_end
	public cHTTPServer::cCallbacks
// tolua_begin
{
  public:
	// tolua_end

	/** Interface for getting the content of a single WebTab. */
	class cWebTabCallback abstract
	{
	  public:
		// Force a virtual destructor in descendants
		virtual ~cWebTabCallback() {}

		/** Returns the contents for the specified request.
		Returns true if the call was successful, false on an error.
		a_Request is the full HTTP request object, as received from the client.
		a_UrlPath is the UrlPath of the WebTab registered for this request, as parsed from a_Request.
		Descendants should fill a_Content with the page contents
		and optionally set a_ContentType [defaults to "text/html"] */
		virtual bool Call(
			const HTTPRequest & a_Request,
			const AString & a_UrlPath,
			AString & a_Content,
			AString & a_ContentType
		) = 0;
	};


	/** Container for a single web tab.
	Each web tab has a title, URL path and an associated plugin's name.
	Each web tab is registered with a callback to provide the content. */
	class cWebTab
	{
	  public:
		AString m_Title;
		AString m_UrlPath;
		AString m_PluginName;
		std::shared_ptr<cWebTabCallback> m_Callback;

		cWebTab(
			const AString & a_Title,
			const AString & a_UrlPath,
			const AString & a_PluginName,
			std::shared_ptr<cWebTabCallback> a_Callback
		) :
			m_Title(a_Title), m_UrlPath(a_UrlPath), m_PluginName(a_PluginName), m_Callback(std::move(a_Callback))
		{
		}
	};
	typedef std::shared_ptr<cWebTab> cWebTabPtr;
	typedef std::vector<cWebTabPtr> cWebTabPtrs;


	cWebAdmin(void);
	virtual ~cWebAdmin() override;

	/** Initializes the object. Returns true if successfully initialized and ready to start */
	bool Init(void);

	/** Starts the HTTP server taking care of the webadmin. Returns true if successful */
	bool Start(void);

	/** Stops the HTTP server, if it was started. */
	void Stop(void);

	/** Loads the login template into m_LoginPage.
	Returns true if the loading succeeds, false if not. */
	bool LoadLoginPage(void);

	/** Returns a copy of all the registered web tabs.
	Exported to Lua in ManualBindings.cpp. */
	cWebTabPtrs GetAllWebTabs(void) { return m_WebTabs; }

	/** Removes all WebTabs registered by the specified plugin. */
	void RemoveAllPluginWebTabs(const AString & a_PluginName);

	/** Returns the (inner) page contents for the specified request.
	Calls the appropriate WebTab handler to get the contents.
	Exported to Lua in ManualBindings.cpp. */
	sWebAdminPage GetPage(const HTTPRequest & a_Request);

	// tolua_begin

	/** Reloads m_IniFile, m_LoginPage and m_TemplateScript.
	Note that reloading will not change the "enabled" state of the server, and it will not update listening ports. */
	void Reload(void);

	/** Returns the list of ports on which the webadmin is configured to listen. */
	AString GetPorts(void) const { return StringsConcat(m_Ports, ','); }

	/** Returns the prefix needed for making a link point to the webadmin root from the given URL
	 * ("../../../webadmin"-style). */
	static AString GetBaseURL(const AString & a_URL);

	/** Returns the content type from the file extension.
	If the extension isn't in the list, the function returns an empty string. */
	static AString GetContentTypeFromFileExt(const AString & a_FileExtension);

	/** Escapes text passed into it, so it can be embedded into html. */
	static AString GetHTMLEscapedString(const AString & a_Input);
	// tolua_end

	/** Adds a new WebTab handler.
	a_Title is the display title of the tab
	a_UrlPath is the part of the URL that uniquely identifies this tab.
	a_PluginName is the display name of the plugin creating this tab.
	a_Callback is used to provide the actual WebTab contents, when requested.
	Exported in ManualBindings.cpp. */
	void AddWebTab(
		const AString & a_Title,
		const AString & a_UrlPath,
		const AString & a_PluginName,
		std::shared_ptr<cWebTabCallback> a_Callback
	);

	/** Removes the WebTab with the specified URL path.
	Returns true if WebTab was found and removed, false if not found.
	Exported in ManualBindings.cpp */
	bool DelWebTab(const AString & a_UrlPath);

	/** Escapes the string for use in an URL
	Exported to Lua in ManualBindings.cpp. */
	static AString GetURLEncodedString(const AString & a_Input);

	/** 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);

  protected:
	/** Protects m_WebTabs, m_TemplateScript, m_LoginTemplate and m_IniFile against multithreaded access. */
	cCriticalSection m_CS;

	/** All registered WebTab handlers.
	Protected against multithreaded access by m_CS. */
	cWebTabPtrs m_WebTabs;

	/** The Lua template script to provide templates.
	Protected against multithreaded access by m_CS. */
	cLuaState m_TemplateScript;

	/** The HTML page that provides the login.
	Protected against multithreaded access by m_CS. */
	AString m_LoginPage;

	/** The webadmin.ini file, used for the settings and allowed logins.
	Protected against multithreaded access by m_CS. */
	cIniFile m_IniFile;

	/** Set to true if Init() succeeds and the webadmin isn't to be disabled */
	bool m_IsInitialized;

	/** Set to true if Start() succeeds in starting the server, reset back to false in Stop(). */
	bool m_IsRunning;

	/** The ports on which the webadmin is running. */
	AStringVector m_Ports;

	/** The HTTP server which provides the underlying HTTP parsing, serialization and events */
	cHTTPServer m_HTTPServer;


	/** Loads webadmin.ini into m_IniFile.
	Creates a default file if it doesn't exist.
	Returns true if webadmin is enabled, false if disabled. */
	bool LoadIniFile(void);

	/** Checks inside the webadmin.ini file if there are users configured. */
	bool HasUsers();

	/** Handles requests coming to the "/webadmin" or "/~webadmin" URLs */
	void HandleWebadminRequest(cHTTPServerConnection & a_Connection, cHTTPIncomingRequest & a_Request);

	/** Handles requests for the root page */
	void HandleRootRequest(cHTTPServerConnection & a_Connection, cHTTPIncomingRequest & a_Request);

	/** Handles requests for a file */
	void HandleFileRequest(cHTTPServerConnection & a_Connection, cHTTPIncomingRequest & a_Request);

	// cHTTPServer::cCallbacks overrides:
	virtual void OnRequestBegun(cHTTPServerConnection & a_Connection, cHTTPIncomingRequest & a_Request) override;
	virtual void OnRequestBody(
		cHTTPServerConnection & a_Connection,
		cHTTPIncomingRequest & a_Request,
		const char * a_Data,
		size_t a_Size
	) override;
	virtual void OnRequestFinished(cHTTPServerConnection & a_Connection, cHTTPIncomingRequest & a_Request) override;
};  // tolua_export





// Revert MSVC warnings back to orignal state:
#if defined(_MSC_VER)
#pragma warning(pop)
#endif