add a low level LLSDxml encoder for cases where it makes no sense to use more heavy things like OSD, and use it on displaynames

httptests
UbitUmarov 2018-01-25 06:50:49 +00:00
parent 3aff72e403
commit 266eabcad4
2 changed files with 490 additions and 34 deletions

View File

@ -0,0 +1,457 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// a class for low level LLSD encoding into a provided StringBuilder
// for cases where we already need to know the low level detail
// and so using something like OSD or even protbuf is just a pure waste
using System;
using System.Globalization;
using System.Text;
using OpenMetaverse;
namespace OpenSim.Framework
{
public static class LLSDxmlEncode
{
static readonly DateTime depoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
public static void AddStartHeader(StringBuilder sb, bool addxmlversion = false)
{
if(addxmlversion)
sb.Append("<?xml version=\"1.0\" encoding=\"UTF-8\"?><llsd>"); // legacy llsd xml name still valid
else
sb.Append("<llsd>");
}
public static void AddEndHeader(StringBuilder sb)
{
sb.Append("</llsd>");
}
// map == a list of key value pairs
public static void AddStartMap(StringBuilder sb)
{
sb.Append("<map>");
}
public static void AddEndMap(StringBuilder sb)
{
sb.Append("</map>");
}
public static void AddEmpyMap(StringBuilder sb)
{
sb.Append("<map />");
}
// array == a list values
public static void AddStartArray(StringBuilder sb)
{
sb.Append("<array>");
}
public static void AddEndArray(StringBuilder sb)
{
sb.Append("</array>");
}
public static void AddEmpyArray(StringBuilder sb)
{
sb.Append("<array />");
}
// undefined or null
public static void AddUnknownElem(StringBuilder sb)
{
sb.Append("<undef />");
}
public static void AddElem(bool e, StringBuilder sb)
{
if(e)
sb.Append("<boolean>1</boolean>");
else
sb.Append("<boolean />");
}
public static void AddElem(int e, StringBuilder sb)
{
if(e == 0)
sb.Append("<integer />");
else
{
sb.Append("<integer>");
sb.Append(e.ToString());
sb.Append("</integer>");
}
}
public static void AddElem(float e, StringBuilder sb)
{
if(e == 0)
sb.Append("<real />");
else
{
sb.Append("<real>");
sb.Append(e.ToString(CultureInfo.InvariantCulture));
sb.Append("</real>");
}
}
public static void AddElem(double e, StringBuilder sb)
{
if(e == 0)
sb.Append("<real />");
else
{
sb.Append("<real>");
sb.Append(e.ToString(CultureInfo.InvariantCulture));
sb.Append("</real>");
}
}
public static void AddElem(UUID e, StringBuilder sb)
{
if(e == UUID.Zero)
sb.Append("<uuid />");
else
{
sb.Append("<uuid>");
EscapeToXML(e.ToString(), sb);
sb.Append("</uuid>");
}
}
public static void AddElem(string e, StringBuilder sb)
{
if(String.IsNullOrEmpty(e))
sb.Append("<string />");
else
{
sb.Append("<string>");
sb.Append(e.ToString());
sb.Append("</string>");
}
}
public static void AddRawElem(string e, StringBuilder sb)
{
if(String.IsNullOrEmpty(e))
sb.Append("<string />");
else
{
sb.Append("<string>");
sb.Append(e);
sb.Append("</string>");
}
}
public static void AddURIElem(Uri e, StringBuilder sb)
{
if(e == null)
{
sb.Append("<uri />");
return;
}
string s;
if (e.IsAbsoluteUri)
s = e.AbsoluteUri;
else
s = e.ToString();
if(String.IsNullOrEmpty(s))
sb.Append("<uri />");
else
{
sb.Append("<uri>");
sb.Append(s);
sb.Append("</uri>");
}
}
public static void AddElem(DateTime e, StringBuilder sb)
{
DateTime u = e.ToUniversalTime();
if(u == depoch)
{
sb.Append("<date />");
return;
}
string format;
if(u.Hour == 0 && u.Minute == 0 && u.Second == 0)
format = "yyyy-MM-dd";
else if (u.Millisecond > 0)
format = "yyyy-MM-ddTHH:mm:ss.ffZ";
else
format = "yyyy-MM-ddTHH:mm:ssZ";
sb.Append("<date>");
sb.Append(u.ToString(format,CultureInfo.InvariantCulture));
sb.Append("</date>");
}
//************ key value *******************
// assumes name is a valid llsd key
public static void AddStartMap(string name, StringBuilder sb)
{
sb.Append("<key>");
sb.Append(name);
sb.Append("</key><map>");
}
public static void AddEmpyMap(string name, StringBuilder sb)
{
sb.Append("<key>");
sb.Append(name);
sb.Append("</key><map />");
}
// array == a list values
public static void AddStartArray(string name, StringBuilder sb)
{
sb.Append("<key>");
sb.Append(name);
sb.Append("</key><array>");
}
public static void AddEmpyArray(string name, StringBuilder sb)
{
sb.Append("<key>");
sb.Append(name);
sb.Append("</key><array />");
}
// undefined or null
public static void AddUnknownElem(string name, StringBuilder sb)
{
sb.Append("<key>");
sb.Append(name);
sb.Append("</key><undef />");
}
public static void AddElem(string name, bool e, StringBuilder sb)
{
sb.Append("<key>");
sb.Append(name);
sb.Append("</key>");
if(e)
sb.Append("<boolean>1</boolean>");
else
sb.Append("<boolean />");
}
public static void AddElem(string name, int e, StringBuilder sb)
{
sb.Append("<key>");
sb.Append(name);
sb.Append("</key>");
if(e == 0)
sb.Append("<integer />");
else
{
sb.Append("<integer>");
sb.Append(e.ToString());
sb.Append("</integer>");
}
}
public static void AddElem(string name, float e, StringBuilder sb)
{
sb.Append("<key>");
sb.Append(name);
sb.Append("</key>");
if(e == 0)
sb.Append("<real />");
else
{
sb.Append("<real>");
sb.Append(e.ToString(CultureInfo.InvariantCulture));
sb.Append("</real>");
}
}
public static void AddElem(string name, double e, StringBuilder sb)
{
sb.Append("<key>");
sb.Append(name);
sb.Append("</key>");
if(e == 0)
sb.Append("<real />");
else
{
sb.Append("<real>");
sb.Append(e.ToString(CultureInfo.InvariantCulture));
sb.Append("</real>");
}
}
public static void AddElem(string name, UUID e, StringBuilder sb)
{
sb.Append("<key>");
sb.Append(name);
sb.Append("</key>");
if(e == UUID.Zero)
sb.Append("<uuid />");
else
{
sb.Append("<uuid>");
EscapeToXML(e.ToString(), sb);
sb.Append("</uuid>");
}
}
public static void AddElem(string name, string e, StringBuilder sb)
{
sb.Append("<key>");
sb.Append(name);
sb.Append("</key>");
if(String.IsNullOrEmpty(e))
sb.Append("<string />");
else
{
sb.Append("<string>");
sb.Append(e.ToString());
sb.Append("</string>");
}
}
public static void AddRawElem(string name, string e, StringBuilder sb)
{
sb.Append("<key>");
sb.Append(name);
sb.Append("</key>");
if(String.IsNullOrEmpty(e))
sb.Append("<string />");
else
{
sb.Append("<string>");
sb.Append(e);
sb.Append("</string>");
}
}
public static void AddURIElem(string name, Uri e, StringBuilder sb)
{
sb.Append("<key>");
sb.Append(name);
sb.Append("</key>");
if(e == null)
{
sb.Append("<uri />");
return;
}
string s;
if (e.IsAbsoluteUri)
s = e.AbsoluteUri;
else
s = e.ToString();
if(String.IsNullOrEmpty(s))
sb.Append("<uri />");
else
{
sb.Append("<uri>");
sb.Append(s);
sb.Append("</uri>");
}
}
public static void AddElem(string name, DateTime e, StringBuilder sb)
{
sb.Append("<key>");
sb.Append(name);
sb.Append("</key>");
DateTime u = e.ToUniversalTime();
if(u == depoch)
{
sb.Append("<date />");
return;
}
string format;
if(u.Hour == 0 && u.Minute == 0 && u.Second == 0)
format = "yyyy-MM-dd";
else if (u.Millisecond > 0)
format = "yyyy-MM-ddTHH:mm:ss.ffZ";
else
format = "yyyy-MM-ddTHH:mm:ssZ";
sb.Append("<date>");
sb.Append(u.ToString(format,CultureInfo.InvariantCulture));
sb.Append("</date>");
}
public static void AddLLSD(string e, StringBuilder sb)
{
sb.Append(e);
}
public static void EscapeToXML(string s, StringBuilder sb)
{
int i;
char c;
String t;
int len = s.Length;
for (i = 0; i < len; i++)
{
c = s[i];
switch (c)
{
case '<':
sb.Append("&lt;");
break;
case '>':
sb.Append("&gt;");
break;
case '&':
sb.Append("&amp;");
break;
case '"':
sb.Append("&quot;");
break;
case '\\':
sb.Append("&apos;");
break;
default:
sb.Append(c);
break;
}
}
}
}
}

