X-Git-Url: https://git.pterodactylus.net/?a=blobdiff_plain;f=src%2Fhttp%2Fipagehandler.cpp;h=3565aabb20707637d88160a6e6f604b764996f25;hb=ee580d19b7920904587e18d72a3465d52eab6204;hp=230da65e55e04491936e56f65a5726d5aba2f579;hpb=d8ccfe2b3944adf07d35534459cdda19d15217c8;p=fms.git diff --git a/src/http/ipagehandler.cpp b/src/http/ipagehandler.cpp index 230da65..3565aab 100644 --- a/src/http/ipagehandler.cpp +++ b/src/http/ipagehandler.cpp @@ -6,6 +6,31 @@ #include #endif +void IPageHandler::CreateArgArray(const std::map &vars, const std::string &basename, std::vector &args) +{ + for(std::map::const_iterator i=vars.begin(); i!=vars.end(); i++) + { + if((*i).first.find(basename)==0 && (*i).first.find("[")!=std::string::npos && (*i).first.find("]")!=std::string::npos) + { + int index=0; + std::string indexstr; + std::string::size_type startpos; + std::string::size_type endpos; + startpos=(*i).first.find("["); + endpos=(*i).first.find("]"); + + indexstr=(*i).first.substr(startpos+1,(endpos-startpos)-1); + StringFunctions::Convert(indexstr,index); + + while(args.size()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) { @@ -34,7 +81,8 @@ const bool IPageHandler::Handle(shttpd_arg *arg) { long len; StringFunctions::Convert(std::string(lenstr),len); - mystate->m_indata=new char[len]; + mystate->m_indata=new char[len+1]; + mystate->m_indata[len]='\0'; mystate->m_indatalen=len; mystate->m_indatapos=0; } @@ -45,7 +93,7 @@ const bool IPageHandler::Handle(shttpd_arg *arg) if(arg->in.len>0) { int pos=0; - while(arg->in.num_bytesin.len) + while(posin.len) { mystate->m_indata[mystate->m_indatapos++]=arg->in.buf[pos++]; } @@ -55,8 +103,53 @@ const bool IPageHandler::Handle(shttpd_arg *arg) // we have all POST data (or it was 0 to begin with) - generate the page if(mystate->m_indatalen==mystate->m_indatapos && mystate->m_outdata==NULL) { - //TODO parse POST data and any QUERY_STRING before generating page - std::string page=GeneratePage(methodstr,std::map()); + //parse POST data and any QUERY_STRING before generating page + std::map args; + std::vector argparts; + std::string contenttype=""; + + if(shttpd_get_header(arg,"Content-Type")) + { + contenttype=shttpd_get_header(arg,"Content-Type"); + } + + if(contenttype.find("multipart/form-data")!=std::string::npos) + { + HandleMultiPartData(contenttype,mystate->m_indata,mystate->m_indatalen,args); + } + else + { + // split apart non-multipart POST + if(mystate->m_indata) + { + 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[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]); + } + } + } + } + + std::string page=GeneratePage(methodstr,args); mystate->m_outdata=new char[page.size()]; memcpy(mystate->m_outdata,page.c_str(),page.size()); mystate->m_outdatalen=page.size(); @@ -79,11 +172,11 @@ const bool IPageHandler::Handle(shttpd_arg *arg) { if(mystate->m_indata) { - delete mystate->m_indata; + delete [] mystate->m_indata; } if(mystate->m_outdata) { - delete mystate->m_outdata; + delete [] mystate->m_outdata; } delete mystate; arg->state=NULL; @@ -98,3 +191,81 @@ const bool IPageHandler::Handle(shttpd_arg *arg) return false; } } + +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! + std::string output=StringFunctions::Replace(input,"&","&"); + output=StringFunctions::Replace(output,"<","<"); + output=StringFunctions::Replace(output,">",">"); + output=StringFunctions::Replace(output,"\"","""); + output=StringFunctions::Replace(output," "," "); + return output; +}