if(uri && WillHandleURI(std::string(uri)))\r
{\r
httpstate *mystate=(httpstate *)arg->state;\r
+\r
+ // first check if there was a connection error - if so delete the input/output and state buffers and return immediately\r
+ if((arg->flags & SHTTPD_CONNECTION_ERROR)==SHTTPD_CONNECTION_ERROR)\r
+ {\r
+ if(mystate && mystate->m_indata)\r
+ {\r
+ delete mystate->m_indata;\r
+ mystate->m_indata=NULL;\r
+ }\r
+ if(mystate && mystate->m_outdata)\r
+ {\r
+ delete mystate->m_outdata;\r
+ mystate->m_outdata=NULL;\r
+ }\r
+ if(mystate)\r
+ {\r
+ delete mystate;\r
+ mystate=NULL;\r
+ }\r
+ return true;\r
+ }\r
+\r
// this is a new request - create a new arg object\r
if(arg->state==NULL)\r
{\r
//parse POST data and any QUERY_STRING before generating page\r
std::map<std::string,std::string> args;\r
std::vector<std::string> argparts;\r
+ std::string contenttype="";\r
\r
- if(mystate->m_indata)\r
+ if(shttpd_get_header(arg,"Content-Type"))\r
{\r
- StringFunctions::Split(mystate->m_indata,"&",argparts);\r
+ contenttype=shttpd_get_header(arg,"Content-Type");\r
}\r
- if(shttpd_get_env(arg,"QUERY_STRING"))\r
+ \r
+ if(contenttype.find("multipart/form-data")!=std::string::npos)\r
{\r
- StringFunctions::Split(shttpd_get_env(arg,"QUERY_STRING"),"&",argparts);\r
+ HandleMultiPartData(contenttype,mystate->m_indata,mystate->m_indatalen,args);\r
}\r
- for(std::vector<std::string>::iterator argi=argparts.begin(); argi!=argparts.end(); argi++)\r
+ else\r
{\r
- std::vector<std::string> parts;\r
- StringFunctions::Split((*argi),"=",parts);\r
- if(parts.size()>0)\r
+ // split apart non-multipart POST\r
+ if(mystate->m_indata)\r
{\r
- // replace + with space before UriDecoding\r
- parts[0]=StringFunctions::Replace(parts[0],"+"," ");\r
- args[StringFunctions::UriDecode(parts[0])];\r
- if(parts.size()>1)\r
+ StringFunctions::Split(mystate->m_indata,"&",argparts);\r
+ }\r
+ // split apart query string\r
+ if(shttpd_get_env(arg,"QUERY_STRING"))\r
+ {\r
+ StringFunctions::Split(shttpd_get_env(arg,"QUERY_STRING"),"&",argparts);\r
+ }\r
+\r
+ for(std::vector<std::string>::iterator argi=argparts.begin(); argi!=argparts.end(); argi++)\r
+ {\r
+ std::vector<std::string> parts;\r
+ StringFunctions::Split((*argi),"=",parts);\r
+ if(parts.size()>0)\r
{\r
// replace + with space before UriDecoding\r
- parts[1]=StringFunctions::Replace(parts[1],"+"," ");\r
- args[StringFunctions::UriDecode(parts[0])]=StringFunctions::UriDecode(parts[1]);\r
+ parts[0]=StringFunctions::Replace(parts[0],"+"," ");\r
+ args[StringFunctions::UriDecode(parts[0])];\r
+ if(parts.size()>1)\r
+ {\r
+ // replace + with space before UriDecoding\r
+ parts[1]=StringFunctions::Replace(parts[1],"+"," ");\r
+ args[StringFunctions::UriDecode(parts[0])]=StringFunctions::UriDecode(parts[1]);\r
+ }\r
}\r
}\r
}\r
}\r
}\r
\r
+void IPageHandler::HandleMultiPartData(const std::string &contenttypeheader, char *data, const long datalen, std::map<std::string,std::string> &args)\r
+{\r
+ if(data)\r
+ {\r
+ std::string datastr(data,data+datalen);\r
+ std::vector<std::string> parts;\r
+ std::string boundary="";\r
+ std::string::size_type pos=contenttypeheader.find("boundary=");\r
+\r
+ // find boundary\r
+ if(pos!=std::string::npos)\r
+ {\r
+ boundary=contenttypeheader.substr(pos+9);\r
+ // strip off any " and ;\r
+ boundary=StringFunctions::Replace(boundary,"\"","");\r
+ boundary=StringFunctions::Replace(boundary,";","");\r
+ }\r
+\r
+ // split into parts separated by boundary\r
+ StringFunctions::Split(datastr,"--"+boundary+"\r\n",parts);\r
+\r
+ // go through each part and get name=value\r
+ for(std::vector<std::string>::iterator i=parts.begin(); i!=parts.end(); i++)\r
+ {\r
+ std::string data="";\r
+ std::string name="";\r
+\r
+ // find name\r
+ pos=(*i).find("name=");\r
+ if(pos!=std::string::npos)\r
+ {\r
+ std::string::size_type pos2=(*i).find(";",pos);\r
+ if(pos2!=std::string::npos)\r
+ {\r
+ name=(*i).substr(pos+5,pos2-(pos+5));\r
+ }\r
+ else\r
+ {\r
+ pos2=(*i).find("\r\n",pos);\r
+ if(pos2!=std::string::npos)\r
+ {\r
+ name=(*i).substr(pos+5,pos2-(pos+5));\r
+ }\r
+ }\r
+\r
+ name=StringFunctions::Replace(name,"\"","");\r
+ }\r
+\r
+ // find header boundary\r
+ pos=(*i).find("\r\n\r\n");\r
+ if(pos!=std::string::npos)\r
+ {\r
+ data=(*i).substr(pos+4);\r
+ // strip off final \r\n from data\r
+ if(data.size()>2 && data.rfind("\r\n")==data.size()-2)\r
+ {\r
+ data.erase(data.size()-2);\r
+ }\r
+ }\r
+ if(name!="" && data!="")\r
+ {\r
+ args[name]=data;\r
+ }\r
+ }\r
+ }\r
+}\r
+\r
const std::string IPageHandler::SanitizeOutput(const std::string &input)\r
{\r
// must do & first because all other elements have & in them!\r