From 968f41ba511f8f74377b1a1c7b61ff759ebe3078 Mon Sep 17 00:00:00 2001 From: faketruth Date: Tue, 31 Jan 2012 20:56:42 +0000 Subject: [PATCH] Changed how Lua handles the (Post)Params in the HTTPRequest of a WebPlugin It should now be theoretically possible to upload files through WebAdmin git-svn-id: http://mc-server.googlecode.com/svn/trunk@203 0a769ca7-a7f5-676a-18bf-c427514a06d6 --- Plugins/Core/web_playerlist.lua | 4 +- Plugins/Core/web_reload.lua | 2 +- Plugins/Core/web_whitelist.lua | 16 +-- WebServer/WebServer.cpp | 230 ++++++++++++++++++++++++++++++-- WebServer/WebServer.h | 9 ++ source/Bindings.cpp | 187 +++++++++++++++----------- source/Bindings.h | 2 +- source/ManualBindings.cpp | 59 ++++++++ source/cPlayer.h | 2 +- source/cStringMap.h | 2 + source/cWebAdmin.cpp | 19 ++- source/cWebAdmin.h | 29 ++-- 12 files changed, 444 insertions(+), 117 deletions(-) diff --git a/Plugins/Core/web_playerlist.lua b/Plugins/Core/web_playerlist.lua index 205306ba8..6c736ce3c 100644 --- a/Plugins/Core/web_playerlist.lua +++ b/Plugins/Core/web_playerlist.lua @@ -2,8 +2,8 @@ function HandleRequest_PlayerList( Request ) local World = cRoot:Get():GetWorld() local Content = "" - if( Request.Params:get("playerlist-kick") ~= "" ) then - local KickPlayerName = Request.Params:get("playerlist-kick") + if( Request.Params["playerlist-kick"] ~= nil ) then + local KickPlayerName = Request.Params["playerlist-kick"] local Player = World:GetPlayer( KickPlayerName ) if( Player == nil ) then Content = Content .. "

Could not find player " .. KickPlayerName .. " !

" diff --git a/Plugins/Core/web_reload.lua b/Plugins/Core/web_reload.lua index 45ed1a40b..3a59ad6b6 100644 --- a/Plugins/Core/web_reload.lua +++ b/Plugins/Core/web_reload.lua @@ -1,7 +1,7 @@ function HandleRequest_Reload( Request ) local Content = "" - if( Request.PostParams:get("reload") ~= "" ) then + if( Request.PostParams["reload"] ~= nil ) then Content = Content .. "" Content = Content .. "

Reloading plugins... This can take a while depending on the plugins you're using.

