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