version 0.3.29
[fms.git] / src / http / ipagehandler.cpp
1 #include "../../include/http/ipagehandler.h"\r
2 #include "../../include/stringfunctions.h"\r
3 #include "../../include/http/multipartparser.h"\r
4 \r
5 #include <Poco/Net/HTMLForm.h>\r
6 #include <Poco/UUIDGenerator.h>\r
7 #include <Poco/UUID.h>\r
8 #include <Poco/DateTime.h>\r
9 #include <Poco/DateTimeFormatter.h>\r
10 #include <Poco/Timespan.h>\r
11 \r
12 #include <cstring>\r
13 \r
14 #ifdef XMEM\r
15         #include <xmem.h>\r
16 #endif\r
17 \r
18 void IPageHandler::CreateArgArray(const std::map<std::string,std::string> &vars, const std::string &basename, std::vector<std::string> &args)\r
19 {\r
20         for(std::map<std::string,std::string>::const_iterator i=vars.begin(); i!=vars.end(); i++)\r
21         {\r
22                 if((*i).first.find(basename)==0 && (*i).first.find("[")!=std::string::npos && (*i).first.find("]")!=std::string::npos)\r
23                 {\r
24                         int index=0;\r
25                         std::string indexstr;\r
26                         std::string::size_type startpos;\r
27                         std::string::size_type endpos;\r
28                         startpos=(*i).first.find("[");\r
29                         endpos=(*i).first.find("]");\r
30 \r
31                         indexstr=(*i).first.substr(startpos+1,(endpos-startpos)-1);\r
32                         StringFunctions::Convert(indexstr,index);\r
33 \r
34                         while(args.size()<index+1)\r
35                         {\r
36                                 args.push_back("");\r
37                         }\r
38                         args[index]=(*i).second;\r
39                 }\r
40         }\r
41 }\r
42 \r
43 const std::string IPageHandler::CreateFormPassword()\r
44 {\r
45         Poco::DateTime date;\r
46         Poco::UUIDGenerator uuidgen;\r
47         Poco::UUID uuid;\r
48         try\r
49         {\r
50                 uuid=uuidgen.createRandom();\r
51         }\r
52         catch(...)\r
53         {\r
54         }\r
55 \r
56         SQLite3DB::Statement st=m_db->Prepare("INSERT INTO tmpFormPassword(Date,Password) VALUES(?,?);");\r
57         st.Bind(0,Poco::DateTimeFormatter::format(date,"%Y-%m-%d %H:%M:%S"));\r
58         st.Bind(1,uuid.toString());\r
59         st.Step();\r
60 \r
61         return "<input type=\"hidden\" name=\"formpassword\" value=\""+uuid.toString()+"\">";\r
62 \r
63 }\r
64 \r
65 const std::string IPageHandler::CreateTrueFalseDropDown(const std::string &name, const std::string &selected)\r
66 {\r
67         std::string rval="";\r
68 \r
69         rval+="<select name=\""+name+"\">";\r
70         rval+="<option value=\"true\"";\r
71         if(selected=="true")\r
72         {\r
73                 rval+=" SELECTED";\r
74         }\r
75         rval+=">true</option>";\r
76         rval+="<option value=\"false\"";\r
77         if(selected=="false")\r
78         {\r
79                 rval+=" SELECTED";\r
80         }\r
81         rval+=">false</option>";\r
82         rval+="</select>";\r
83 \r
84         return rval;\r
85 }\r
86 \r
87 void IPageHandler::CreateQueryVarMap(Poco::Net::HTTPServerRequest &request, std::map<std::string,std::string> &vars)\r
88 {\r
89         for(Poco::Net::HTTPServerRequest::ConstIterator i=request.begin(); i!=request.end(); i++)\r
90         {\r
91                 vars[(*i).first]=(*i).second;\r
92         }\r
93 \r
94         // handle HTMLForm and multiparts\r
95         MultiPartParser mpp;\r
96         Poco::Net::HTMLForm form(request,request.stream(),mpp);\r
97         for(Poco::Net::HTMLForm::ConstIterator i=form.begin(); i!=form.end(); i++)\r
98         {\r
99                 vars[(*i).first]=(*i).second;\r
100         }\r
101 \r
102         // for a POST method, the HTMLForm won't grab vars off the query string so we\r
103         // temporarily set the method to GET and parse with the HTMLForm again\r
104         if(request.getMethod()=="POST")\r
105         {\r
106                 request.setMethod("GET");\r
107                 Poco::Net::HTMLForm form1(request,request.stream(),mpp);\r
108                 for(Poco::Net::HTMLForm::ConstIterator i=form1.begin(); i!=form1.end(); i++)\r
109                 {\r
110                         vars[(*i).first]=(*i).second;\r
111                 }\r
112                 request.setMethod("POST");\r
113         }\r
114 \r
115         // get any multiparts\r
116         std::map<std::string,std::string> mpvars=mpp.GetVars();\r
117         for(std::map<std::string,std::string>::iterator i=mpvars.begin(); i!=mpvars.end(); i++)\r
118         {\r
119                 vars[(*i).first]=(*i).second;\r
120         }\r
121 \r
122 }\r
123 \r
124 void IPageHandler::handleRequest(Poco::Net::HTTPServerRequest &request, Poco::Net::HTTPServerResponse &response)\r
125 {\r
126         m_log->trace("IPageHandler::handleRequest from "+request.clientAddress().toString());\r
127 \r
128         std::map<std::string,std::string> vars;\r
129 \r
130         CreateQueryVarMap(request,vars);\r
131 \r
132         if(request.getVersion()==Poco::Net::HTTPRequest::HTTP_1_1)\r
133         {\r
134                 response.setChunkedTransferEncoding(true);\r
135         }\r
136         response.setContentType("text/html");\r
137 \r
138         std::ostream &ostr = response.send();\r
139         ostr << GeneratePage(request.getMethod(),vars);\r
140 \r
141 }\r
142 \r
143 const std::string IPageHandler::SanitizeOutput(const std::string &input)\r
144 {\r
145         // must do & first because all other elements have & in them!\r
146         std::string output=StringFunctions::Replace(input,"&","&amp;");\r
147         output=StringFunctions::Replace(output,"<","&lt;");\r
148         output=StringFunctions::Replace(output,">","&gt;");\r
149         output=StringFunctions::Replace(output,"\"","&quot;");\r
150         output=StringFunctions::Replace(output," ","&nbsp;");\r
151         return output;\r
152 }\r
153 \r
154 const std::string IPageHandler::SanitizeTextAreaOutput(const std::string &input)\r
155 {\r
156         // must do & first because all other elements have & in them!\r
157         std::string output=StringFunctions::Replace(input,"&","&amp;");\r
158         output=StringFunctions::Replace(output,"<","&lt;");\r
159         output=StringFunctions::Replace(output,">","&gt;");\r
160         output=StringFunctions::Replace(output,"\"","&quot;");\r
161         return output;\r
162 }\r
163 \r
164 const bool IPageHandler::ValidateFormPassword(const std::map<std::string,std::string> &vars)\r
165 {\r
166         Poco::DateTime date;\r
167         date-=Poco::Timespan(0,1,0,0,0);\r
168 \r
169         SQLite3DB::Statement st=m_db->Prepare("DELETE FROM tmpFormPassword WHERE Date<?;");\r
170         st.Bind(0,Poco::DateTimeFormatter::format(date,"%Y-%m-%d %H:%M:%S"));\r
171         st.Step();\r
172 \r
173         std::map<std::string,std::string>::const_iterator i=vars.find("formpassword");\r
174         if(i!=vars.end())\r
175         {\r
176                 st=m_db->Prepare("SELECT COUNT(*) FROM tmpFormPassword WHERE Password=?;");\r
177                 st.Bind(0,(*i).second);\r
178                 st.Step();\r
179                 if(st.RowReturned())\r
180                 {\r
181                         if(st.ResultNull(0)==false)\r
182                         {\r
183                                 int rval=0;\r
184                                 st.ResultInt(0,rval);\r
185                                 if(rval>0)\r
186                                 {\r
187                                         return true;\r
188                                 }\r
189                                 else\r
190                                 {\r
191                                         return false;\r
192                                 }\r
193                         }\r
194                         else\r
195                         {\r
196                                 return false;\r
197                         }\r
198                 }\r
199                 else\r
200                 {\r
201                         return false;\r
202                 }\r
203         }\r
204         else\r
205         {\r
206                 return false;\r
207         }\r
208 }\r
209 \r
210 const bool IPageHandler::WillHandleURI(const std::string &uri)\r
211 {\r
212         if(uri.find(m_pagename)!=std::string::npos)\r
213         {\r
214                 return true;\r
215         }\r
216         else\r
217         {\r
218                 return false;\r
219         }\r
220 }\r