" cRoot:Get():GetPluginManager():ReloadPlugins() diff --git a/Plugins/Core/web_whitelist.lua b/Plugins/Core/web_whitelist.lua index 1a99a9f95..2c9ddb953 100644 --- a/Plugins/Core/web_whitelist.lua +++ b/Plugins/Core/web_whitelist.lua @@ -4,8 +4,8 @@ end function HandleRequest_WhiteList( Request ) local UpdateMessage = "" - if( Request.PostParams:get("whitelist-add") ~= "" ) then - local PlayerName = Request.PostParams:get("whitelist-add") + if( Request.PostParams["whitelist-add"] ~= nil ) then + local PlayerName = Request.PostParams["whitelist-add"] if( WhiteListIni:GetValueB("WhiteList", PlayerName, false) == true ) then UpdateMessage = "".. PlayerName.." is already on the whitelist" @@ -14,18 +14,18 @@ function HandleRequest_WhiteList( Request ) UpdateMessage = "Added " .. PlayerName .. " to whitelist." WhiteListIni:WriteFile() end - elseif( Request.PostParams:get("whitelist-delete") ~= "" ) then - local PlayerName = Request.PostParams:get("whitelist-delete") + elseif( Request.PostParams["whitelist-delete"] ~= nil ) then + local PlayerName = Request.PostParams["whitelist-delete"] WhiteListIni:DeleteValue( "WhiteList", PlayerName ) UpdateMessage = "Removed " .. PlayerName .. " from whitelist." WhiteListIni:WriteFile() - elseif( Request.PostParams:get("whitelist-reload") ~= "" ) then + elseif( Request.PostParams["whitelist-reload"] ~= nil ) then WhiteListIni:Erase() -- Empty entire loaded ini first, otherwise weird shit goes down WhiteListIni:ReadFile() UpdateMessage = "Loaded from disk" - elseif( Request.Params:get("whitelist-setenable") ~= "" ) then - local Enabled = Request.Params:get("whitelist-setenable"); - local CreateNewValue = false; + elseif( Request.Params["whitelist-setenable"] ~= nil ) then + local Enabled = Request.Params["whitelist-setenable"] + local CreateNewValue = false if( WhiteListIni:FindValue( WhiteListIni:FindKey("WhiteListSettings"), "WhiteListOn" ) == cIniFile.noID ) then -- Find out whether the value is in the ini CreateNewValue = true end diff --git a/WebServer/WebServer.cpp b/WebServer/WebServer.cpp index 5de1385a2..3a2b6fbef 100644 --- a/WebServer/WebServer.cpp +++ b/WebServer/WebServer.cpp @@ -49,6 +49,206 @@ webserver::request_func webserver::request_func_=0; +static std::vector< std::string > StringSplit(std::string str, std::string delim) +{ + std::vector< std::string > results; + size_t cutAt; + while( (cutAt = str.find_first_of(delim)) != str.npos ) + { + if(cutAt > 0) + { + results.push_back(str.substr(0,cutAt)); + } + str = str.substr(cutAt+1); + } + if(str.length() > 0) + { + results.push_back(str); + } + return results; +} + +static std::string EatLine( std::string& a_String ) +{ + std::string RetVal = ""; + unsigned int StringSize = a_String.size(); + const char* c = a_String.c_str(); + + for( unsigned int i = 0; i < StringSize; ++i, ++c) + { + if( *c == '\n' ) + { + RetVal += *c; +// ++i; ++c; +// if( i < StringSize ) +// { +// if( *c == '\r' ) +// { +// RetVal += *c; +// } +// } + break; + } + RetVal += *c; + } + a_String = a_String.substr( RetVal.size() ); + return RetVal; +} + +// Turns +// "blabla my string with \"quotes\"!" +// into +// blabla my string with "quotes"! +static std::string GetQuotedString( const std::string& a_String ) +{ + std::string RetVal; + + bool bGotFirstQuote = false; + bool bIgnoreNext = false; + unsigned int StrLen = a_String.size(); + for( unsigned int i = 0; i < StrLen; ++i ) + { + if( bIgnoreNext == false ) + { + if( a_String[i] == '\"' ) + { + if( bGotFirstQuote == false ) + { + bGotFirstQuote = true; + } + else + { + break; + } + continue; + } + else if( a_String[i] == '\\' ) // Escape character + { + bIgnoreNext = true; + continue; + } + } + RetVal.push_back( a_String[i] ); + bIgnoreNext = false; + } + + return RetVal; +} + +void ParseMultipartFormData( webserver::http_request& req, Socket* s) +{ + static const std::string multipart_form_data = "multipart/form-data"; + if(req.content_type_.substr(0, multipart_form_data.size()) == multipart_form_data) // Difficult data... :( + { + typedef std::vector< std::string > StringVector; + StringVector ContentTypeData = StringSplit( req.content_type_, "; " ); + + std::string boundary; + // Find boundary + for( unsigned int i = 0; i < ContentTypeData.size(); ++i ) + { + static const std::string boundary_ = "boundary="; + if( ContentTypeData[i].substr(0, boundary_.size()) == boundary_ ) // Found boundary + { + boundary = ContentTypeData[i].substr( boundary_.size() ); + } + } + + //LOGINFO("Boundary: %s", boundary.c_str() ); + std::string boundary_start = "--" + boundary; + std::string boundary_end = boundary_start + "--"; + + std::string Content = s->ReceiveBytes( req.content_length_ ); + + //printf("Total content: \n%s\n", Content.c_str() ); + + // Should start with boundary! + std::string line = EatLine( Content ); + if( line.substr(0, boundary_start.size() ) != boundary_start ) + { + // Something was wrong! :( + Content.clear(); + } + + while( !Content.empty() ) + { + webserver::formdata FormData; + + static const std::string content_disposition = "Content-Disposition: "; + static const std::string content_type = "Content-Type: "; + + std::string f_disposition; + + while( 1 ) + { + std::string line = EatLine( Content ); + if( line.empty() ) + break; + + unsigned int pos_cr_lf = line.find_first_of("\x0a\x0d"); + if (pos_cr_lf == 0) break; // Empty line, indicates end of mime thingy + + if( line.substr(0, content_disposition.size() ) == content_disposition ) + { + f_disposition = line.substr(content_disposition.size()); + LOGINFO("Disposition: %s", f_disposition.c_str() ); + } + else if( line.substr(0, content_type.size() ) == content_type ) + { + FormData.content_type_ = line.substr(content_type.size()); + } + + //LOGINFO("Got line: '%s'", line.c_str() ); + } + + // Check if we got the proper headers + if( !f_disposition.empty() ) + { + static const std::string disp_name = "name="; + static const std::string disp_filename = "filename="; + + // Parse the disposition + StringVector DispositionData = StringSplit( f_disposition, "; " ); + for( unsigned int i = 0; i < DispositionData.size(); ++i ) + { + if( DispositionData[i].substr(0, disp_name.size()) == disp_name ) + { + FormData.name_ = GetQuotedString( DispositionData[i].substr(disp_name.size()) ); + } + else if( DispositionData[i].substr(0, disp_filename.size()) == disp_filename ) + { + FormData.filename_ = GetQuotedString( DispositionData[i].substr(disp_filename.size()) ); + } + } + + std::string ContentValue; + // Parse until boundary_end is found + while( 1 ) + { + std::string line = EatLine( Content ); + if( line.empty() ) + break; + + if( line.substr(0, boundary_end.size() ) == boundary_end ) + { + break; + } + else if( line.substr(0, boundary_start.size() ) == boundary_start ) + { + break; + } + ContentValue.append( line.c_str(), line.size() ); + } + + + FormData.value_ = ContentValue; + } + + req.multipart_formdata_.push_back( FormData ); + } + } +} + #ifdef _WIN32 unsigned webserver::Request(void* ptr_s) #else @@ -99,7 +299,10 @@ void* webserver::Request(void* ptr_s) while(1) { line=s->ReceiveLine(); - if (line.empty()) break; + if (line.empty()) + { + break; + } unsigned int pos_cr_lf = line.find_first_of("\x0a\x0d"); if (pos_cr_lf == 0) break; @@ -143,22 +346,23 @@ void* webserver::Request(void* ptr_s) } } - if( req.method_.compare("POST") == 0 ) + if( (req.method_.compare("POST") == 0) && (req.content_length_ > 0) ) { - if( req.content_length_ > 0 ) + // The only content type we can parse at the moment, the default HTML post data + if( req.content_type_.compare( "application/x-www-form-urlencoded" ) == 0 ) { - // The only content type we can parse at the moment, the default HTML post data - if( req.content_type_.compare( "application/x-www-form-urlencoded" ) == 0 ) - { - std::string Content = s->ReceiveBytes( req.content_length_ ); - Content.insert( 0, "/ ?" ); // Little hack, inserts dummy URL so that SplitGetReq() can work with this content + std::string Content = s->ReceiveBytes( req.content_length_ ); + Content.insert( 0, "/ ?" ); // Little hack, inserts dummy URL so that SplitGetReq() can work with this content - std::string dummy; - std::map post_params; - SplitGetReq(Content, dummy, post_params); + std::string dummy; + std::map post_params; + SplitGetReq(Content, dummy, post_params); - req.params_post_ = post_params; - } + req.params_post_ = post_params; + } + else + { + ParseMultipartFormData( req, s ); } } diff --git a/WebServer/WebServer.h b/WebServer/WebServer.h index a78fc44e4..90b38d407 100644 --- a/WebServer/WebServer.h +++ b/WebServer/WebServer.h @@ -36,6 +36,14 @@ class Socket; class SocketServer; class webserver { public: + struct formdata + { + std::string name_; + std::string filename_; + std::string content_type_; + std::string value_; + }; + struct http_request { http_request() @@ -56,6 +64,7 @@ public: std::string user_agent_; int content_length_; std::string content_type_; + std::vector< formdata > multipart_formdata_; /* status_: used to transmit server's error status, such as o 202 OK diff --git a/source/Bindings.cpp b/source/Bindings.cpp index 6462036be..45008bb32 100644 --- a/source/Bindings.cpp +++ b/source/Bindings.cpp @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 01/31/12 01:23:11. +** Generated automatically by tolua++-1.0.92 on 01/31/12 19:40:39. */ #ifndef __cplusplus @@ -164,53 +164,54 @@ static void tolua_reg_types (lua_State* tolua_S) tolua_usertype(tolua_S,"TakeDamageInfo"); tolua_usertype(tolua_S,"cPlugin"); tolua_usertype(tolua_S,"cStringMap"); + tolua_usertype(tolua_S,"Lua__cEntity"); tolua_usertype(tolua_S,"Json::Value"); tolua_usertype(tolua_S,"cInventory"); tolua_usertype(tolua_S,"cRoot"); - tolua_usertype(tolua_S,"Lua__cPickup"); tolua_usertype(tolua_S,"Lua__cPacket_BlockDig"); + tolua_usertype(tolua_S,"Lua__cTCPLink"); tolua_usertype(tolua_S,"cWorld"); tolua_usertype(tolua_S,"cPlugin::CommandStruct"); tolua_usertype(tolua_S,"cPickup"); - tolua_usertype(tolua_S,"Vector3i"); + tolua_usertype(tolua_S,"cGroup"); tolua_usertype(tolua_S,"cPacket_Login"); tolua_usertype(tolua_S,"cClientHandle"); - tolua_usertype(tolua_S,"cGroup"); - tolua_usertype(tolua_S,"cFurnaceRecipe"); tolua_usertype(tolua_S,"cTracer"); - tolua_usertype(tolua_S,"cChatColor"); + tolua_usertype(tolua_S,"cFurnaceRecipe"); tolua_usertype(tolua_S,"cMCLogger"); + tolua_usertype(tolua_S,"cChatColor"); + tolua_usertype(tolua_S,"cCuboid"); tolua_usertype(tolua_S,"cPacket_PickupSpawn"); tolua_usertype(tolua_S,"Lua__cWebPlugin"); tolua_usertype(tolua_S,"Lua__cPawn"); - tolua_usertype(tolua_S,"cCuboid"); + tolua_usertype(tolua_S,"Vector3i"); tolua_usertype(tolua_S,"cItem"); tolua_usertype(tolua_S,"Vector3f"); tolua_usertype(tolua_S,"cPlugin_Lua"); tolua_usertype(tolua_S,"cWebPlugin_Lua"); - tolua_usertype(tolua_S,"Lua__cPlayer"); + tolua_usertype(tolua_S,"Lua__cPlugin_NewLua"); tolua_usertype(tolua_S,"cPacket"); tolua_usertype(tolua_S,"cPacket_BlockDig"); tolua_usertype(tolua_S,"cWebAdmin"); - tolua_usertype(tolua_S,"Lua__cTCPLink"); - tolua_usertype(tolua_S,"cBlockEntity"); tolua_usertype(tolua_S,"cTCPLink"); + tolua_usertype(tolua_S,"cBlockEntity"); tolua_usertype(tolua_S,"cRecipeChecker"); - tolua_usertype(tolua_S,"Lua__cPlugin"); tolua_usertype(tolua_S,"cGroupManager"); + tolua_usertype(tolua_S,"Lua__cPlugin"); + tolua_usertype(tolua_S,"Lua__cPickup"); tolua_usertype(tolua_S,"cPacket_BlockPlace"); tolua_usertype(tolua_S,"cLadder"); - tolua_usertype(tolua_S,"Lua__cPlugin_NewLua"); tolua_usertype(tolua_S,"cPluginManager"); + tolua_usertype(tolua_S,"Lua__cPlayer"); tolua_usertype(tolua_S,"cIniFile"); - tolua_usertype(tolua_S,"Lua__cEntity"); + tolua_usertype(tolua_S,"cWebPlugin"); tolua_usertype(tolua_S,"HTTPRequest"); tolua_usertype(tolua_S,"cPawn"); tolua_usertype(tolua_S,"cPlayer"); tolua_usertype(tolua_S,"cTorch"); tolua_usertype(tolua_S,"cEntity"); - tolua_usertype(tolua_S,"cWebPlugin"); tolua_usertype(tolua_S,"cPlugin_NewLua"); + tolua_usertype(tolua_S,"HTTPFormData"); tolua_usertype(tolua_S,"cServer"); tolua_usertype(tolua_S,"cStairs"); tolua_usertype(tolua_S,"Vector3d"); @@ -10363,6 +10364,96 @@ static int tolua_set_cItem_m_ItemHealth(lua_State* tolua_S) } #endif //#ifndef TOLUA_DISABLE +/* get function: Name of class HTTPFormData */ +#ifndef TOLUA_DISABLE_tolua_get_HTTPFormData_Name +static int tolua_get_HTTPFormData_Name(lua_State* tolua_S) +{ + HTTPFormData* self = (HTTPFormData*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Name'",NULL); +#endif + tolua_pushcppstring(tolua_S,(const char*)self->Name); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: Name of class HTTPFormData */ +#ifndef TOLUA_DISABLE_tolua_set_HTTPFormData_Name +static int tolua_set_HTTPFormData_Name(lua_State* tolua_S) +{ + HTTPFormData* self = (HTTPFormData*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Name'",NULL); + if (!tolua_iscppstring(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->Name = ((std::string) tolua_tocppstring(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: Value of class HTTPFormData */ +#ifndef TOLUA_DISABLE_tolua_get_HTTPFormData_Value +static int tolua_get_HTTPFormData_Value(lua_State* tolua_S) +{ + HTTPFormData* self = (HTTPFormData*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Value'",NULL); +#endif + tolua_pushcppstring(tolua_S,(const char*)self->Value); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: Value of class HTTPFormData */ +#ifndef TOLUA_DISABLE_tolua_set_HTTPFormData_Value +static int tolua_set_HTTPFormData_Value(lua_State* tolua_S) +{ + HTTPFormData* self = (HTTPFormData*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Value'",NULL); + if (!tolua_iscppstring(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->Value = ((std::string) tolua_tocppstring(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: Type of class HTTPFormData */ +#ifndef TOLUA_DISABLE_tolua_get_HTTPFormData_Type +static int tolua_get_HTTPFormData_Type(lua_State* tolua_S) +{ + HTTPFormData* self = (HTTPFormData*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Type'",NULL); +#endif + tolua_pushcppstring(tolua_S,(const char*)self->Type); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: Type of class HTTPFormData */ +#ifndef TOLUA_DISABLE_tolua_set_HTTPFormData_Type +static int tolua_set_HTTPFormData_Type(lua_State* tolua_S) +{ + HTTPFormData* self = (HTTPFormData*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Type'",NULL); + if (!tolua_iscppstring(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); +#endif + self->Type = ((std::string) tolua_tocppstring(tolua_S,2,0)) +; + return 0; +} +#endif //#ifndef TOLUA_DISABLE + /* get function: Method of class HTTPRequest */ #ifndef TOLUA_DISABLE_tolua_get_HTTPRequest_Method static int tolua_get_HTTPRequest_Method(lua_State* tolua_S) @@ -10423,66 +10514,6 @@ static int tolua_set_HTTPRequest_Path(lua_State* tolua_S) } #endif //#ifndef TOLUA_DISABLE -/* get function: Params of class HTTPRequest */ -#ifndef TOLUA_DISABLE_tolua_get_HTTPRequest_Params_ptr -static int tolua_get_HTTPRequest_Params_ptr(lua_State* tolua_S) -{ - HTTPRequest* self = (HTTPRequest*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Params'",NULL); -#endif - tolua_pushusertype(tolua_S,(void*)self->Params,"cStringMap"); - return 1; -} -#endif //#ifndef TOLUA_DISABLE - -/* set function: Params of class HTTPRequest */ -#ifndef TOLUA_DISABLE_tolua_set_HTTPRequest_Params_ptr -static int tolua_set_HTTPRequest_Params_ptr(lua_State* tolua_S) -{ - HTTPRequest* self = (HTTPRequest*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Params'",NULL); - if (!tolua_isusertype(tolua_S,2,"cStringMap",0,&tolua_err)) - tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); -#endif - self->Params = ((cStringMap*) tolua_tousertype(tolua_S,2,0)) -; - return 0; -} -#endif //#ifndef TOLUA_DISABLE - -/* get function: PostParams of class HTTPRequest */ -#ifndef TOLUA_DISABLE_tolua_get_HTTPRequest_PostParams_ptr -static int tolua_get_HTTPRequest_PostParams_ptr(lua_State* tolua_S) -{ - HTTPRequest* self = (HTTPRequest*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'PostParams'",NULL); -#endif - tolua_pushusertype(tolua_S,(void*)self->PostParams,"cStringMap"); - return 1; -} -#endif //#ifndef TOLUA_DISABLE - -/* set function: PostParams of class HTTPRequest */ -#ifndef TOLUA_DISABLE_tolua_set_HTTPRequest_PostParams_ptr -static int tolua_set_HTTPRequest_PostParams_ptr(lua_State* tolua_S) -{ - HTTPRequest* self = (HTTPRequest*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'PostParams'",NULL); - if (!tolua_isusertype(tolua_S,2,"cStringMap",0,&tolua_err)) - tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err); -#endif - self->PostParams = ((cStringMap*) tolua_tousertype(tolua_S,2,0)) -; - return 0; -} -#endif //#ifndef TOLUA_DISABLE - /* get function: Username of class HTTPRequest */ #ifndef TOLUA_DISABLE_tolua_get_HTTPRequest_Username static int tolua_get_HTTPRequest_Username(lua_State* tolua_S) @@ -17026,12 +17057,16 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_variable(tolua_S,"m_ItemCount",tolua_get_cItem_m_ItemCount,tolua_set_cItem_m_ItemCount); tolua_variable(tolua_S,"m_ItemHealth",tolua_get_cItem_m_ItemHealth,tolua_set_cItem_m_ItemHealth); tolua_endmodule(tolua_S); + tolua_cclass(tolua_S,"HTTPFormData","HTTPFormData","",NULL); + tolua_beginmodule(tolua_S,"HTTPFormData"); + tolua_variable(tolua_S,"Name",tolua_get_HTTPFormData_Name,tolua_set_HTTPFormData_Name); + tolua_variable(tolua_S,"Value",tolua_get_HTTPFormData_Value,tolua_set_HTTPFormData_Value); + tolua_variable(tolua_S,"Type",tolua_get_HTTPFormData_Type,tolua_set_HTTPFormData_Type); + tolua_endmodule(tolua_S); tolua_cclass(tolua_S,"HTTPRequest","HTTPRequest","",NULL); tolua_beginmodule(tolua_S,"HTTPRequest"); tolua_variable(tolua_S,"Method",tolua_get_HTTPRequest_Method,tolua_set_HTTPRequest_Method); tolua_variable(tolua_S,"Path",tolua_get_HTTPRequest_Path,tolua_set_HTTPRequest_Path); - tolua_variable(tolua_S,"Params",tolua_get_HTTPRequest_Params_ptr,tolua_set_HTTPRequest_Params_ptr); - tolua_variable(tolua_S,"PostParams",tolua_get_HTTPRequest_PostParams_ptr,tolua_set_HTTPRequest_PostParams_ptr); tolua_variable(tolua_S,"Username",tolua_get_HTTPRequest_Username,tolua_set_HTTPRequest_Username); tolua_endmodule(tolua_S); #ifdef __cplusplus diff --git a/source/Bindings.h b/source/Bindings.h index 6e1a7b46c..061f9231e 100644 --- a/source/Bindings.h +++ b/source/Bindings.h @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 01/31/12 01:23:11. +** Generated automatically by tolua++-1.0.92 on 01/31/12 19:40:39. */ /* Exported function */ diff --git a/source/ManualBindings.cpp b/source/ManualBindings.cpp index 06a148b91..7e2e45855 100644 --- a/source/ManualBindings.cpp +++ b/source/ManualBindings.cpp @@ -11,6 +11,8 @@ #include "cWebPlugin_Lua.h" #include "cLuaCommandBinder.h" #include "cPlayer.h" +#include "cWebAdmin.h" +#include "cStringMap.h" #include "md5/md5.h" extern std::vector StringSplit(std::string str, std::string delim); @@ -266,6 +268,54 @@ static int tolua_md5(lua_State* tolua_S) return 1; } +static int tolua_push_StringStringMap(lua_State* tolua_S, std::map< std::string, std::string >& a_StringStringMap ) +{ + lua_newtable(tolua_S); + int top = lua_gettop(tolua_S); + + for( std::map< std::string, std::string >::iterator it = a_StringStringMap.begin(); it != a_StringStringMap.end(); ++it ) + { + const char* key = it->first.c_str(); + const char* value = it->second.c_str(); + lua_pushstring(tolua_S, key); + lua_pushstring(tolua_S, value); + lua_settable(tolua_S, top); + } + + return 1; +} + +static int tolua_get_HTTPRequest_Params(lua_State* tolua_S) +{ + HTTPRequest* self = (HTTPRequest*) tolua_tousertype(tolua_S,1,0); + return tolua_push_StringStringMap(tolua_S, self->Params); +} + +static int tolua_get_HTTPRequest_PostParams(lua_State* tolua_S) +{ + HTTPRequest* self = (HTTPRequest*) tolua_tousertype(tolua_S,1,0); + return tolua_push_StringStringMap(tolua_S, self->PostParams); +} + +static int tolua_get_HTTPRequest_FormData(lua_State* tolua_S) +{ + HTTPRequest* self = (HTTPRequest*) tolua_tousertype(tolua_S,1,0); + std::map< std::string, HTTPFormData >& FormData = self->FormData; + + lua_newtable(tolua_S); + int top = lua_gettop(tolua_S); + + for( std::map< std::string, HTTPFormData >::iterator it = FormData.begin(); it != FormData.end(); ++it ) + { + lua_pushstring(tolua_S, it->first.c_str() ); + tolua_pushusertype(tolua_S, &(it->second), "HTTPFormData" ); + //lua_pushlstring(tolua_S, it->second.Value.c_str(), it->second.Value.size() ); // Might contain binary data + lua_settable(tolua_S, top); + } + + return 1; +} + void ManualBindings::Bind( lua_State* tolua_S ) { tolua_beginmodule(tolua_S,NULL); @@ -293,6 +343,15 @@ void ManualBindings::Bind( lua_State* tolua_S ) tolua_beginmodule(tolua_S,"cWebPlugin_Lua"); tolua_function(tolua_S,"AddTab",tolua_cWebPlugin_Lua_AddTab); tolua_endmodule(tolua_S); + + tolua_cclass(tolua_S,"HTTPRequest","HTTPRequest","",NULL); + tolua_beginmodule(tolua_S,"HTTPRequest"); + //tolua_variable(tolua_S,"Method",tolua_get_HTTPRequest_Method,tolua_set_HTTPRequest_Method); + //tolua_variable(tolua_S,"Path",tolua_get_HTTPRequest_Path,tolua_set_HTTPRequest_Path); + tolua_variable(tolua_S,"Params",tolua_get_HTTPRequest_Params,0); + tolua_variable(tolua_S,"PostParams",tolua_get_HTTPRequest_PostParams,0); + tolua_variable(tolua_S,"FormData",tolua_get_HTTPRequest_FormData,0); + tolua_endmodule(tolua_S); tolua_function(tolua_S,"md5",tolua_md5); diff --git a/source/cPlayer.h b/source/cPlayer.h index c05600f80..d18e3ac4f 100644 --- a/source/cPlayer.h +++ b/source/cPlayer.h @@ -68,7 +68,7 @@ public: bool CanUseCommand( const char* a_Command ); //tolua_export bool HasPermission( const char* a_Permission ); //tolua_export const GroupList & GetGroups(); // >> EXPORTED IN MANUALBINDINGS << - StringList GetResolvedPermissions(); // >> EXPORTED IN MANUALBINDINGS << + StringList GetResolvedPermissions(); // >> EXPORTED IN MANUALBINDINGS << bool IsInGroup( const char* a_Group ); //tolua_export std::string GetColor(); //tolua_export diff --git a/source/cStringMap.h b/source/cStringMap.h index 454218cf4..e6b61c171 100644 --- a/source/cStringMap.h +++ b/source/cStringMap.h @@ -18,6 +18,8 @@ public: // tolua_export unsigned int size() const; // tolua_export std::string & get( const std::string & index ); //tolua_export + + std::map< std::string, std::string >& GetStringMap() { return m_StringMap; } private: std::map< std::string, std::string > m_StringMap; }; // tolua_export diff --git a/source/cWebAdmin.cpp b/source/cWebAdmin.cpp index 002505c1f..b99b8e779 100644 --- a/source/cWebAdmin.cpp +++ b/source/cWebAdmin.cpp @@ -136,10 +136,22 @@ void cWebAdmin::Request_Handler(webserver::http_request* r) HTTPRequest Request; Request.Username = r->username_; Request.Method = r->method_; - Request.Params = new cStringMap(r->params_); - Request.PostParams = new cStringMap(r->params_post_); + Request.Params = r->params_; + Request.PostParams = r->params_post_; Request.Path = r->path_; + for( unsigned int i = 0; i < r->multipart_formdata_.size(); ++i ) + { + webserver::formdata& fd = r->multipart_formdata_[i]; + + HTTPFormData HTTPfd;//( fd.value_ ); + HTTPfd.Value = fd.value_; + HTTPfd.Type = fd.content_type_; + HTTPfd.Name = fd.name_; + LOGINFO("Form data name: %s", fd.name_.c_str() ); + Request.FormData[ fd.name_ ] = HTTPfd; + } + if( Split.size() > 1 ) { for( PluginList::iterator itr = WebAdmin->m_Plugins.begin(); itr != WebAdmin->m_Plugins.end(); ++itr ) @@ -159,9 +171,6 @@ void cWebAdmin::Request_Handler(webserver::http_request* r) } } - delete Request.Params; - delete Request.PostParams; - if( FoundPlugin.empty() ) // Default page { Content.clear(); diff --git a/source/cWebAdmin.h b/source/cWebAdmin.h index da60a5492..3be9426ad 100644 --- a/source/cWebAdmin.h +++ b/source/cWebAdmin.h @@ -4,16 +4,25 @@ #include "cSocket.h" class cStringMap; -//tolua_begin -struct HTTPRequest -{ - std::string Method; - std::string Path; - cStringMap* Params; - cStringMap* PostParams; - std::string Username; -}; -//tolua_end + +struct HTTPFormData //tolua_export +{ //tolua_export + std::string Name; //tolua_export + std::string Value; //tolua_export + std::string Type; //tolua_export +};//tolua_export + +struct HTTPRequest //tolua_export +{ //tolua_export + typedef std::map< std::string, std::string > StringStringMap; + typedef std::map< std::string, HTTPFormData > FormDataMap; + std::string Method; //tolua_export + std::string Path; //tolua_export + StringStringMap Params; // >> EXPORTED IN MANUALBINDINGS << + StringStringMap PostParams; // >> EXPORTED IN MANUALBINDINGS << + std::string Username; //tolua_export + FormDataMap FormData; // >> EXPORTED IN MANUALBINDINGS << +}; //tolua_export struct lua_State; class cEvent;