#include "../../include/http/ipagehandler.h"\r
-#include "../../include/http/httpdefs.h"\r
#include "../../include/stringfunctions.h"\r
+#include "../../include/http/multipartparser.h"\r
+#include "../../include/db/sqlite3db.h"\r
+\r
+#include <Poco/Net/HTMLForm.h>\r
+#include <Poco/UUIDGenerator.h>\r
+#include <Poco/UUID.h>\r
+#include <Poco/DateTime.h>\r
+#include <Poco/DateTimeFormatter.h>\r
+#include <Poco/Timespan.h>\r
+\r
+#include <cstring>\r
\r
#ifdef XMEM\r
#include <xmem.h>\r
{\r
if((*i).first.find(basename)==0 && (*i).first.find("[")!=std::string::npos && (*i).first.find("]")!=std::string::npos)\r
{\r
- int index;\r
+ int index=0;\r
std::string indexstr;\r
std::string::size_type startpos;\r
std::string::size_type endpos;\r
}\r
}\r
\r
-const bool IPageHandler::Handle(shttpd_arg *arg)\r
+const std::string IPageHandler::CreateFormPassword()\r
{\r
- const char *uri=shttpd_get_env(arg,"REQUEST_URI");\r
- const char *method=shttpd_get_env(arg,"REQUEST_METHOD");\r
- std::string methodstr="";\r
- if(method)\r
+ Poco::DateTime date;\r
+ Poco::UUIDGenerator uuidgen;\r
+ Poco::UUID uuid;\r
+ try\r
{\r
- methodstr=method;\r
+ uuid=uuidgen.createRandom();\r
}\r
+ catch(...)\r
+ {\r
+ }\r
+\r
+ SQLite3DB::Statement st=SQLite3DB::DB::Instance()->Prepare("INSERT INTO tmpFormPassword(Date,Password) VALUES(?,?);");\r
+ st.Bind(0,Poco::DateTimeFormatter::format(date,"%Y-%m-%d %H:%M:%S"));\r
+ st.Bind(1,uuid.toString());\r
+ st.Step();\r
+\r
+ return "<input type=\"hidden\" name=\"formpassword\" value=\""+uuid.toString()+"\">";\r
+\r
+}\r
+\r
+const std::string IPageHandler::CreateTrueFalseDropDown(const std::string &name, const std::string &selected)\r
+{\r
+ std::string rval="";\r
\r
- if(uri && WillHandleURI(std::string(uri)))\r
+ rval+="<select name=\""+name+"\">";\r
+ rval+="<option value=\"true\"";\r
+ if(selected=="true")\r
{\r
- httpstate *mystate=(httpstate *)arg->state;\r
- // this is a new request - create a new arg object\r
- if(arg->state==NULL)\r
- {\r
- arg->state=new httpstate;\r
- memset(arg->state,0,sizeof(httpstate));\r
- mystate=(httpstate *)arg->state;\r
+ rval+=" SELECTED";\r
+ }\r
+ rval+=">true</option>";\r
+ rval+="<option value=\"false\"";\r
+ if(selected=="false")\r
+ {\r
+ rval+=" SELECTED";\r
+ }\r
+ rval+=">false</option>";\r
+ rval+="</select>";\r
\r
- // if post then create input buffer\r
- if(methodstr=="POST")\r
- {\r
- const char *lenstr=shttpd_get_header(arg,"Content-Length");\r
- if(lenstr)\r
- {\r
- long len;\r
- StringFunctions::Convert(std::string(lenstr),len);\r
- mystate->m_indata=new char[len+1];\r
- mystate->m_indata[len]=NULL;\r
- mystate->m_indatalen=len;\r
- mystate->m_indatapos=0;\r
- }\r
- }\r
- }\r
+ return rval;\r
+}\r
\r
- // we have more POST data to get\r
- if(arg->in.len>0)\r
+void IPageHandler::CreateQueryVarMap(Poco::Net::HTTPServerRequest &request, std::map<std::string,std::string> &vars)\r
+{\r
+ for(Poco::Net::HTTPServerRequest::ConstIterator i=request.begin(); i!=request.end(); i++)\r
+ {\r
+ vars[(*i).first]=(*i).second;\r
+ }\r
+\r
+ // handle HTMLForm and multiparts\r
+ MultiPartParser mpp;\r
+ Poco::Net::HTMLForm form(request,request.stream(),mpp);\r
+ for(Poco::Net::HTMLForm::ConstIterator i=form.begin(); i!=form.end(); i++)\r
+ {\r
+ vars[(*i).first]=(*i).second;\r
+ }\r
+\r
+ // for a POST method, the HTMLForm won't grab vars off the query string so we\r
+ // temporarily set the method to GET and parse with the HTMLForm again\r
+ if(request.getMethod()=="POST")\r
+ {\r
+ request.setMethod("GET");\r
+ Poco::Net::HTMLForm form1(request,request.stream(),mpp);\r
+ for(Poco::Net::HTMLForm::ConstIterator i=form1.begin(); i!=form1.end(); i++)\r
{\r
- int pos=0;\r
- while(pos<arg->in.len)\r
- {\r
- mystate->m_indata[mystate->m_indatapos++]=arg->in.buf[pos++];\r
- }\r
- arg->in.num_bytes=arg->in.len;\r
+ vars[(*i).first]=(*i).second;\r
}\r
+ request.setMethod("POST");\r
+ }\r
+\r
+ // get any multiparts\r
+ std::map<std::string,std::string> mpvars=mpp.GetVars();\r
+ for(std::map<std::string,std::string>::iterator i=mpvars.begin(); i!=mpvars.end(); i++)\r
+ {\r
+ vars[(*i).first]=(*i).second;\r
+ }\r
+\r
+}\r
+\r
+void IPageHandler::handleRequest(Poco::Net::HTTPServerRequest &request, Poco::Net::HTTPServerResponse &response)\r
+{\r
+ m_log->trace("IPageHandler::handleRequest from "+request.clientAddress().toString());\r
+\r
+ std::map<std::string,std::string> vars;\r
\r
- // we have all POST data (or it was 0 to begin with) - generate the page\r
- if(mystate->m_indatalen==mystate->m_indatapos && mystate->m_outdata==NULL)\r
+ CreateQueryVarMap(request,vars);\r
+\r
+ if(request.getVersion()==Poco::Net::HTTPRequest::HTTP_1_1)\r
+ {\r
+ response.setChunkedTransferEncoding(true);\r
+ }\r
+ response.setContentType("text/html");\r
+\r
+ std::ostream &ostr = response.send();\r
+ ostr << GeneratePage(request.getMethod(),vars);\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
+ std::string output=StringFunctions::Replace(input,"&","&");\r
+ output=StringFunctions::Replace(output,"<","<");\r
+ output=StringFunctions::Replace(output,">",">");\r
+ output=StringFunctions::Replace(output,"\"",""");\r
+ output=StringFunctions::Replace(output," "," ");\r
+ return output;\r
+}\r
+\r
+const bool IPageHandler::ValidateFormPassword(const std::map<std::string,std::string> &vars)\r
+{\r
+ Poco::DateTime date;\r
+ date-=Poco::Timespan(0,1,0,0,0);\r
+\r
+ SQLite3DB::Statement st=SQLite3DB::DB::Instance()->Prepare("DELETE FROM tmpFormPassword WHERE Date<?;");\r
+ st.Bind(0,Poco::DateTimeFormatter::format(date,"%Y-%m-%d %H:%M:%S"));\r
+ st.Step();\r
+\r
+ std::map<std::string,std::string>::const_iterator i=vars.find("formpassword");\r
+ if(i!=vars.end())\r
+ {\r
+ st=SQLite3DB::DB::Instance()->Prepare("SELECT COUNT(*) FROM tmpFormPassword WHERE Password=?;");\r
+ st.Bind(0,(*i).second);\r
+ st.Step();\r
+ if(st.RowReturned())\r
{\r
- //TODO 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
- \r
- if(mystate->m_indata)\r
+ if(st.ResultNull(0)==false)\r
{\r
- StringFunctions::Split(mystate->m_indata,"&",argparts);\r
- }\r
- if(shttpd_get_env(arg,"QUERY_STRING"))\r
- {\r
- StringFunctions::Split(shttpd_get_env(arg,"QUERY_STRING"),"&",argparts);\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
+ int rval=0;\r
+ st.ResultInt(0,rval);\r
+ if(rval>0)\r
+ {\r
+ return true;\r
+ }\r
+ else\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
- {\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
+ return false;\r
}\r
}\r
-\r
- std::string page=GeneratePage(methodstr,args);\r
- mystate->m_outdata=new char[page.size()];\r
- memcpy(mystate->m_outdata,page.c_str(),page.size());\r
- mystate->m_outdatalen=page.size();\r
- mystate->m_outdatapos=0;\r
- }\r
-\r
- // if we have output data, push next block of data onto out buffer\r
- if(mystate->m_outdata && mystate->m_outdatapos<mystate->m_outdatalen)\r
- {\r
- int pos=0;\r
- while(mystate->m_outdatapos<mystate->m_outdatalen && pos<arg->out.len)\r
+ else\r
{\r
- arg->out.buf[pos++]=mystate->m_outdata[mystate->m_outdatapos++];\r
+ return false;\r
}\r
- arg->out.num_bytes=pos;\r
}\r
-\r
- // if we have no more output data to send - delete the data pointers and set end of output flag\r
- if(mystate->m_outdata && mystate->m_outdatapos==mystate->m_outdatalen)\r
+ else\r
{\r
- if(mystate->m_indata)\r
- {\r
- delete [] mystate->m_indata;\r
- }\r
- if(mystate->m_outdata)\r
- {\r
- delete [] mystate->m_outdata;\r
- }\r
- delete mystate;\r
- arg->state=NULL;\r
-\r
- arg->flags|=SHTTPD_END_OF_OUTPUT;\r
+ return false;\r
}\r
+ }\r
+ else\r
+ {\r
+ return false;\r
+ }\r
+}\r
\r
+const bool IPageHandler::WillHandleURI(const std::string &uri)\r
+{\r
+ if(uri.find(m_pagename)!=std::string::npos)\r
+ {\r
return true;\r
}\r
else\r