View File

@ -1824,10 +1824,15 @@ namespace OpenSim.Region.ClientStack.Linden
Dictionary<UUID,string> names = m_UserManager.GetUsersNames(ids); Dictionary<UUID,string> names = m_UserManager.GetUsersNames(ids);
OSDMap osdReply = new OSDMap(); StringBuilder lsl = new StringBuilder(names.Count * 256 + 256);
OSDArray agents = new OSDArray(); LLSDxmlEncode.AddStartHeader(lsl);
LLSDxmlEncode.AddStartMap(lsl);
if(names.Count == 0)
LLSDxmlEncode.AddEmpyArray("agents", lsl);
else
{
LLSDxmlEncode.AddStartArray("agents", lsl);
osdReply["agents"] = agents;
foreach (KeyValuePair<UUID,string> kvp in names) foreach (KeyValuePair<UUID,string> kvp in names)
{ {
if (string.IsNullOrEmpty(kvp.Value)) if (string.IsNullOrEmpty(kvp.Value))
@ -1836,40 +1841,34 @@ namespace OpenSim.Region.ClientStack.Linden
continue; continue;
string[] parts = kvp.Value.Split(new char[] {' '}); string[] parts = kvp.Value.Split(new char[] {' '});
OSDMap osdname = new OSDMap();
// dont tell about unknown users, we can't send them back on Bad either // dont tell about unknown users, we can't send them back on Bad either
if(parts[0] == "Unknown") if(parts[0] == "Unknown")
continue; continue;
/*
if(parts[0] == "Unknown")
{
osdname["display_name_next_update"] = OSD.FromDate(DateTime.UtcNow.AddHours(1));
osdname["display_name_expires"] = OSD.FromDate(DateTime.UtcNow.AddHours(2));
}
else
*/
{
osdname["display_name_next_update"] = OSD.FromDate(DateTime.UtcNow.AddDays(8));
osdname["display_name_expires"] = OSD.FromDate(DateTime.UtcNow.AddMonths(1));
}
osdname["display_name"] = OSD.FromString(kvp.Value);
osdname["legacy_first_name"] = parts[0];
osdname["legacy_last_name"] = parts[1];
osdname["username"] = OSD.FromString(kvp.Value);
osdname["id"] = OSD.FromUUID(kvp.Key);
osdname["is_display_name_default"] = OSD.FromBoolean(true);
agents.Add(osdname); LLSDxmlEncode.AddStartMap(lsl);
LLSDxmlEncode.AddElem("display_name_next_update", DateTime.UtcNow.AddDays(8), lsl);
LLSDxmlEncode.AddElem("display_name_expires", DateTime.UtcNow.AddMonths(1), lsl);
LLSDxmlEncode.AddElem("display_name", kvp.Value, lsl);
LLSDxmlEncode.AddElem("legacy_first_name", parts[0], lsl);
LLSDxmlEncode.AddElem("legacy_last_name", parts[1], lsl);
LLSDxmlEncode.AddElem("username", kvp.Value, lsl);
LLSDxmlEncode.AddElem("id", kvp.Key, lsl);
LLSDxmlEncode.AddElem("is_display_name_default", true, lsl);
LLSDxmlEncode.AddEndMap(lsl);
} }
LLSDxmlEncode.AddEndArray(lsl);
}
LLSDxmlEncode.AddEndMap(lsl);
LLSDxmlEncode.AddEndHeader(lsl);
// Full content request // Full content request
httpResponse.StatusCode = (int)System.Net.HttpStatusCode.OK; httpResponse.StatusCode = (int)System.Net.HttpStatusCode.OK;
//httpResponse.ContentLength = ??; //httpResponse.ContentLength = ??;
httpResponse.ContentType = "application/llsd+xml"; httpResponse.ContentType = "application/llsd+xml";
string reply = OSDParser.SerializeLLSDXmlString(osdReply); return lsl.ToString();
return reply;
} }
} }