37 m_Form(a_Request, *this)
62 m_TemplateScript(
"<webadmin_template>"),
63 m_IsInitialized(false),
89 LOGD(
"Initialising WebAdmin...");
118 LOGD(
"Starting WebAdmin...");
135 LOGD(
"Stopping WebAdmin...");
172 return (a_CBWebTab->m_PluginName == a_PluginName);
189 "WebAdmin was previously enabled and now the settings say to disable it." 190 " This will not take effect until you restart the server." 203 LOGWARN(
"Could not load WebAdmin template \"%s\". WebAdmin will not work properly!",
FILE_IO_PREFIX "webadmin/template.lua");
210 LOGWARN(
"Could not load WebAdmin login page \"%s\", using fallback template.",
FILE_IO_PREFIX "webadmin/login_template.html");
214 "<h1>Cuberite WebAdmin</h1>" \
216 "<form method='get' action='webadmin/'>" \
217 "<input type='submit' value='Log in'>" \
232 LOGWARN(
"Regenerating webadmin.ini, all settings will be reset");
263 if ((UserPassword ==
"") || (a_Request.
GetAuthPassword() != UserPassword))
265 a_Connection.
SendNeedAuth(
"Cuberite WebAdmin - bad username or password");
272 ASSERT(BareURL.length() > 0);
273 bool ShouldWrapInTemplate = (!BareURL.empty() && (BareURL[1] !=
'~'));
291 if (Data->m_Form.Finish())
293 for (cHTTPFormParser::const_iterator itr = Data->m_Form.begin(), end = Data->m_Form.end(); itr != end; ++itr)
296 HTTPfd.
Value = itr->second;
298 HTTPfd.
Name = itr->first;
305 size_t idxQM = URL.find(
'?');
306 if (idxQM != AString::npos)
310 for (cHTTPFormParser::const_iterator itr = URLParams.begin(), end = URLParams.end(); itr != end; ++itr)
318 if (ShouldWrapInTemplate)
326 a_Connection.
Send(Resp);
327 a_Connection.
Send(Template.c_str(), Template.length());
339 a_Connection.
Send(resp);
340 a_Connection.
Send(page.Content.c_str(), page.Content.length());
354 a_Connection.
Send(Resp);
366 std::replace(FileURL.begin(), FileURL.end(),
'\\',
'/');
369 if (!FileURL.empty() && (FileURL[0] ==
'/'))
371 size_t FirstCharToRead = FileURL.find_first_not_of(
'/');
372 if (FirstCharToRead != AString::npos)
374 FileURL = FileURL.substr(FirstCharToRead);
379 AString Content =
"<h2>404 Not Found</h2>";
380 AString ContentType =
"text/html";
384 if ((FileURL.find(
"../") == AString::npos) &&
cFile::IsFile(Path))
390 std::swap(Content, FileContent);
391 size_t LastPointPosition = Path.find_last_of(
'.');
392 if (LastPointPosition != AString::npos)
397 if (ContentType.empty())
399 ContentType =
"application/unknown";
406 a_Connection.
Send(Resp);
407 a_Connection.
Send(Content);
417 static bool IsInitialized =
false;
422 ContentTypeMap[
"png"] =
"image/png";
423 ContentTypeMap[
"fif"] =
"image/fif";
424 ContentTypeMap[
"gif"] =
"image/gif";
425 ContentTypeMap[
"jpeg"] =
"image/jpeg";
426 ContentTypeMap[
"jpg"] =
"image/jpeg";
427 ContentTypeMap[
"jpe"] =
"image/jpeg";
428 ContentTypeMap[
"tiff"] =
"image/tiff";
429 ContentTypeMap[
"ico"] =
"image/ico";
430 ContentTypeMap[
"csv"] =
"text/csv";
431 ContentTypeMap[
"css"] =
"text/css";
432 ContentTypeMap[
"js"] =
"text/javascript";
433 ContentTypeMap[
"txt"] =
"text/plain";
434 ContentTypeMap[
"rtx"] =
"text/richtext";
435 ContentTypeMap[
"rtf"] =
"text/richtext";
436 ContentTypeMap[
"xml"] =
"text/xml";
437 ContentTypeMap[
"html"] =
"text/html";
438 ContentTypeMap[
"htm"] =
"text/html";
439 ContentTypeMap[
"xhtml"] =
"application/xhtml+xml";
442 auto itr = ContentTypeMap.find(
StrToLower(a_FileExtension));
443 if (itr == ContentTypeMap.end())
460 if (split.size() <= 2)
472 (wt->m_PluginName == split[1]) &&
473 (wt->m_UrlPath == split[2])
489 "WebTab callback for plugin %s, page %s has failed.",
490 tab->m_PluginName.c_str(), tab->m_Title.c_str()
518 std::shared_ptr<cWebAdmin::cWebTabCallback> a_Callback
522 m_WebTabs.emplace_back(std::make_shared<cWebTab>(a_Title, a_UrlPath, a_PluginName, a_Callback));
534 if ((*itr)->m_UrlPath == a_UrlPath)
552 dst.reserve(a_Input.length());
555 size_t len = a_Input.length();
556 for (
size_t i = 0; i < len; i++)
560 case '&': dst.append(
"&");
break;
561 case '\'': dst.append(
"'");
break;
562 case '"': dst.append(
""");
break;
563 case '<': dst.append(
"<");
break;
564 case '>': dst.append(
">");
break;
567 dst.push_back(a_Input[i]);
592 if (a_URLSplit.size() > 1)
594 for (
unsigned int i = 0; i < a_URLSplit.size(); i++)
598 BaseURL +=
"webadmin/";
612 (strncmp(URL.c_str(),
"/webadmin", 9) == 0) ||
613 (strncmp(URL.c_str(),
"/~webadmin", 10) == 0)
616 a_Request.
SetUserData(std::make_shared<cWebadminRequestData>(a_Request));
650 (strncmp(URL.c_str(),
"/webadmin", 9) == 0) ||
651 (strncmp(URL.c_str(),
"/~webadmin", 10) == 0)
const AString & GetMethod(void) const
Returns the method used in the request.
void Stop(void)
Stops the server, drops all current connections.
void HandleRootRequest(cHTTPServerConnection &a_Connection, cHTTPIncomingRequest &a_Request)
Handles requests for the root page.
AString URL
The entire URL presented to the HTTP server.
bool Call(const FnT &a_Function, Args &&...args)
Call the specified Lua function.
static AString GetURLEncodedString(const AString &a_Input)
Escapes the string for use in an URL Exported to Lua in ManualBindings.cpp.
StringStringMap PostParams
Parameters posted as a part of a form - either in the URL (GET method) or in the body (POST method) ...
Provides storage for an incoming HTTP request.
void Parse(const char *a_Data, size_t a_Size)
Adds more data into the parser, as the request body is received.
Stores outgoing response headers and serializes them to an HTTP data stream.
Base class for anything that can be used as the UserData for the request.
static AString GetHTMLEscapedString(const AString &a_Input)
Escapes text passed into it, so it can be embedded into html.
void SetUserData(cUserDataPtr a_UserData)
Attaches any kind of data to this request, to be later retrieved by GetUserData().
The form has been transmitted as parameters to a GET request.
cWebadminRequestData(const cHTTPIncomingRequest &a_Request)
int ReadRestOfFile(AString &a_Contents)
Reads the file from current position till EOF into an AString; returns the number of bytes read or -1...
void Reload(void)
Reloads m_IniFile, m_LoginPage and m_TemplateScript.
static AString GetContentTypeFromFileExt(const AString &a_FileExtension)
Returns the content type from the file extension.
void HandleFileRequest(cHTTPServerConnection &a_Connection, cHTTPIncomingRequest &a_Request)
Handles requests for a file.
AString Username
Name of the logged-in user.
cIniFile m_IniFile
The webadmin.ini file, used for the settings and allowed logins.
AString Method
HTTP method used for the request ("GET", "POST" etc.)
bool ReadFile(const AString &a_FileName, bool a_AllowExampleRedirect=true)
Reads the contents of the specified ini file If the file doesn't exist and a_AllowExampleRedirect is ...
const AString & GetURL(void) const
Returns the URL used in the request.
virtual void OnFileEnd(cHTTPFormParser &) override
Called when the current file part has ended in the form data.
cUserDataPtr GetUserData(void)
Returns the data attached to this request by the class client.
void SendStatusAndReason(int a_StatusCode, const AString &a_Reason)
Sends HTTP status code together with a_Reason (used for HTTP errors).
std::vector< AString > AStringVector
bool Initialize(void)
Initializes the server - reads the cert files etc.
static bool IsFile(const AString &a_Path)
Returns true if the specified path is a regular file.
bool WriteFile(const AString &a_FileName) const
Writes data stored in class to the specified ini file.
cWebTabPtrs m_WebTabs
All registered WebTab handlers.
virtual ~cWebAdmin() override
void AddWebTab(const AString &a_Title, const AString &a_UrlPath, const AString &a_PluginName, std::shared_ptr< cWebTabCallback > a_Callback)
Adds a new WebTab handler.
void Stop(void)
Stops the HTTP server, if it was started.
bool SetValue(const int keyID, const int valueID, const AString &value)
AString GetURLPath(void) const
Returns the path part of the URL.
static const char DEFAULT_WEBADMIN_PORTS[]
virtual void OnRequestBody(cHTTPServerConnection &a_Connection, cHTTPIncomingRequest &a_Request, const char *a_Data, size_t a_Size) override
Called when another part of request body has arrived.
void HandleWebadminRequest(cHTTPServerConnection &a_Connection, cHTTPIncomingRequest &a_Request)
Handles requests coming to the "/webadmin" or "/~webadmin" URLs.
virtual void OnFileData(cHTTPFormParser &, const char *a_Data, size_t a_Size) override
Called when more file data has come for the current file in the form data.
AString & Printf(AString &str, const char *format, fmt::ArgList args)
Output the formatted text into the string.
void AddHeaderComment(const AString &comment)
Adds a header comment.
void SendNeedAuth(const AString &a_Realm)
Sends the "401 unauthorized" reply together with instructions on authorizing, using the specified rea...
void FinishResponse(void)
Indicates that the current response is finished, gets ready for receiving another request (HTTP 1...
std::map< AString, AString > AStringMap
A string dictionary, used for key-value pairs.
cLuaState m_TemplateScript
The Lua template script to provide templates.
void LOGWARNING(const char *a_Format, fmt::ArgList a_ArgList)
void SetContentType(const AString &a_ContentType)
void Clear(void)
Deletes all stored ini data (but doesn't touch the file)
bool Finish(void)
Notifies that there's no more data incoming and the parser should finish its parsing.
const AString & GetAuthUsername(void) const
Returns the username that the request presented.
AString URLEncode(const AString &a_Text)
URL-encodes the given string.
cHTTPServer m_HTTPServer
The HTTP server which provides the underlying HTTP parsing, serialization and events.
bool DelWebTab(const AString &a_UrlPath)
Removes the WebTab with the specified URL path.
void Close(void)
Closes the m_LuaState, if not closed already.
std::shared_ptr< cWebTab > cWebTabPtr
virtual void OnRequestBegun(cHTTPServerConnection &a_Connection, cHTTPIncomingRequest &a_Request) override
Called when a new request arrives over a connection and all its headers have been parsed...
The form parser callbacks for requests in the "/webadmin" and "/~webadmin" paths. ...
void Send(const cHTTPOutgoingResponse &a_Response)
Sends the headers contained in a_Response.
bool LoadIniFile(void)
Loads webadmin.ini into m_IniFile.
FormDataMap FormData
Same as PostParams.
Provides a RAII-style locking for the LuaState.
void Create(void)
Creates the m_LuaState, if not created already.
sWebAdminPage GetPage(const HTTPRequest &a_Request)
Returns the (inner) page contents for the specified request.
AString Path
The Path part of the request's URL (excluding GET params).
bool LoadFile(const AString &a_FileName, bool a_LogWarnings=true)
Loads the specified file Returns false and optionally logs a warning to the console if not successful...
AStringVector StringSplit(const AString &str, const AString &delim)
Split the string at any of the listed delimiters.
RAII for cCriticalSection - locks the CS on creation, unlocks on destruction.
void RegisterAPILibs(void)
Registers all the API libraries that MCS provides into m_LuaState.
static AString GetBaseURL(const AString &a_URL)
Returns the prefix needed for making a link point to the webadmin root from the given URL ("...
virtual void OnRequestFinished(cHTTPServerConnection &a_Connection, cHTTPIncomingRequest &a_Request) override
Called when the request body has been fully received in previous calls to OnRequestBody() ...
bool IsValid(void) const
Returns true if the m_LuaState is valid.
void RemoveAllPluginWebTabs(const AString &a_PluginName)
Removes all WebTabs registered by the specified plugin.
bool m_IsRunning
Set to true if Start() succeeds in starting the server, reset back to false in Stop().
bool Init(void)
Initializes the object.
AStringVector ReadUpgradeIniPorts(cSettingsRepositoryInterface &a_Settings, const AString &a_KeyName, const AString &a_PortsValueName, const AString &a_OldIPv4ValueName, const AString &a_OldIPv6ValueName, const AString &a_DefaultValue)
Reads the list of ports from the INI file, possibly upgrading from IPv4 / IPv6-specific values into n...
AString m_LoginPage
The HTML page that provides the login.
bool GetValueSetB(const AString &keyname, const AString &valuename, const bool defValue=false) override
virtual void OnFileStart(cHTTPFormParser &, const AString &a_FileName) override
Called when a new file part is encountered in the form data.
bool Start(cCallbacks &a_Callbacks, const AStringVector &a_Ports)
Starts the server and assigns the callbacks to use for incoming requests.
bool m_IsInitialized
Set to true if Init() succeeds and the webadmin isn't to be disabled.
AString GetValue(const AString &keyname, const AString &valuename, const AString &defValue="") const override
Get the value at the specified key and value, returns defValue on failure.
bool Start(void)
Starts the HTTP server taking care of the webadmin.
AString StrToLower(const AString &s)
Returns a lower-cased copy of the string.
StringStringMap Params
Parameters given in the URL, after the questionmark.
const AString & GetAuthPassword(void) const
Returns the password that the request presented.
cCriticalSection m_CS
Protects m_WebTabs, m_TemplateScript, m_LoginTemplate and m_IniFile against multithreaded access...
bool HasAuth(void) const
Returns true if the request has had the Auth header present.
AStringVector m_Ports
The ports on which the webadmin is running.
bool LoadLoginPage(void)
Loads the login template into m_LoginPage.