diff options
author | UbitUmarov | 2017-12-30 15:28:26 +0000 |
---|---|---|
committer | UbitUmarov | 2017-12-30 15:28:26 +0000 |
commit | 803289877307ce0016627f58af382b68a1905327 (patch) | |
tree | ad7cdd3026322ba20e9c608332c6578909e2d996 | |
parent | add missing entry on prebuid.xml for mutelist service (diff) | |
download | opensim-SC_OLD-803289877307ce0016627f58af382b68a1905327.zip opensim-SC_OLD-803289877307ce0016627f58af382b68a1905327.tar.gz opensim-SC_OLD-803289877307ce0016627f58af382b68a1905327.tar.bz2 opensim-SC_OLD-803289877307ce0016627f58af382b68a1905327.tar.xz |
mantis 8271: work around missing encoding of estate bans on the pseudo url encode used on POST, without changing the xml also used elsewhere. Possible this can be used in other case
-rw-r--r-- | OpenSim/Framework/EstateSettings.cs | 43 | ||||
-rw-r--r-- | OpenSim/Server/Base/ServerUtils.cs | 126 |
2 files changed, 116 insertions, 53 deletions
diff --git a/OpenSim/Framework/EstateSettings.cs b/OpenSim/Framework/EstateSettings.cs index 7134cbf..8c8270a 100644 --- a/OpenSim/Framework/EstateSettings.cs +++ b/OpenSim/Framework/EstateSettings.cs | |||
@@ -572,14 +572,41 @@ namespace OpenSim.Framework | |||
572 | 572 | ||
573 | // EstateBans are special | 573 | // EstateBans are special |
574 | if (map.ContainsKey("EstateBans")) | 574 | if (map.ContainsKey("EstateBans")) |
575 | { | 575 | { |
576 | var banData = ((Dictionary<string, object>)map["EstateBans"]).Values; | 576 | if(map["EstateBans"] is string) |
577 | EstateBan[] bans = new EstateBan[banData.Count]; | 577 | { |
578 | int b = 0; | 578 | // JSON encoded bans map |
579 | foreach (Dictionary<string, object> ban in banData) | 579 | Dictionary<string, EstateBan> bdata = new Dictionary<string, EstateBan>(); |
580 | bans[b++] = new EstateBan(ban); | 580 | try |
581 | PropertyInfo bansProperty = this.GetType().GetProperty("EstateBans", BindingFlags.Public | BindingFlags.Instance); | 581 | { |
582 | bansProperty.SetValue(this, bans, null); | 582 | // bypass libovm, we dont need even more useless high level maps |
583 | // this should only be called once.. but no problem, i hope | ||
584 | // (other uses may need more..) | ||
585 | LitJson.JsonMapper.RegisterImporter<string, UUID>((input) => new UUID(input)); | ||
586 | bdata = LitJson.JsonMapper.ToObject<Dictionary<string,EstateBan>>((string)map["EstateBans"]); | ||
587 | } | ||
588 | // catch(Exception e) | ||
589 | catch | ||
590 | { | ||
591 | return; | ||
592 | } | ||
593 | EstateBan[] jbans = new EstateBan[bdata.Count]; | ||
594 | bdata.Values.CopyTo(jbans,0); | ||
595 | |||
596 | PropertyInfo jbansProperty = this.GetType().GetProperty("EstateBans", BindingFlags.Public | BindingFlags.Instance); | ||
597 | jbansProperty.SetValue(this, jbans, null); | ||
598 | } | ||
599 | else | ||
600 | { | ||
601 | var banData = ((Dictionary<string, object>)map["EstateBans"]).Values; | ||
602 | EstateBan[] bans = new EstateBan[banData.Count]; | ||
603 | |||
604 | int b = 0; | ||
605 | foreach (Dictionary<string, object> ban in banData) | ||
606 | bans[b++] = new EstateBan(ban); | ||
607 | PropertyInfo bansProperty = this.GetType().GetProperty("EstateBans", BindingFlags.Public | BindingFlags.Instance); | ||
608 | bansProperty.SetValue(this, bans, null); | ||
609 | } | ||
583 | } | 610 | } |
584 | } | 611 | } |
585 | } | 612 | } |
diff --git a/OpenSim/Server/Base/ServerUtils.cs b/OpenSim/Server/Base/ServerUtils.cs index aff6b4f..9fd613f 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 |
@@ -326,50 +326,63 @@ namespace OpenSim.Server.Base | |||
326 | } | 326 | } |
327 | 327 | ||
328 | public static Dictionary<string, object> ParseQueryString(string query) | 328 | public static Dictionary<string, object> ParseQueryString(string query) |
329 | { | 329 | { |
330 | Dictionary<string, object> result = new Dictionary<string, object>(); | ||
331 | string[] terms = query.Split(new char[] {'&'}); | 330 | string[] terms = query.Split(new char[] {'&'}); |
332 | 331 | ||
333 | if (terms.Length == 0) | 332 | int nterms = terms.Length; |
334 | return result; | 333 | if (nterms == 0) |
334 | return new Dictionary<string, object>(); | ||
335 | |||
336 | Dictionary<string, object> result = new Dictionary<string, object>(nterms); | ||
337 | string name; | ||
335 | 338 | ||
336 | foreach (string t in terms) | 339 | for(int i = 0; i < nterms; ++i) |
337 | { | 340 | { |
338 | string[] elems = t.Split(new char[] {'='}); | 341 | string[] elems = terms[i].Split(new char[] {'='}); |
342 | |||
339 | if (elems.Length == 0) | 343 | if (elems.Length == 0) |
340 | continue; | 344 | continue; |
341 | 345 | ||
342 | string name = System.Web.HttpUtility.UrlDecode(elems[0]); | 346 | if(String.IsNullOrWhiteSpace(elems[0])) |
343 | string value = String.Empty; | 347 | continue; |
344 | 348 | ||
345 | if (elems.Length > 1) | 349 | name = System.Web.HttpUtility.UrlDecode(elems[0]); |
346 | value = System.Web.HttpUtility.UrlDecode(elems[1]); | ||
347 | 350 | ||
348 | if (name.EndsWith("[]")) | 351 | if (name.EndsWith("[]")) |
349 | { | 352 | { |
350 | string cleanName = name.Substring(0, name.Length - 2); | 353 | name = name.Substring(0, name.Length - 2); |
351 | if (result.ContainsKey(cleanName)) | 354 | if(String.IsNullOrWhiteSpace(name)) |
355 | continue; | ||
356 | if (result.ContainsKey(name)) | ||
352 | { | 357 | { |
353 | if (!(result[cleanName] is List<string>)) | 358 | if (!(result[name] is List<string>)) |
354 | continue; | 359 | continue; |
355 | 360 | ||
356 | List<string> l = (List<string>)result[cleanName]; | 361 | List<string> l = (List<string>)result[name]; |
357 | 362 | if (elems.Length > 1 && !String.IsNullOrWhiteSpace(elems[1])) | |
358 | l.Add(value); | 363 | l.Add(System.Web.HttpUtility.UrlDecode(elems[1])); |
364 | else | ||
365 | l.Add(String.Empty); | ||
359 | } | 366 | } |
360 | else | 367 | else |
361 | { | 368 | { |
362 | List<string> newList = new List<string>(); | 369 | List<string> newList = new List<string>(); |
363 | 370 | if (elems.Length > 1 && !String.IsNullOrWhiteSpace(elems[1])) | |
364 | newList.Add(value); | 371 | newList.Add(System.Web.HttpUtility.UrlDecode(elems[1])); |
365 | 372 | else | |
366 | result[cleanName] = newList; | 373 | newList.Add(String.Empty); |
374 | result[name] = newList; | ||
367 | } | 375 | } |
368 | } | 376 | } |
369 | else | 377 | else |
370 | { | 378 | { |
371 | if (!result.ContainsKey(name)) | 379 | if (!result.ContainsKey(name)) |
372 | 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 | } | ||
373 | } | 386 | } |
374 | } | 387 | } |
375 | 388 | ||
@@ -378,47 +391,70 @@ namespace OpenSim.Server.Base | |||
378 | 391 | ||
379 | public static string BuildQueryString(Dictionary<string, object> data) | 392 | public static string BuildQueryString(Dictionary<string, object> data) |
380 | { | 393 | { |
381 | 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); | ||
382 | 397 | ||
383 | string part; | 398 | string pvalue; |
384 | 399 | ||
385 | foreach (KeyValuePair<string, object> kvp in data) | 400 | foreach (KeyValuePair<string, object> kvp in data) |
386 | { | 401 | { |
387 | if (kvp.Value is List<string>) | 402 | if (kvp.Value is List<string>) |
388 | { | 403 | { |
389 | List<string> l = (List<String>)kvp.Value; | 404 | List<string> l = (List<String>)kvp.Value; |
390 | 405 | int llen = l.Count; | |
391 | foreach (string s in l) | 406 | string nkey = System.Web.HttpUtility.UrlEncode(kvp.Key); |
407 | for(int i = 0; i < llen; ++i) | ||
392 | { | 408 | { |
393 | part = System.Web.HttpUtility.UrlEncode(kvp.Key) + | 409 | if (sb.Length != 0) |
394 | "[]=" + System.Web.HttpUtility.UrlEncode(s); | 410 | sb.Append("&"); |
395 | 411 | sb.Append(nkey); | |
396 | if (qstring != String.Empty) | 412 | sb.Append("[]="); |
397 | qstring += "&"; | 413 | sb.Append(System.Web.HttpUtility.UrlEncode(l[i])); |
398 | |||
399 | qstring += part; | ||
400 | } | 414 | } |
401 | } | 415 | } |
402 | else | 416 | else if(kvp.Value is Dictionary<string, object>) |
403 | { | 417 | { |
404 | 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 | ||
405 | { | 424 | { |
406 | part = System.Web.HttpUtility.UrlEncode(kvp.Key) + | 425 | // bypass libovm, we dont need even more useless high level maps |
407 | "=" + 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); | ||
408 | } | 430 | } |
409 | else | 431 | // catch(Exception e) |
432 | catch | ||
410 | { | 433 | { |
411 | 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)); | ||
412 | } | 453 | } |
413 | |||
414 | if (qstring != String.Empty) | ||
415 | qstring += "&"; | ||
416 | |||
417 | qstring += part; | ||
418 | } | 454 | } |
419 | } | 455 | } |
420 | 456 | ||
421 | return qstring; | 457 | return sb.ToString(); |
422 | } | 458 | } |
423 | 459 | ||
424 | public static string BuildXmlResponse(Dictionary<string, object> data) | 460 | public static string BuildXmlResponse(Dictionary<string, object> data) |