diff options
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Server/Base/ServerUtils.cs | 179 |
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; | |||
39 | using Mono.Addins; | 39 | using Mono.Addins; |
40 | using OpenSim.Framework.Servers.HttpServer; | 40 | using OpenSim.Framework.Servers.HttpServer; |
41 | using OpenSim.Framework.Servers; | 41 | using OpenSim.Framework.Servers; |
42 | 42 | using OpenMetaverse.StructuredData; // LitJson is hidden on this | |
43 | 43 | ||
44 | [assembly:AddinRoot("Robust", OpenSim.VersionInfo.VersionNumber)] | 44 | [assembly:AddinRoot("Robust", OpenSim.VersionInfo.VersionNumber)] |
45 | namespace OpenSim.Server.Base | 45 | namespace 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 | ||