X-Git-Url: https://git.pterodactylus.net/?p=fms.git;a=blobdiff_plain;f=src%2Fhttp%2Fipagehandler.cpp;h=f4ac20f0109f73226f72323ebe3654d813fd719d;hp=c4ebbb9c2aceb469754fcc0b745d82e7d3af81b8;hb=f60495a029c54358f82956482fe203fe2b7b5b23;hpb=b9c3763a932cebaa015a27fe111017f6f34dfbaa diff --git a/src/http/ipagehandler.cpp b/src/http/ipagehandler.cpp index c4ebbb9..f4ac20f 100644 --- a/src/http/ipagehandler.cpp +++ b/src/http/ipagehandler.cpp @@ -44,6 +44,28 @@ const bool IPageHandler::Handle(shttpd_arg *arg) if(uri && WillHandleURI(std::string(uri))) { httpstate *mystate=(httpstate *)arg->state; + + // first check if there was a connection error - if so delete the input/output and state buffers and return immediately + if((arg->flags & SHTTPD_CONNECTION_ERROR)==SHTTPD_CONNECTION_ERROR) + { + if(mystate && mystate->m_indata) + { + delete mystate->m_indata; + mystate->m_indata=NULL; + } + if(mystate && mystate->m_outdata) + { + delete mystate->m_outdata; + mystate->m_outdata=NULL; + } + if(mystate) + { + delete mystate; + mystate=NULL; + } + return true; + } + // this is a new request - create a new arg object if(arg->state==NULL) { @@ -84,29 +106,45 @@ const bool IPageHandler::Handle(shttpd_arg *arg) //parse POST data and any QUERY_STRING before generating page std::map args; std::vector argparts; + std::string contenttype=""; - if(mystate->m_indata) + if(shttpd_get_header(arg,"Content-Type")) { - StringFunctions::Split(mystate->m_indata,"&",argparts); + contenttype=shttpd_get_header(arg,"Content-Type"); } - if(shttpd_get_env(arg,"QUERY_STRING")) + + if(contenttype.find("multipart/form-data")!=std::string::npos) { - StringFunctions::Split(shttpd_get_env(arg,"QUERY_STRING"),"&",argparts); + HandleMultiPartData(contenttype,mystate->m_indata,mystate->m_indatalen,args); } - for(std::vector::iterator argi=argparts.begin(); argi!=argparts.end(); argi++) + else { - std::vector parts; - StringFunctions::Split((*argi),"=",parts); - if(parts.size()>0) + // split apart non-multipart POST + if(mystate->m_indata) { - // replace + with space before UriDecoding - parts[0]=StringFunctions::Replace(parts[0],"+"," "); - args[StringFunctions::UriDecode(parts[0])]; - if(parts.size()>1) + StringFunctions::Split(mystate->m_indata,"&",argparts); + } + // split apart query string + if(shttpd_get_env(arg,"QUERY_STRING")) + { + StringFunctions::Split(shttpd_get_env(arg,"QUERY_STRING"),"&",argparts); + } + + for(std::vector::iterator argi=argparts.begin(); argi!=argparts.end(); argi++) + { + std::vector parts; + StringFunctions::Split((*argi),"=",parts); + if(parts.size()>0) { // replace + with space before UriDecoding - parts[1]=StringFunctions::Replace(parts[1],"+"," "); - args[StringFunctions::UriDecode(parts[0])]=StringFunctions::UriDecode(parts[1]); + parts[0]=StringFunctions::Replace(parts[0],"+"," "); + args[StringFunctions::UriDecode(parts[0])]; + if(parts.size()>1) + { + // replace + with space before UriDecoding + parts[1]=StringFunctions::Replace(parts[1],"+"," "); + args[StringFunctions::UriDecode(parts[0])]=StringFunctions::UriDecode(parts[1]); + } } } } @@ -154,6 +192,73 @@ const bool IPageHandler::Handle(shttpd_arg *arg) } } +void IPageHandler::HandleMultiPartData(const std::string &contenttypeheader, char *data, const long datalen, std::map &args) +{ + if(data) + { + std::string datastr(data,data+datalen); + std::vector parts; + std::string boundary=""; + std::string::size_type pos=contenttypeheader.find("boundary="); + + // find boundary + if(pos!=std::string::npos) + { + boundary=contenttypeheader.substr(pos+9); + // strip off any " and ; + boundary=StringFunctions::Replace(boundary,"\"",""); + boundary=StringFunctions::Replace(boundary,";",""); + } + + // split into parts separated by boundary + StringFunctions::Split(datastr,"--"+boundary+"\r\n",parts); + + // go through each part and get name=value + for(std::vector::iterator i=parts.begin(); i!=parts.end(); i++) + { + std::string data=""; + std::string name=""; + + // find name + pos=(*i).find("name="); + if(pos!=std::string::npos) + { + std::string::size_type pos2=(*i).find(";",pos); + if(pos2!=std::string::npos) + { + name=(*i).substr(pos+5,pos2-(pos+5)); + } + else + { + pos2=(*i).find("\r\n",pos); + if(pos2!=std::string::npos) + { + name=(*i).substr(pos+5,pos2-(pos+5)); + } + } + + name=StringFunctions::Replace(name,"\"",""); + } + + // find header boundary + pos=(*i).find("\r\n\r\n"); + if(pos!=std::string::npos) + { + data=(*i).substr(pos+4); + // strip off final \r\n from data + if(data.size()>2 && data.rfind("\r\n")==data.size()-2) + { + data.erase(data.size()-2); + } + } + if(name!="" && data!="") + { + args[name]=data; + } + } + } +} + const std::string IPageHandler::SanitizeOutput(const std::string &input) { // must do & first because all other elements have & in them!