aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Server/Base/ServerUtils.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Server/Base/ServerUtils.cs')
-rw-r--r--OpenSim/Server/Base/ServerUtils.cs179
1 files changed, 116 insertions, 63 deletions
diff --git a/OpenSim/Server/Base/ServerUtils.cs b/OpenSim/Server/Base/ServerUtils.cs
index 18a4266..cc506bc 100644
--- a/OpenSim/Server/Base/ServerUtils.cs
+++ b/OpenSim/Server/Base/ServerUtils.cs
@@ -39,7 +39,7 @@ using OpenMetaverse;
39using Mono.Addins; 39using Mono.Addins;
40using OpenSim.Framework.Servers.HttpServer; 40using OpenSim.Framework.Servers.HttpServer;
41using OpenSim.Framework.Servers; 41using OpenSim.Framework.Servers;
42 42using OpenMetaverse.StructuredData; // LitJson is hidden on this
43 43
44[assembly:AddinRoot("Robust", OpenSim.VersionInfo.VersionNumber)] 44[assembly:AddinRoot("Robust", OpenSim.VersionInfo.VersionNumber)]
45namespace OpenSim.Server.Base 45namespace OpenSim.Server.Base
@@ -104,7 +104,7 @@ namespace OpenSim.Server.Base
104 // libomv, which has a hard-coded path to "." for pinvoke 104 // libomv, which has a hard-coded path to "." for pinvoke
105 // to load the openjpeg dll 105 // to load the openjpeg dll
106 // 106 //
107 // Will look for a way to fix, but for now this keeps the 107 // Will look for a way to fix, but for now this keeps the
108 // confusion to a minimum. this was copied from our region 108 // confusion to a minimum. this was copied from our region
109 // plugin loader, we have been doing this in there for a long time. 109 // plugin loader, we have been doing this in there for a long time.
110 // 110 //
@@ -183,7 +183,7 @@ namespace OpenSim.Server.Base
183 183
184 if(port != 0) 184 if(port != 0)
185 server = MainServer.GetHttpServer(port); 185 server = MainServer.GetHttpServer(port);
186 else 186 else
187 server = MainServer.Instance; 187 server = MainServer.Instance;
188 188
189 return server; 189 return server;
@@ -222,19 +222,19 @@ namespace OpenSim.Server.Base
222 // This is good to debug configuration problems 222 // This is good to debug configuration problems
223 //if (dllName == string.Empty) 223 //if (dllName == string.Empty)
224 // Util.PrintCallStack(); 224 // Util.PrintCallStack();
225 225
226 string className = String.Empty; 226 string className = String.Empty;
227 227
228 // The path for a dynamic plugin will contain ":" on Windows 228 // The path for a dynamic plugin will contain ":" on Windows
229 string[] parts = dllName.Split (new char[] {':'}); 229 string[] parts = dllName.Split (new char[] {':'});
230 230
231 if (parts [0].Length > 1) 231 if (parts [0].Length > 1)
232 { 232 {
233 dllName = parts [0]; 233 dllName = parts [0];
234 if (parts.Length > 1) 234 if (parts.Length > 1)
235 className = parts[1]; 235 className = parts[1];
236 } 236 }
237 else 237 else
238 { 238 {
239 // This is Windows - we must replace the ":" in the path 239 // This is Windows - we must replace the ":" in the path
240 dllName = String.Format ("{0}:{1}", parts [0], parts [1]); 240 dllName = String.Format ("{0}:{1}", parts [0], parts [1]);
@@ -242,6 +242,18 @@ namespace OpenSim.Server.Base
242 className = parts[2]; 242 className = parts[2];
243 } 243 }
244 244
245 // Handle extra string arguments in a more generic way
246 if (dllName.Contains("@"))
247 {
248 string[] dllNameParts = dllName.Split(new char[] {'@'});
249 dllName = dllNameParts[dllNameParts.Length - 1];
250 List<Object> argList = new List<Object>(args);
251 for (int i = 0 ; i < dllNameParts.Length - 1 ; ++i)
252 argList.Add(dllNameParts[i]);
253
254 args = argList.ToArray();
255 }
256
245 return LoadPlugin<T>(dllName, className, args); 257 return LoadPlugin<T>(dllName, className, args);
246 } 258 }
247 259
@@ -264,10 +276,10 @@ namespace OpenSim.Server.Base
264 { 276 {
265 if (pluginType.IsPublic) 277 if (pluginType.IsPublic)
266 { 278 {
267 if (className != String.Empty 279 if (className != String.Empty
268 && pluginType.ToString() != pluginType.Namespace + "." + className) 280 && pluginType.ToString() != pluginType.Namespace + "." + className)
269 continue; 281 continue;
270 282
271 Type typeInterface = pluginType.GetInterface(interfaceName); 283 Type typeInterface = pluginType.GetInterface(interfaceName);
272 284
273 if (typeInterface != null) 285 if (typeInterface != null)
@@ -283,8 +295,8 @@ namespace OpenSim.Server.Base
283 if (!(e is System.MissingMethodException)) 295 if (!(e is System.MissingMethodException))
284 { 296 {
285 m_log.Error(string.Format("[SERVER UTILS]: Error loading plugin {0} from {1}. Exception: {2}", 297 m_log.Error(string.Format("[SERVER UTILS]: Error loading plugin {0} from {1}. Exception: {2}",
286 interfaceName, 298 interfaceName,
287 dllName, 299 dllName,
288 e.InnerException == null ? e.Message : e.InnerException.Message), 300 e.InnerException == null ? e.Message : e.InnerException.Message),
289 e); 301 e);
290 } 302 }
@@ -315,49 +327,62 @@ namespace OpenSim.Server.Base
315 327
316 public static Dictionary<string, object> ParseQueryString(string query) 328 public static Dictionary<string, object> ParseQueryString(string query)
317 { 329 {
318 Dictionary<string, object> result = new Dictionary<string, object>();
319 string[] terms = query.Split(new char[] {'&'}); 330 string[] terms = query.Split(new char[] {'&'});
320 331
321 if (terms.Length == 0) 332 int nterms = terms.Length;
322 return result; 333 if (nterms == 0)
334 return new Dictionary<string, object>();
323 335
324 foreach (string t in terms) 336 Dictionary<string, object> result = new Dictionary<string, object>(nterms);
337 string name;
338
339 for(int i = 0; i < nterms; ++i)
325 { 340 {
326 string[] elems = t.Split(new char[] {'='}); 341 string[] elems = terms[i].Split(new char[] {'='});
342
327 if (elems.Length == 0) 343 if (elems.Length == 0)
328 continue; 344 continue;
329 345
330 string name = System.Web.HttpUtility.UrlDecode(elems[0]); 346 if(String.IsNullOrWhiteSpace(elems[0]))
331 string value = String.Empty; 347 continue;
332 348
333 if (elems.Length > 1) 349 name = System.Web.HttpUtility.UrlDecode(elems[0]);
334 value = System.Web.HttpUtility.UrlDecode(elems[1]);
335 350
336 if (name.EndsWith("[]")) 351 if (name.EndsWith("[]"))
337 { 352 {
338 string cleanName = name.Substring(0, name.Length - 2); 353 name = name.Substring(0, name.Length - 2);
339 if (result.ContainsKey(cleanName)) 354 if(String.IsNullOrWhiteSpace(name))
355 continue;
356 if (result.ContainsKey(name))
340 { 357 {
341 if (!(result[cleanName] is List<string>)) 358 if (!(result[name] is List<string>))
342 continue; 359 continue;
343 360
344 List<string> l = (List<string>)result[cleanName]; 361 List<string> l = (List<string>)result[name];
345 362 if (elems.Length > 1 && !String.IsNullOrWhiteSpace(elems[1]))
346 l.Add(value); 363 l.Add(System.Web.HttpUtility.UrlDecode(elems[1]));
364 else
365 l.Add(String.Empty);
347 } 366 }
348 else 367 else
349 { 368 {
350 List<string> newList = new List<string>(); 369 List<string> newList = new List<string>();
351 370 if (elems.Length > 1 && !String.IsNullOrWhiteSpace(elems[1]))
352 newList.Add(value); 371 newList.Add(System.Web.HttpUtility.UrlDecode(elems[1]));
353 372 else
354 result[cleanName] = newList; 373 newList.Add(String.Empty);
374 result[name] = newList;
355 } 375 }
356 } 376 }
357 else 377 else
358 { 378 {
359 if (!result.ContainsKey(name)) 379 if (!result.ContainsKey(name))
360 result[name] = value; 380 {
381 if (elems.Length > 1 && !String.IsNullOrWhiteSpace(elems[1]))
382 result[name] = System.Web.HttpUtility.UrlDecode(elems[1]);
383 else
384 result[name] = String.Empty;
385 }
361 } 386 }
362 } 387 }
363 388
@@ -366,47 +391,70 @@ namespace OpenSim.Server.Base
366 391
367 public static string BuildQueryString(Dictionary<string, object> data) 392 public static string BuildQueryString(Dictionary<string, object> data)
368 { 393 {
369 string qstring = String.Empty; 394 // this is not conform to html url encoding
395 // can only be used on Body of POST or PUT
396 StringBuilder sb = new StringBuilder(4096);
370 397
371 string part; 398 string pvalue;
372 399
373 foreach (KeyValuePair<string, object> kvp in data) 400 foreach (KeyValuePair<string, object> kvp in data)
374 { 401 {
375 if (kvp.Value is List<string>) 402 if (kvp.Value is List<string>)
376 { 403 {
377 List<string> l = (List<String>)kvp.Value; 404 List<string> l = (List<String>)kvp.Value;
378 405 int llen = l.Count;
379 foreach (string s in l) 406 string nkey = System.Web.HttpUtility.UrlEncode(kvp.Key);
407 for(int i = 0; i < llen; ++i)
380 { 408 {
381 part = System.Web.HttpUtility.UrlEncode(kvp.Key) + 409 if (sb.Length != 0)
382 "[]=" + System.Web.HttpUtility.UrlEncode(s); 410 sb.Append("&");
383 411 sb.Append(nkey);
384 if (qstring != String.Empty) 412 sb.Append("[]=");
385 qstring += "&"; 413 sb.Append(System.Web.HttpUtility.UrlEncode(l[i]));
386
387 qstring += part;
388 } 414 }
389 } 415 }
390 else 416 else if(kvp.Value is Dictionary<string, object>)
391 { 417 {
392 if (kvp.Value.ToString() != String.Empty) 418 // encode complex structures as JSON
419 // needed for estate bans with the encoding used on xml
420 // encode can be here because object does contain the structure information
421 // but decode needs to be on estateSettings (or other user)
422 string js;
423 try
393 { 424 {
394 part = System.Web.HttpUtility.UrlEncode(kvp.Key) + 425 // bypass libovm, we dont need even more useless high level maps
395 "=" + System.Web.HttpUtility.UrlEncode(kvp.Value.ToString()); 426 // this should only be called once.. but no problem, i hope
427 // (other uses may need more..)
428 LitJson.JsonMapper.RegisterExporter<UUID>((uuid, writer) => writer.Write(uuid.ToString()) );
429 js = LitJson.JsonMapper.ToJson(kvp.Value);
396 } 430 }
397 else 431 // catch(Exception e)
432 catch
398 { 433 {
399 part = System.Web.HttpUtility.UrlEncode(kvp.Key); 434 continue;
435 }
436 if (sb.Length != 0)
437 sb.Append("&");
438 sb.Append(System.Web.HttpUtility.UrlEncode(kvp.Key));
439 sb.Append("=");
440 sb.Append(System.Web.HttpUtility.UrlEncode(js));
441 }
442 else
443 {
444 if (sb.Length != 0)
445 sb.Append("&");
446 sb.Append(System.Web.HttpUtility.UrlEncode(kvp.Key));
447
448 pvalue = kvp.Value.ToString();
449 if (!String.IsNullOrEmpty(pvalue))
450 {
451 sb.Append("=");
452 sb.Append(System.Web.HttpUtility.UrlEncode(pvalue));
400 } 453 }
401
402 if (qstring != String.Empty)
403 qstring += "&";
404
405 qstring += part;
406 } 454 }
407 } 455 }
408 456
409 return qstring; 457 return sb.ToString();
410 } 458 }
411 459
412 public static string BuildXmlResponse(Dictionary<string, object> data) 460 public static string BuildXmlResponse(Dictionary<string, object> data)
@@ -465,18 +513,23 @@ namespace OpenSim.Server.Base
465 Dictionary<string, object> ret = new Dictionary<string, object>(); 513 Dictionary<string, object> ret = new Dictionary<string, object>();
466 514
467 XmlDocument doc = new XmlDocument(); 515 XmlDocument doc = new XmlDocument();
516 doc.XmlResolver = null;
517 try
518 {
519 doc.LoadXml(data);
520 XmlNodeList rootL = doc.GetElementsByTagName("ServerResponse");
468 521
469 doc.LoadXml(data); 522 if (rootL.Count != 1)
470 523 return ret;
471 XmlNodeList rootL = doc.GetElementsByTagName("ServerResponse");
472
473 if (rootL.Count != 1)
474 return ret;
475
476 XmlNode rootNode = rootL[0];
477 524
478 ret = ParseElement(rootNode); 525 XmlNode rootNode = rootL[0];
479 526
527 ret = ParseElement(rootNode);
528 }
529 catch (Exception e)
530 {
531 m_log.DebugFormat("[serverUtils.ParseXmlResponse]: failed error: {0} \n --- string: {1} - ",e.Message, data);
532 }
480 return ret; 533 return ret;
481 } 534 }
482 535