diff options
Diffstat (limited to 'OpenSim/Server')
-rw-r--r-- | OpenSim/Server/Handlers/Web/WebServerInConnector.cs | 207 |
1 files changed, 183 insertions, 24 deletions
diff --git a/OpenSim/Server/Handlers/Web/WebServerInConnector.cs b/OpenSim/Server/Handlers/Web/WebServerInConnector.cs index 52ee9ae..8c14fde 100644 --- a/OpenSim/Server/Handlers/Web/WebServerInConnector.cs +++ b/OpenSim/Server/Handlers/Web/WebServerInConnector.cs | |||
@@ -51,7 +51,7 @@ namespace OpenSim.Server.Handlers.Web | |||
51 | private IConfigSource m_Config; | 51 | private IConfigSource m_Config; |
52 | protected MySQLGenericHandler m_Database = null; | 52 | protected MySQLGenericHandler m_Database = null; |
53 | private Hashtable mime = new Hashtable(); | 53 | private Hashtable mime = new Hashtable(); |
54 | private Hashtable ssi = new Hashtable(); | 54 | private Hashtable ssi = new Hashtable(); |
55 | 55 | ||
56 | public WebServerInConnector(IConfigSource config, IHttpServer server, string configName) : base(config, server, configName) | 56 | public WebServerInConnector(IConfigSource config, IHttpServer server, string configName) : base(config, server, configName) |
57 | { | 57 | { |
@@ -76,12 +76,12 @@ namespace OpenSim.Server.Handlers.Web | |||
76 | throw new Exception("No StorageProvider configured"); | 76 | throw new Exception("No StorageProvider configured"); |
77 | 77 | ||
78 | //// TODO - Should do the plugin thing to pick between database backends. | 78 | //// TODO - Should do the plugin thing to pick between database backends. |
79 | //// Or not, we are all using MariaDB anyway. | ||
79 | // m_Database = LoadPlugin<SQLGenericHandler>(dllName, new Object[] { connString }); | 80 | // m_Database = LoadPlugin<SQLGenericHandler>(dllName, new Object[] { connString }); |
80 | m_Database = new MySQLGenericHandler(connString); | 81 | m_Database = new MySQLGenericHandler(connString); |
81 | if (m_Database == null) | 82 | if (m_Database == null) |
82 | throw new Exception("Could not find a storage interface in the given module " + dllName); | 83 | throw new Exception("Could not find a storage interface in the given module " + dllName); |
83 | 84 | ||
84 | |||
85 | mime.Add(".gz", "application/gzip"); | 85 | mime.Add(".gz", "application/gzip"); |
86 | mime.Add(".js", "application/javascript"); | 86 | mime.Add(".js", "application/javascript"); |
87 | mime.Add(".json", "application/json"); | 87 | mime.Add(".json", "application/json"); |
@@ -135,41 +135,200 @@ namespace OpenSim.Server.Handlers.Web | |||
135 | string method = (string) request["http-method"]; | 135 | string method = (string) request["http-method"]; |
136 | string type = (string) request["content-type"]; | 136 | string type = (string) request["content-type"]; |
137 | string body = (string) request["body"]; | 137 | string body = (string) request["body"]; |
138 | string file = Path.Combine(Util.webDir(), reqpath.Remove(0, 5)); | 138 | string file = reqpath.Remove(0, 5); |
139 | string path = Path.Combine(Util.webDir(), file); | ||
140 | |||
141 | m_log.InfoFormat("[WEB SERVICE]: {0} method path {1} type {2} body {3}.", method, reqpath, type, body); | ||
142 | foreach (DictionaryEntry h in headers) | ||
143 | m_log.InfoFormat("[WEB SERVICE]: {0} method path {1} header {2} = {3}", method, reqpath, (string) h.Key, (string) h.Value); | ||
144 | foreach (String q in query) | ||
145 | m_log.InfoFormat("[WEB SERVICE]: {0} method path {1} query {2}", method, reqpath, q); | ||
139 | 146 | ||
140 | reply["int_response_code"] = 200; | 147 | reply["int_response_code"] = 200; |
141 | if (File.Exists(file)) | 148 | if ("GET" == method) |
142 | { | 149 | { |
143 | string m = (string) mime[Path.GetExtension(file).ToLower()]; | 150 | if (File.Exists(path)) |
144 | reply["content_type"] = m; | ||
145 | if ((null == m) || ("text/" != m.Substring(0, 5))) | ||
146 | { | ||
147 | reply["bin_response_data"] = File.ReadAllBytes(file); | ||
148 | } | ||
149 | else | ||
150 | { | 151 | { |
151 | StreamReader csr = File.OpenText(file); | 152 | string m = (string) mime[Path.GetExtension(path).ToLower()]; |
152 | string content = csr.ReadToEnd(); | 153 | reply["content_type"] = m; |
153 | // Slow and wasteful, but I'm expecting only tiny web files, not accessed very often. | 154 | if ((null == m) || ("text/" != m.Substring(0, 5))) |
154 | foreach (DictionaryEntry v in ssi) | 155 | reply["bin_response_data"] = File.ReadAllBytes(path); |
156 | else | ||
155 | { | 157 | { |
156 | content = content.Replace("<!--#echo var=\"" + ((string) v.Key) + "\" -->", (string) v.Value); | 158 | StreamReader csr = File.OpenText(path); |
159 | string content = csr.ReadToEnd(); | ||
160 | // Slow and wasteful, but I'm expecting only tiny web files, not accessed very often. | ||
161 | foreach (DictionaryEntry v in ssi) | ||
162 | { | ||
163 | content = content.Replace("<!--#echo var=\"" + ((string) v.Key) + "\" -->", (string) v.Value); | ||
164 | } | ||
165 | reply["str_response_string"] = content; | ||
166 | csr.Close(); | ||
157 | } | 167 | } |
158 | reply["str_response_string"] = content; | ||
159 | csr.Close(); | ||
160 | } | 168 | } |
161 | } | 169 | else |
162 | else | 170 | { |
171 | if ("account.html" == file) | ||
172 | reply["str_response_string"] = loginPage(null, ""); | ||
173 | else | ||
174 | { | ||
175 | m_log.ErrorFormat("[WEB SERVICE]: Unable to read {0}.", path); | ||
176 | reply["int_response_code"] = 404; | ||
177 | reply["content_type"] = "text/html"; | ||
178 | reply["str_response_string"] = "<html><title>404 Unknown page</title><head></head><body bgcolor=\"black\" text=\"white\" alink=\"red\" link=\"blue\" vlink=\"purple\">" + | ||
179 | "404 error, can't find the " + reqpath + " page.<p> </p></body></html>"; | ||
180 | } | ||
181 | } | ||
182 | } | ||
183 | else if ("POST" == method) | ||
163 | { | 184 | { |
164 | m_log.ErrorFormat("[WEB SERVICE]: Unable to read {0}.", file); | 185 | Hashtable fields = new Hashtable(); |
186 | string[] bdy = body.Split('&'); | ||
187 | body = ""; | ||
188 | foreach (String bd in bdy) | ||
189 | { | ||
190 | string[] b = bd.Split('='); | ||
191 | if (b.Length == 0) | ||
192 | continue; | ||
193 | String n = System.Web.HttpUtility.UrlDecode(b[0]); | ||
194 | String v = ""; | ||
195 | if (b.Length > 1) | ||
196 | v = System.Web.HttpUtility.UrlDecode(b[1]); | ||
197 | fields[n] = v; | ||
198 | body = body + "<p>" + n + " = " + v + "</p>\n"; | ||
199 | } | ||
200 | |||
201 | if ("account.html" == file) | ||
202 | { | ||
203 | if ("logout" == fields["doit"].ToString()) | ||
204 | reply["str_response_string"] = loginPage(null, "Logged out."); | ||
205 | else if ("create" == fields["doit"].ToString()) | ||
206 | { | ||
207 | if ("" == fields["email"].ToString()) | ||
208 | reply["str_response_string"] = loginPage(fields, "Please supply an email address when creating an account."); | ||
209 | else | ||
210 | { | ||
211 | reply["str_response_string"] = loggedOnPage(body, fields); | ||
212 | } | ||
213 | } | ||
214 | else | ||
215 | { | ||
216 | reply["str_response_string"] = loggedOnPage(body, fields); | ||
217 | } | ||
218 | } | ||
219 | else | ||
220 | { | ||
221 | m_log.ErrorFormat("[WEB SERVICE]: No such POST target {0}.", path); | ||
222 | reply["int_response_code"] = 404; | ||
223 | reply["content_type"] = "text/html"; | ||
224 | reply["str_response_string"] = "<html><title>404 Unknown page</title><head></head><body bgcolor=\"black\" text=\"white\" alink=\"red\" link=\"blue\" vlink=\"purple\">" + | ||
225 | "404 error, can't find the " + reqpath + " page.<p> </p></body></html>"; | ||
226 | } | ||
227 | } | ||
228 | else | ||
229 | { | ||
230 | m_log.ErrorFormat("[WEB SERVICE]: UNKNOWN method {0} path {1}.", method, reqpath); | ||
165 | reply["int_response_code"] = 404; | 231 | reply["int_response_code"] = 404; |
166 | reply["content_type"] = "text/html"; | 232 | reply["content_type"] = "text/html"; |
167 | reply["str_response_string"] = "<html><title>404 Unknown page</title><head></head><body bgcolor=\"black\" text=\"white\" alink=\"red\" link=\"blue\" vlink=\"purple\">" + | 233 | reply["str_response_string"] = "<html><title>Unknown method</title><head></head><body bgcolor=\"black\" text=\"white\" alink=\"red\" link=\"blue\" vlink=\"purple\">" + |
168 | "404 error, can't find the " + reqpath + " page.<p> </p></body></html>"; | 234 | "HUH! For " + reqpath + " page.<p> </p></body></html>"; |
169 | } | 235 | } |
170 | 236 | ||
237 | m_log.Info("[WEB SERVICE]: "); | ||
171 | return reply; | 238 | return reply; |
172 | } | 239 | } |
173 | 240 | ||
241 | private string loginPage(Hashtable fields, string message) | ||
242 | { | ||
243 | string f = ""; | ||
244 | string l = ""; | ||
245 | string e = ""; | ||
246 | if (null != fields) | ||
247 | { | ||
248 | f = fields["firstName"].ToString(); | ||
249 | l = fields["lastName"].ToString(); | ||
250 | e = fields["email"].ToString(); | ||
251 | } | ||
252 | return header(ssi["grid"] + " account") | ||
253 | + form("account.html", "", | ||
254 | text("text", "first name", "firstName", f, 16, true) | ||
255 | + text("text", "last name", "lastName", l, 16, true) | ||
256 | + text("email", "email", "email", e, 0, false) | ||
257 | + text("password", "password", "password", "", 14,true) | ||
258 | + button("create") | ||
259 | + button("login") | ||
260 | ) | ||
261 | + "<p>" + message + "</p>" | ||
262 | + footer(); | ||
263 | } | ||
264 | |||
265 | private string loggedOnPage(string body, Hashtable fields) | ||
266 | { | ||
267 | return header(ssi["grid"] + " account") | ||
268 | + "<h1>" + ssi["grid"] + " account for " + fields["firstName"].ToString() + " " + fields["lastName"].ToString() + "</h1>" | ||
269 | + form("account.html", fields["token"].ToString(), | ||
270 | hidden("firstName", fields["firstName"].ToString()) | ||
271 | + hidden("lastName", fields["lastName"].ToString()) | ||
272 | + text("email", "email", "email", fields["email"].ToString(), 0, false) | ||
273 | + text("password", "password", "password", "", 14, false) | ||
274 | + select("type", "type", | ||
275 | option("", false) | ||
276 | + option("approved", true) | ||
277 | + option("disabled", false) | ||
278 | + option("god", false) | ||
279 | ) | ||
280 | + button("delete") | ||
281 | + button("list") | ||
282 | + button("logout") | ||
283 | // + button("read") | ||
284 | + button("update") | ||
285 | ) | ||
286 | + body | ||
287 | + footer(); | ||
288 | } | ||
289 | |||
290 | private string header(string title) | ||
291 | { | ||
292 | return "<html>\n <head>\n <title>" + title + "</title>\n </head>\n <body>\n"; | ||
293 | } | ||
294 | private string form(string action, string token, string form) | ||
295 | { | ||
296 | return " <form action=\"" + action + "\" method=\"POST\">\n" + hidden("token", token) + form + " </form>\n"; | ||
297 | } | ||
298 | private string hidden(string name, string val) | ||
299 | { | ||
300 | return " <input type=\"hidden\" name=\"" + name + "\" value=\"" + val + "\">\n"; | ||
301 | } | ||
302 | private string text(string type, string title, string name, string val, int max, bool required) | ||
303 | { | ||
304 | string extra = ""; | ||
305 | if (0 < max) | ||
306 | extra = extra + " maxlength=\"" + max.ToString() + "\""; | ||
307 | if (required) | ||
308 | extra = extra + " required"; | ||
309 | if ("" != val) | ||
310 | val = "value=\"" + val + "\""; | ||
311 | return " <p>" + title + " : <input type=\"" + type + "\" name=\"" + name + "\"" + val + extra + "></p>\n"; | ||
312 | } | ||
313 | private string select(string title, string name, string options) | ||
314 | { | ||
315 | return " <p>" + title + " : \n <select name=\"" + name + "\">\n" + options + " </select>\n </p>\n"; | ||
316 | } | ||
317 | private string option(string title, bool selected) | ||
318 | { | ||
319 | string sel = ""; | ||
320 | if (selected) | ||
321 | sel = " selected"; | ||
322 | return " <option value=\"" + title + "\"" + sel + ">" + title + "</option>\n"; | ||
323 | } | ||
324 | private string button(string title) | ||
325 | { | ||
326 | return " <button type=\"submit\" name=\"doit\" value=\"" + title + "\">" + title + "</button>\n"; | ||
327 | } | ||
328 | private string footer() | ||
329 | { | ||
330 | return " </body>\n</html>\n"; | ||
331 | } | ||
332 | |||
174 | } | 333 | } |
175 | } | 334 | } |