From d15a3b10a3031b9552d67d2e2d435a689b448e2f Mon Sep 17 00:00:00 2001 From: Oren Hurvitz Date: Thu, 24 Apr 2014 14:19:03 +0300 Subject: When sending JSON-RPC calls (for UserProfile), use WebUtil instead of constructing the HTTP requests manually. This allows the calls to be logged when using "debug http all 6". --- OpenSim/Data/MySQL/MySQLUserProfilesData.cs | 5 - OpenSim/Data/SQLite/SQLiteUserProfilesData.cs | 6 - .../Servers/HttpServer/JsonRpcRequestManager.cs | 175 +++++++++------------ OpenSim/Framework/WebUtil.cs | 24 +-- .../Simulation/SimulationServiceConnector.cs | 10 +- 5 files changed, 94 insertions(+), 126 deletions(-) diff --git a/OpenSim/Data/MySQL/MySQLUserProfilesData.cs b/OpenSim/Data/MySQL/MySQLUserProfilesData.cs index cc4c5b0..e301bbe 100644 --- a/OpenSim/Data/MySQL/MySQLUserProfilesData.cs +++ b/OpenSim/Data/MySQL/MySQLUserProfilesData.cs @@ -634,8 +634,6 @@ namespace OpenSim.Data.MySQL { if(reader.HasRows) { - m_log.DebugFormat("[PROFILES_DATA]" + - ": Getting data for {0}.", props.UserId); reader.Read(); props.WebUrl = (string)reader["profileURL"]; UUID.TryParse((string)reader["profileImage"], out props.ImageId); @@ -651,9 +649,6 @@ namespace OpenSim.Data.MySQL } else { - m_log.DebugFormat("[PROFILES_DATA]" + - ": No data for {0}", props.UserId); - props.WebUrl = string.Empty; props.ImageId = UUID.Zero; props.AboutText = string.Empty; diff --git a/OpenSim/Data/SQLite/SQLiteUserProfilesData.cs b/OpenSim/Data/SQLite/SQLiteUserProfilesData.cs index 0f5b4c8..5494091 100644 --- a/OpenSim/Data/SQLite/SQLiteUserProfilesData.cs +++ b/OpenSim/Data/SQLite/SQLiteUserProfilesData.cs @@ -584,9 +584,6 @@ namespace OpenSim.Data.SQLite } if(reader != null && reader.Read()) { - m_log.DebugFormat("[PROFILES_DATA]" + - ": Getting data for {0}.", props.UserId); - props.WebUrl = (string)reader["profileURL"]; UUID.TryParse((string)reader["profileImage"], out props.ImageId); props.AboutText = (string)reader["profileAboutText"]; @@ -601,9 +598,6 @@ namespace OpenSim.Data.SQLite } else { - m_log.DebugFormat("[PROFILES_DATA]" + - ": No data for {0}", props.UserId); - props.WebUrl = string.Empty; props.ImageId = UUID.Zero; props.AboutText = string.Empty; diff --git a/OpenSim/Framework/Servers/HttpServer/JsonRpcRequestManager.cs b/OpenSim/Framework/Servers/HttpServer/JsonRpcRequestManager.cs index a44f471..ed6a14c 100644 --- a/OpenSim/Framework/Servers/HttpServer/JsonRpcRequestManager.cs +++ b/OpenSim/Framework/Servers/HttpServer/JsonRpcRequestManager.cs @@ -48,7 +48,6 @@ namespace OpenSim.Framework.Servers.HttpServer { } - #region Web Util /// /// Sends json-rpc request with a serializable type. /// @@ -70,64 +69,62 @@ namespace OpenSim.Framework.Servers.HttpServer public bool JsonRpcRequest(ref object parameters, string method, string uri, string jsonId) { if (jsonId == null) - throw new ArgumentNullException ("jsonId"); + throw new ArgumentNullException("jsonId"); if (uri == null) - throw new ArgumentNullException ("uri"); + throw new ArgumentNullException("uri"); if (method == null) - throw new ArgumentNullException ("method"); + throw new ArgumentNullException("method"); if (parameters == null) - throw new ArgumentNullException ("parameters"); - - // Prep our payload - OSDMap json = new OSDMap(); - - json.Add("jsonrpc", OSD.FromString("2.0")); - json.Add("id", OSD.FromString(jsonId)); - json.Add("method", OSD.FromString(method)); - - json.Add("params", OSD.SerializeMembers(parameters)); - - string jsonRequestData = OSDParser.SerializeJsonString(json); - byte[] content = Encoding.UTF8.GetBytes(jsonRequestData); - - HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(uri); - - webRequest.ContentType = "application/json-rpc"; - webRequest.Method = "POST"; - - //Stream dataStream = webRequest.GetRequestStream(); - //dataStream.Write(content, 0, content.Length); - //dataStream.Close(); - - using (Stream dataStream = webRequest.GetRequestStream()) - dataStream.Write(content, 0, content.Length); - - WebResponse webResponse = null; + throw new ArgumentNullException("parameters"); + + OSDMap request = new OSDMap(); + request.Add("jsonrpc", OSD.FromString("2.0")); + request.Add("id", OSD.FromString(jsonId)); + request.Add("method", OSD.FromString(method)); + request.Add("params", OSD.SerializeMembers(parameters)); + + OSDMap response; try { - webResponse = webRequest.GetResponse(); + response = WebUtil.PostToService(uri, request, 10000, true); + } + catch (Exception e) + { + m_log.Debug(string.Format("JsonRpc request '{0}' failed", method), e); + return false; + } + + if (!response.ContainsKey("_Result")) + { + m_log.DebugFormat("JsonRpc request '{0}' returned an invalid response: {1}", + method, OSDParser.SerializeJsonString(response)); + return false; } - catch (WebException e) + response = (OSDMap)response["_Result"]; + + OSD data; + + if (response.ContainsKey("error")) { - Console.WriteLine("Web Error" + e.Message); - Console.WriteLine ("Please check input"); + data = response["error"]; + m_log.DebugFormat("JsonRpc request '{0}' returned an error: {1}", + method, OSDParser.SerializeJsonString(data)); return false; } - - using (webResponse) - using (Stream rstream = webResponse.GetResponseStream()) + + if (!response.ContainsKey("result")) { - OSDMap mret = (OSDMap)OSDParser.DeserializeJson(rstream); - - if (mret.ContainsKey("error")) - return false; - - // get params... - OSD.DeserializeMembers(ref parameters, (OSDMap)mret["result"]); - return true; + m_log.DebugFormat("JsonRpc request '{0}' returned an invalid response: {1}", + method, OSDParser.SerializeJsonString(response)); + return false; } + + data = response["result"]; + OSD.DeserializeMembers(ref parameters, (OSDMap)data); + + return true; } - + /// /// Sends json-rpc request with OSD parameter. /// @@ -135,7 +132,7 @@ namespace OpenSim.Framework.Servers.HttpServer /// The rpc request. /// /// - /// data - incoming as parameters, outgong as result/error + /// data - incoming as parameters, outgoing as result/error /// /// /// Json-rpc method to call. @@ -148,64 +145,46 @@ namespace OpenSim.Framework.Servers.HttpServer /// public bool JsonRpcRequest(ref OSD data, string method, string uri, string jsonId) { - OSDMap map = new OSDMap(); - - map["jsonrpc"] = "2.0"; - if(string.IsNullOrEmpty(jsonId)) - map["id"] = UUID.Random().ToString(); - else - map["id"] = jsonId; - - map["method"] = method; - map["params"] = data; - - string jsonRequestData = OSDParser.SerializeJsonString(map); - byte[] content = Encoding.UTF8.GetBytes(jsonRequestData); - - HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(uri); - webRequest.ContentType = "application/json-rpc"; - webRequest.Method = "POST"; - - using (Stream dataStream = webRequest.GetRequestStream()) - dataStream.Write(content, 0, content.Length); - - WebResponse webResponse = null; + if (string.IsNullOrEmpty(jsonId)) + jsonId = UUID.Random().ToString(); + + OSDMap request = new OSDMap(); + request.Add("jsonrpc", OSD.FromString("2.0")); + request.Add("id", OSD.FromString(jsonId)); + request.Add("method", OSD.FromString(method)); + request.Add("params", data); + + OSDMap response; try { - webResponse = webRequest.GetResponse(); + response = WebUtil.PostToService(uri, request, 10000, true); } - catch (WebException e) + catch (Exception e) { - Console.WriteLine("Web Error" + e.Message); - Console.WriteLine ("Please check input"); + m_log.Debug(string.Format("JsonRpc request '{0}' failed", method), e); return false; } - - using (webResponse) - using (Stream rstream = webResponse.GetResponseStream()) + + if (!response.ContainsKey("_Result")) { - OSDMap response = new OSDMap(); - try - { - response = (OSDMap)OSDParser.DeserializeJson(rstream); - } - catch (Exception e) - { - m_log.DebugFormat("[JSONRPC]: JsonRpcRequest Error {0}", e.Message); - return false; - } - - if (response.ContainsKey("error")) - { - data = response["error"]; - return false; - } - - data = response; - - return true; + m_log.DebugFormat("JsonRpc request '{0}' returned an invalid response: {1}", + method, OSDParser.SerializeJsonString(response)); + return false; } + response = (OSDMap)response["_Result"]; + + if (response.ContainsKey("error")) + { + data = response["error"]; + m_log.DebugFormat("JsonRpc request '{0}' returned an error: {1}", + method, OSDParser.SerializeJsonString(data)); + return false; + } + + data = response; + + return true; } - #endregion Web Util + } } diff --git a/OpenSim/Framework/WebUtil.cs b/OpenSim/Framework/WebUtil.cs index 768ff16..8f5bc0c 100644 --- a/OpenSim/Framework/WebUtil.cs +++ b/OpenSim/Framework/WebUtil.cs @@ -127,41 +127,41 @@ namespace OpenSim.Framework /// public static OSDMap PutToServiceCompressed(string url, OSDMap data, int timeout) { - return ServiceOSDRequest(url,data, "PUT", timeout, true); + return ServiceOSDRequest(url,data, "PUT", timeout, true, false); } public static OSDMap PutToService(string url, OSDMap data, int timeout) { - return ServiceOSDRequest(url,data, "PUT", timeout, false); + return ServiceOSDRequest(url,data, "PUT", timeout, false, false); } - public static OSDMap PostToService(string url, OSDMap data, int timeout) + public static OSDMap PostToService(string url, OSDMap data, int timeout, bool rpc) { - return ServiceOSDRequest(url, data, "POST", timeout, false); + return ServiceOSDRequest(url, data, "POST", timeout, false, rpc); } public static OSDMap PostToServiceCompressed(string url, OSDMap data, int timeout) { - return ServiceOSDRequest(url, data, "POST", timeout, true); + return ServiceOSDRequest(url, data, "POST", timeout, true, false); } public static OSDMap GetFromService(string url, int timeout) { - return ServiceOSDRequest(url, null, "GET", timeout, false); + return ServiceOSDRequest(url, null, "GET", timeout, false, false); } - - public static OSDMap ServiceOSDRequest(string url, OSDMap data, string method, int timeout, bool compressed) + + public static OSDMap ServiceOSDRequest(string url, OSDMap data, string method, int timeout, bool compressed, bool rpc) { if (SerializeOSDRequestsPerEndpoint) { lock (EndPointLock(url)) { - return ServiceOSDRequestWorker(url, data, method, timeout, compressed); + return ServiceOSDRequestWorker(url, data, method, timeout, compressed, rpc); } } else { - return ServiceOSDRequestWorker(url, data, method, timeout, compressed); + return ServiceOSDRequestWorker(url, data, method, timeout, compressed, rpc); } } @@ -217,7 +217,7 @@ namespace OpenSim.Framework LogOutgoingDetail("RESPONSE: ", input); } - private static OSDMap ServiceOSDRequestWorker(string url, OSDMap data, string method, int timeout, bool compressed) + private static OSDMap ServiceOSDRequestWorker(string url, OSDMap data, string method, int timeout, bool compressed, bool rpc) { int reqnum = RequestNumber++; @@ -251,7 +251,7 @@ namespace OpenSim.Framework byte[] buffer = System.Text.Encoding.UTF8.GetBytes(strBuffer); - request.ContentType = "application/json"; + request.ContentType = rpc ? "application/json-rpc" : "application/json"; if (compressed) { diff --git a/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs b/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs index a5520c4..d9fe5a0 100644 --- a/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs +++ b/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs @@ -136,7 +136,7 @@ namespace OpenSim.Services.Connectors.Simulation } // Try the old version, uncompressed - result = WebUtil.PostToService(uri, args, 30000); + result = WebUtil.PostToService(uri, args, 30000, false); if (result["Success"].AsBoolean()) { @@ -302,7 +302,7 @@ namespace OpenSim.Services.Connectors.Simulation try { - OSDMap result = WebUtil.ServiceOSDRequest(uri, request, "QUERYACCESS", 30000, false); + OSDMap result = WebUtil.ServiceOSDRequest(uri, request, "QUERYACCESS", 30000, false, false); bool success = result["success"].AsBoolean(); if (result.ContainsKey("_Result")) { @@ -365,7 +365,7 @@ namespace OpenSim.Services.Connectors.Simulation try { - WebUtil.ServiceOSDRequest(uri, null, "DELETE", 10000, false); + WebUtil.ServiceOSDRequest(uri, null, "DELETE", 10000, false, false); } catch (Exception e) { @@ -384,7 +384,7 @@ namespace OpenSim.Services.Connectors.Simulation try { - WebUtil.ServiceOSDRequest(uri, null, "DELETE", 10000, false); + WebUtil.ServiceOSDRequest(uri, null, "DELETE", 10000, false, false); } catch (Exception e) { @@ -431,7 +431,7 @@ namespace OpenSim.Services.Connectors.Simulation args["destination_name"] = OSD.FromString(destination.RegionName); args["destination_uuid"] = OSD.FromString(destination.RegionID.ToString()); - OSDMap result = WebUtil.PostToService(uri, args, 40000); + OSDMap result = WebUtil.PostToService(uri, args, 40000, false); if (result == null) return false; -- cgit v1.1 From d62f0bc35d966ca4099e43026b90ab24cd768e4b Mon Sep 17 00:00:00 2001 From: Oren Hurvitz Date: Sun, 2 Mar 2014 14:43:43 +0200 Subject: Refactored: moved OpenProfileClient to a location where it can be used by both the Simulators and Robust --- .../Avatar/UserProfiles/OpenProfileClient.cs | 193 --------------------- .../Avatar/UserProfiles/UserProfileModule.cs | 1 + OpenSim/Services/Interfaces/OpenProfileClient.cs | 193 +++++++++++++++++++++ prebuild.xml | 2 + 4 files changed, 196 insertions(+), 193 deletions(-) delete mode 100644 OpenSim/Region/CoreModules/Avatar/UserProfiles/OpenProfileClient.cs create mode 100644 OpenSim/Services/Interfaces/OpenProfileClient.cs diff --git a/OpenSim/Region/CoreModules/Avatar/UserProfiles/OpenProfileClient.cs b/OpenSim/Region/CoreModules/Avatar/UserProfiles/OpenProfileClient.cs deleted file mode 100644 index 23de3f5..0000000 --- a/OpenSim/Region/CoreModules/Avatar/UserProfiles/OpenProfileClient.cs +++ /dev/null @@ -1,193 +0,0 @@ -/* - * 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. - */ - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Linq; -using System.Net; -using System.Net.Sockets; -using System.Reflection; -using System.Text; -using System.Xml; -using log4net; -using Nwc.XmlRpc; -using OpenMetaverse; -using OpenSim.Framework; - -namespace OpenSim.Region.CoreModules.Avatar.UserProfiles -{ - /// - /// A client for accessing a profile server using the OpenProfile protocol. - /// - /// - /// This class was adapted from the full OpenProfile class. Since it's only a client, and not a server, - /// it's much simpler. - /// - public class OpenProfileClient - { - static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - - private string m_serverURI; - - /// - /// Creates a client for accessing a foreign grid's profile server using the OpenProfile protocol. - /// - /// The grid's profile server URL - public OpenProfileClient(string serverURI) - { - m_serverURI = serverURI; - } - - - /// - /// Gets an avatar's profile using the OpenProfile protocol. - /// - /// On success, this will contain the avatar's profile - /// Success/failure - /// - /// There are two profile modules currently in use in OpenSim: the older one is OpenProfile, and the newer - /// one is UserProfileModule (this file). This method attempts to read an avatar's profile from a foreign - /// grid using the OpenProfile protocol. - /// - public bool RequestAvatarPropertiesUsingOpenProfile(ref UserProfileProperties props) - { - Hashtable ReqHash = new Hashtable(); - ReqHash["avatar_id"] = props.UserId.ToString(); - - Hashtable profileData = GenericXMLRPCRequest(ReqHash, "avatar_properties_request", m_serverURI); - - ArrayList dataArray = (ArrayList)profileData["data"]; - - if (dataArray == null || dataArray[0] == null) - return false; - profileData = (Hashtable)dataArray[0]; - - props.WebUrl = string.Empty; - props.AboutText = String.Empty; - props.FirstLifeText = String.Empty; - props.ImageId = UUID.Zero; - props.FirstLifeImageId = UUID.Zero; - props.PartnerId = UUID.Zero; - - if (profileData["ProfileUrl"] != null) - props.WebUrl = profileData["ProfileUrl"].ToString(); - if (profileData["AboutText"] != null) - props.AboutText = profileData["AboutText"].ToString(); - if (profileData["FirstLifeAboutText"] != null) - props.FirstLifeText = profileData["FirstLifeAboutText"].ToString(); - if (profileData["Image"] != null) - props.ImageId = new UUID(profileData["Image"].ToString()); - if (profileData["FirstLifeImage"] != null) - props.FirstLifeImageId = new UUID(profileData["FirstLifeImage"].ToString()); - if (profileData["Partner"] != null) - props.PartnerId = new UUID(profileData["Partner"].ToString()); - - props.WantToMask = 0; - props.WantToText = String.Empty; - props.SkillsMask = 0; - props.SkillsText = String.Empty; - props.Language = String.Empty; - - if (profileData["wantmask"] != null) - props.WantToMask = Convert.ToInt32(profileData["wantmask"].ToString()); - if (profileData["wanttext"] != null) - props.WantToText = profileData["wanttext"].ToString(); - - if (profileData["skillsmask"] != null) - props.SkillsMask = Convert.ToInt32(profileData["skillsmask"].ToString()); - if (profileData["skillstext"] != null) - props.SkillsText = profileData["skillstext"].ToString(); - - if (profileData["languages"] != null) - props.Language = profileData["languages"].ToString(); - - return true; - } - - private Hashtable GenericXMLRPCRequest(Hashtable ReqParams, string method, string server) - { - ArrayList SendParams = new ArrayList(); - SendParams.Add(ReqParams); - - XmlRpcResponse Resp; - try - { - XmlRpcRequest Req = new XmlRpcRequest(method, SendParams); - Resp = Req.Send(server, 30000); - } - catch (WebException ex) - { - m_log.ErrorFormat("[PROFILE]: Unable to connect to Profile " + - "Server {0}. Exception {1}", server, ex); - - Hashtable ErrorHash = new Hashtable(); - ErrorHash["success"] = false; - ErrorHash["errorMessage"] = "Unable to fetch profile data at this time. "; - ErrorHash["errorURI"] = ""; - - return ErrorHash; - } - catch (SocketException ex) - { - m_log.ErrorFormat( - "[PROFILE]: Unable to connect to Profile Server {0}. Method {1}, params {2}. " + - "Exception {3}", server, method, ReqParams, ex); - - Hashtable ErrorHash = new Hashtable(); - ErrorHash["success"] = false; - ErrorHash["errorMessage"] = "Unable to fetch profile data at this time. "; - ErrorHash["errorURI"] = ""; - - return ErrorHash; - } - catch (XmlException ex) - { - m_log.ErrorFormat( - "[PROFILE]: Unable to connect to Profile Server {0}. Method {1}, params {2}. " + - "Exception {3}", server, method, ReqParams.ToString(), ex); - Hashtable ErrorHash = new Hashtable(); - ErrorHash["success"] = false; - ErrorHash["errorMessage"] = "Unable to fetch profile data at this time. "; - ErrorHash["errorURI"] = ""; - - return ErrorHash; - } - if (Resp.IsFault) - { - Hashtable ErrorHash = new Hashtable(); - ErrorHash["success"] = false; - ErrorHash["errorMessage"] = "Unable to fetch profile data at this time. "; - ErrorHash["errorURI"] = ""; - return ErrorHash; - } - Hashtable RespData = (Hashtable)Resp.Value; - - return RespData; - } - } -} diff --git a/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs b/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs index d05b1f6..3d45f1d 100644 --- a/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs @@ -47,6 +47,7 @@ using OpenSim.Services.Interfaces; using Mono.Addins; using OpenSim.Services.Connectors.Hypergrid; using OpenSim.Framework.Servers.HttpServer; +using OpenSim.Services.UserProfilesService; namespace OpenSim.Region.CoreModules.Avatar.UserProfiles { diff --git a/OpenSim/Services/Interfaces/OpenProfileClient.cs b/OpenSim/Services/Interfaces/OpenProfileClient.cs new file mode 100644 index 0000000..099b0c3 --- /dev/null +++ b/OpenSim/Services/Interfaces/OpenProfileClient.cs @@ -0,0 +1,193 @@ +/* + * 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. + */ + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Net; +using System.Net.Sockets; +using System.Reflection; +using System.Text; +using System.Xml; +using log4net; +using Nwc.XmlRpc; +using OpenMetaverse; +using OpenSim.Framework; + +namespace OpenSim.Services.UserProfilesService +{ + /// + /// A client for accessing a profile server using the OpenProfile protocol. + /// + /// + /// This class was adapted from the full OpenProfile class. Since it's only a client, and not a server, + /// it's much simpler. + /// + public class OpenProfileClient + { + static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + private string m_serverURI; + + /// + /// Creates a client for accessing a foreign grid's profile server using the OpenProfile protocol. + /// + /// The grid's profile server URL + public OpenProfileClient(string serverURI) + { + m_serverURI = serverURI; + } + + + /// + /// Gets an avatar's profile using the OpenProfile protocol. + /// + /// On success, this will contain the avatar's profile + /// Success/failure + /// + /// There are two profile modules currently in use in OpenSim: the older one is OpenProfile, and the newer + /// one is UserProfileModule (this file). This method attempts to read an avatar's profile from a foreign + /// grid using the OpenProfile protocol. + /// + public bool RequestAvatarPropertiesUsingOpenProfile(ref UserProfileProperties props) + { + Hashtable ReqHash = new Hashtable(); + ReqHash["avatar_id"] = props.UserId.ToString(); + + Hashtable profileData = GenericXMLRPCRequest(ReqHash, "avatar_properties_request", m_serverURI); + + ArrayList dataArray = (ArrayList)profileData["data"]; + + if (dataArray == null || dataArray[0] == null) + return false; + profileData = (Hashtable)dataArray[0]; + + props.WebUrl = string.Empty; + props.AboutText = String.Empty; + props.FirstLifeText = String.Empty; + props.ImageId = UUID.Zero; + props.FirstLifeImageId = UUID.Zero; + props.PartnerId = UUID.Zero; + + if (profileData["ProfileUrl"] != null) + props.WebUrl = profileData["ProfileUrl"].ToString(); + if (profileData["AboutText"] != null) + props.AboutText = profileData["AboutText"].ToString(); + if (profileData["FirstLifeAboutText"] != null) + props.FirstLifeText = profileData["FirstLifeAboutText"].ToString(); + if (profileData["Image"] != null) + props.ImageId = new UUID(profileData["Image"].ToString()); + if (profileData["FirstLifeImage"] != null) + props.FirstLifeImageId = new UUID(profileData["FirstLifeImage"].ToString()); + if (profileData["Partner"] != null) + props.PartnerId = new UUID(profileData["Partner"].ToString()); + + props.WantToMask = 0; + props.WantToText = String.Empty; + props.SkillsMask = 0; + props.SkillsText = String.Empty; + props.Language = String.Empty; + + if (profileData["wantmask"] != null) + props.WantToMask = Convert.ToInt32(profileData["wantmask"].ToString()); + if (profileData["wanttext"] != null) + props.WantToText = profileData["wanttext"].ToString(); + + if (profileData["skillsmask"] != null) + props.SkillsMask = Convert.ToInt32(profileData["skillsmask"].ToString()); + if (profileData["skillstext"] != null) + props.SkillsText = profileData["skillstext"].ToString(); + + if (profileData["languages"] != null) + props.Language = profileData["languages"].ToString(); + + return true; + } + + private Hashtable GenericXMLRPCRequest(Hashtable ReqParams, string method, string server) + { + ArrayList SendParams = new ArrayList(); + SendParams.Add(ReqParams); + + XmlRpcResponse Resp; + try + { + XmlRpcRequest Req = new XmlRpcRequest(method, SendParams); + Resp = Req.Send(server, 30000); + } + catch (WebException ex) + { + m_log.ErrorFormat("[PROFILE]: Unable to connect to Profile " + + "Server {0}. Exception {1}", server, ex); + + Hashtable ErrorHash = new Hashtable(); + ErrorHash["success"] = false; + ErrorHash["errorMessage"] = "Unable to fetch profile data at this time. "; + ErrorHash["errorURI"] = ""; + + return ErrorHash; + } + catch (SocketException ex) + { + m_log.ErrorFormat( + "[PROFILE]: Unable to connect to Profile Server {0}. Method {1}, params {2}. " + + "Exception {3}", server, method, ReqParams, ex); + + Hashtable ErrorHash = new Hashtable(); + ErrorHash["success"] = false; + ErrorHash["errorMessage"] = "Unable to fetch profile data at this time. "; + ErrorHash["errorURI"] = ""; + + return ErrorHash; + } + catch (XmlException ex) + { + m_log.ErrorFormat( + "[PROFILE]: Unable to connect to Profile Server {0}. Method {1}, params {2}. " + + "Exception {3}", server, method, ReqParams.ToString(), ex); + Hashtable ErrorHash = new Hashtable(); + ErrorHash["success"] = false; + ErrorHash["errorMessage"] = "Unable to fetch profile data at this time. "; + ErrorHash["errorURI"] = ""; + + return ErrorHash; + } + if (Resp.IsFault) + { + Hashtable ErrorHash = new Hashtable(); + ErrorHash["success"] = false; + ErrorHash["errorMessage"] = "Unable to fetch profile data at this time. "; + ErrorHash["errorURI"] = ""; + return ErrorHash; + } + Hashtable RespData = (Hashtable)Resp.Value; + + return RespData; + } + } +} diff --git a/prebuild.xml b/prebuild.xml index 09c429a..577251b 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -133,6 +133,8 @@ + + -- cgit v1.1 From e8a2eff2e83cba74e84970136dd486beededc1de Mon Sep 17 00:00:00 2001 From: Oren Hurvitz Date: Thu, 24 Apr 2014 14:20:48 +0300 Subject: Changed how UserProfile performs a fallback call using the OpenProfile API, because now JsonRpcRequest() returns an error result instead of throwing an exception --- .../Avatar/UserProfiles/UserProfileModule.cs | 67 ++++++++++++---------- 1 file changed, 37 insertions(+), 30 deletions(-) diff --git a/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs b/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs index 3d45f1d..1ee2a7b 100644 --- a/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs @@ -65,6 +65,8 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles Dictionary m_classifiedCache = new Dictionary(); Dictionary m_classifiedInterest = new Dictionary(); + private JsonRpcRequestManager rpc = new JsonRpcRequestManager(); + public Scene Scene { get; private set; @@ -114,7 +116,6 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles set; } - JsonRpcRequestManager rpc = new JsonRpcRequestManager(); #region IRegionModuleBase implementation /// @@ -920,7 +921,7 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles public void RequestAvatarProperties(IClientAPI remoteClient, UUID avatarID) { - if ( String.IsNullOrEmpty(avatarID.ToString()) || String.IsNullOrEmpty(remoteClient.AgentId.ToString())) + if (String.IsNullOrEmpty(avatarID.ToString()) || String.IsNullOrEmpty(remoteClient.AgentId.ToString())) { // Looking for a reason that some viewers are sending null Id's m_log.DebugFormat("[PROFILES]: This should not happen remoteClient.AgentId {0} - avatarID {1}", remoteClient.AgentId, avatarID); @@ -998,29 +999,10 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles props.UserId = avatarID; - try - { - GetProfileData(ref props, out result); - } - catch (Exception e) + if (!GetProfileData(ref props, foreign, out result)) { - if (foreign) - { - // Check if the foreign grid is using OpenProfile. - // If any error occurs then discard it, and report the original error. - try - { - OpenProfileClient client = new OpenProfileClient(serverURI); - if (!client.RequestAvatarPropertiesUsingOpenProfile(ref props)) - throw e; - } - catch (Exception) - { - throw e; - } - } - else - throw; + m_log.DebugFormat("Error getting profile for {0}: {1}", avatarID, result); + return; } remoteClient.SendAvatarProperties(props.UserId, props.AboutText, born, charterMember , props.FirstLifeText, flags, @@ -1074,10 +1056,7 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles /// /// The profile data. /// - /// - /// User I. - /// - bool GetProfileData(ref UserProfileProperties properties, out string message) + bool GetProfileData(ref UserProfileProperties properties, bool foreign, out string message) { // Can't handle NPC yet... ScenePresence p = FindPresence(properties.UserId); @@ -1096,14 +1075,42 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles // This is checking a friend on the home grid // Not HG friend - if ( String.IsNullOrEmpty(serverURI)) + if (String.IsNullOrEmpty(serverURI)) { message = "No Presence - foreign friend"; return false; } object Prop = (object)properties; - rpc.JsonRpcRequest(ref Prop, "avatar_properties_request", serverURI, UUID.Random().ToString()); + if (!rpc.JsonRpcRequest(ref Prop, "avatar_properties_request", serverURI, UUID.Random().ToString())) + { + // If it's a foreign user then try again using OpenProfile, in case that's what the grid is using + bool secondChanceSuccess = false; + if (foreign) + { + try + { + OpenProfileClient client = new OpenProfileClient(serverURI); + if (client.RequestAvatarPropertiesUsingOpenProfile(ref properties)) + secondChanceSuccess = true; + } + catch (Exception e) + { + m_log.Debug(string.Format("Request using the OpenProfile API to {0} failed", serverURI), e); + // Allow the return 'message' to say "JsonRpcRequest" and not "OpenProfile", because + // the most likely reason that OpenProfile failed is that the remote server + // doesn't support OpenProfile, and that's not very interesting. + } + } + + if (!secondChanceSuccess) + { + message = string.Format("JsonRpcRequest to {0} failed", serverURI); + return false; + } + // else, continue below + } + properties = (UserProfileProperties)Prop; message = "Success"; -- cgit v1.1 From bc06db3df45d8dd61338c5b1426fd0161731f7cd Mon Sep 17 00:00:00 2001 From: Oren Hurvitz Date: Thu, 24 Apr 2014 14:21:05 +0300 Subject: - Created a standard function to send XML-RPC requests, which logs them like we do for other types of HTTP activity. - Changed OpenProfileClient to use the new XML-RPC sending function - Improved logging in WebUtil --- .../Framework/Servers/HttpServer/BaseHttpServer.cs | 2 +- OpenSim/Framework/WebUtil.cs | 212 ++++++++++++++------- OpenSim/Services/Interfaces/OpenProfileClient.cs | 69 +------ prebuild.xml | 2 +- 4 files changed, 146 insertions(+), 139 deletions(-) diff --git a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs index 4f71db9..e8aa278 100644 --- a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs +++ b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs @@ -705,7 +705,7 @@ namespace OpenSim.Framework.Servers.HttpServer } } - WebUtil.LogResponseDetail(output); + WebUtil.LogResponseDetail(null, output); } if (!response.SendChunked && response.ContentLength64 <= 0) diff --git a/OpenSim/Framework/WebUtil.cs b/OpenSim/Framework/WebUtil.cs index 8f5bc0c..d7f6bc8 100644 --- a/OpenSim/Framework/WebUtil.cs +++ b/OpenSim/Framework/WebUtil.cs @@ -39,7 +39,9 @@ using System.Text; using System.Web; using System.Xml; using System.Xml.Serialization; +using System.Xml.Linq; using log4net; +using Nwc.XmlRpc; using OpenMetaverse.StructuredData; using XMLResponseHelper = OpenSim.Framework.SynchronousRestObjectRequester.XMLResponseHelper; @@ -191,9 +193,9 @@ namespace OpenSim.Framework } } - public static void LogOutgoingDetail(string output) + public static void LogOutgoingDetail(string type, int reqnum, string output) { - LogOutgoingDetail("", output); + LogOutgoingDetail(string.Format("{0} {1}: ", type, reqnum), output); } public static void LogOutgoingDetail(string context, string output) @@ -207,14 +209,15 @@ namespace OpenSim.Framework m_log.DebugFormat("[LOGHTTP]: {0}{1}", context, Util.BinaryToASCII(output)); } - public static void LogResponseDetail(Stream inputStream) + public static void LogResponseDetail(int reqnum, Stream inputStream) { - LogOutgoingDetail("RESPONSE: ", inputStream); + LogOutgoingDetail(string.Format("RESPONSE {0}: ", reqnum), inputStream); } - public static void LogResponseDetail(string input) + public static void LogResponseDetail(int? reqnum, string input) { - LogOutgoingDetail("RESPONSE: ", input); + string context = (reqnum == null) ? "" : string.Format("RESPONSE {0}: ", reqnum.Value); + LogOutgoingDetail(context, input); } private static OSDMap ServiceOSDRequestWorker(string url, OSDMap data, string method, int timeout, bool compressed, bool rpc) @@ -222,9 +225,8 @@ namespace OpenSim.Framework int reqnum = RequestNumber++; if (DebugLevel >= 3) - m_log.DebugFormat( - "[LOGHTTP]: HTTP OUT {0} ServiceOSD {1} {2} (timeout {3}, compressed {4})", - reqnum, method, url, timeout, compressed); + m_log.DebugFormat("[LOGHTTP]: HTTP OUT {0} JSON-RPC {1} to {2}", + reqnum, method, url); string errorMessage = "unknown error"; int tickstart = Util.EnvironmentTickCount(); @@ -247,7 +249,7 @@ namespace OpenSim.Framework strBuffer = OSDParser.SerializeJsonString(data); if (DebugLevel >= 5) - LogOutgoingDetail(strBuffer); + LogOutgoingDetail("SEND", reqnum, strBuffer); byte[] buffer = System.Text.Encoding.UTF8.GetBytes(strBuffer); @@ -291,9 +293,8 @@ namespace OpenSim.Framework using (StreamReader reader = new StreamReader(responseStream)) { string responseStr = reader.ReadToEnd(); - // m_log.DebugFormat("[LOGHTTP]: <{0}> response is <{1}>",reqnum,responseStr); if (WebUtil.DebugLevel >= 5) - WebUtil.LogResponseDetail(responseStr); + WebUtil.LogResponseDetail(reqnum, responseStr); return CanonicalizeResults(responseStr); } } @@ -316,24 +317,23 @@ namespace OpenSim.Framework { int tickdiff = Util.EnvironmentTickCountSubtract(tickstart); if (tickdiff > LongCallTime) + { m_log.InfoFormat( - "[LOGHTTP]: Slow ServiceOSD request {0} {1} {2} took {3}ms, {4}ms writing, {5}", - reqnum, - method, - url, - tickdiff, - tickdata, + "[LOGHTTP]: Slow JSON-RPC request {0} {1} to {2} took {3}ms, {4}ms writing, {5}", + reqnum, method, url, tickdiff, tickdata, strBuffer != null ? (strBuffer.Length > MaxRequestDiagLength ? strBuffer.Remove(MaxRequestDiagLength) : strBuffer) : ""); + } else if (DebugLevel >= 4) - m_log.DebugFormat( - "[LOGHTTP]: HTTP OUT {0} took {1}ms, {2}ms writing", + { + m_log.DebugFormat("[LOGHTTP]: HTTP OUT {0} took {1}ms, {2}ms writing", reqnum, tickdiff, tickdata); + } } m_log.DebugFormat( - "[LOGHTTP]: ServiceOSD request {0} {1} {2} FAILED: {3}", reqnum, url, method, errorMessage); + "[LOGHTTP]: JSON-RPC request {0} {1} to {2} FAILED: {3}", reqnum, method, url, errorMessage); return ErrorResponseMap(errorMessage); } @@ -411,9 +411,8 @@ namespace OpenSim.Framework string method = (data != null && data["RequestMethod"] != null) ? data["RequestMethod"] : "unknown"; if (DebugLevel >= 3) - m_log.DebugFormat( - "[LOGHTTP]: HTTP OUT {0} ServiceForm {1} {2} (timeout {3})", - reqnum, method, url, timeout); + m_log.DebugFormat("[LOGHTTP]: HTTP OUT {0} ServiceForm '{1}' to {2}", + reqnum, method, url); string errorMessage = "unknown error"; int tickstart = Util.EnvironmentTickCount(); @@ -435,7 +434,7 @@ namespace OpenSim.Framework queryString = BuildQueryString(data); if (DebugLevel >= 5) - LogOutgoingDetail(queryString); + LogOutgoingDetail("SEND", reqnum, queryString); byte[] buffer = System.Text.Encoding.UTF8.GetBytes(queryString); @@ -457,7 +456,7 @@ namespace OpenSim.Framework { string responseStr = reader.ReadToEnd(); if (WebUtil.DebugLevel >= 5) - WebUtil.LogResponseDetail(responseStr); + WebUtil.LogResponseDetail(reqnum, responseStr); OSD responseOSD = OSDParser.Deserialize(responseStr); if (responseOSD.Type == OSDType.Map) @@ -483,23 +482,22 @@ namespace OpenSim.Framework { int tickdiff = Util.EnvironmentTickCountSubtract(tickstart); if (tickdiff > LongCallTime) + { m_log.InfoFormat( - "[LOGHTTP]: Slow ServiceForm request {0} {1} {2} took {3}ms, {4}ms writing, {5}", - reqnum, - method, - url, - tickdiff, - tickdata, + "[LOGHTTP]: Slow ServiceForm request {0} '{1}' to {2} took {3}ms, {4}ms writing, {5}", + reqnum, method, url, tickdiff, tickdata, queryString != null ? (queryString.Length > MaxRequestDiagLength) ? queryString.Remove(MaxRequestDiagLength) : queryString : ""); + } else if (DebugLevel >= 4) - m_log.DebugFormat( - "[LOGHTTP]: HTTP OUT {0} took {1}ms, {2}ms writing", + { + m_log.DebugFormat("[LOGHTTP]: HTTP OUT {0} took {1}ms, {2}ms writing", reqnum, tickdiff, tickdata); + } } - m_log.WarnFormat("[LOGHTTP]: ServiceForm request {0} {1} {2} failed: {2}", reqnum, method, url, errorMessage); + m_log.WarnFormat("[LOGHTTP]: ServiceForm request {0} '{1}' to {2} failed: {3}", reqnum, method, url, errorMessage); return ErrorResponseMap(errorMessage); } @@ -779,8 +777,7 @@ namespace OpenSim.Framework int reqnum = WebUtil.RequestNumber++; if (WebUtil.DebugLevel >= 3) - m_log.DebugFormat( - "[LOGHTTP]: HTTP OUT {0} AsynchronousRequestObject {1} {2}", + m_log.DebugFormat("[LOGHTTP]: HTTP OUT {0} AsynchronousRequestObject {1} to {2}", reqnum, verb, requestUrl); int tickstart = Util.EnvironmentTickCount(); @@ -822,7 +819,7 @@ namespace OpenSim.Framework byte[] data = buffer.ToArray(); if (WebUtil.DebugLevel >= 5) - WebUtil.LogOutgoingDetail(System.Text.Encoding.UTF8.GetString(data)); + WebUtil.LogOutgoingDetail("SEND", reqnum, System.Text.Encoding.UTF8.GetString(data)); request.BeginGetRequestStream(delegate(IAsyncResult res) { @@ -840,7 +837,8 @@ namespace OpenSim.Framework { using (Stream respStream = response.GetResponseStream()) { - deserial = XMLResponseHelper.LogAndDeserialize(respStream, response.ContentLength); + deserial = XMLResponseHelper.LogAndDeserialize( + reqnum, respStream, response.ContentLength); } } catch (System.InvalidOperationException) @@ -867,7 +865,8 @@ namespace OpenSim.Framework { using (Stream respStream = response.GetResponseStream()) { - deserial = XMLResponseHelper.LogAndDeserialize(respStream, response.ContentLength); + deserial = XMLResponseHelper.LogAndDeserialize( + reqnum, respStream, response.ContentLength); } } catch (System.InvalidOperationException) @@ -938,18 +937,13 @@ namespace OpenSim.Framework } m_log.InfoFormat( - "[LOGHTTP]: [ASYNC REQUEST]: Slow request {0} {1} {2} took {3}ms, {4}ms writing, {5}", - reqnum, - verb, - requestUrl, - tickdiff, - tickdata, + "[LOGHTTP]: Slow AsynchronousRequestObject request {0} {1} to {2} took {3}ms, {4}ms writing, {5}", + reqnum, verb, requestUrl, tickdiff, tickdata, originalRequest); } else if (WebUtil.DebugLevel >= 4) { - m_log.DebugFormat( - "[LOGHTTP]: HTTP OUT {0} took {1}ms, {2}ms writing", + m_log.DebugFormat("[LOGHTTP]: HTTP OUT {0} took {1}ms, {2}ms writing", reqnum, tickdiff, tickdata); } } @@ -981,8 +975,7 @@ namespace OpenSim.Framework int reqnum = WebUtil.RequestNumber++; if (WebUtil.DebugLevel >= 3) - m_log.DebugFormat( - "[LOGHTTP]: HTTP OUT {0} SynchronousRestForms {1} {2}", + m_log.DebugFormat("[LOGHTTP]: HTTP OUT {0} SynchronousRestForms {1} to {2}", reqnum, verb, requestUrl); int tickstart = Util.EnvironmentTickCount(); @@ -1012,7 +1005,7 @@ namespace OpenSim.Framework byte[] data = buffer.ToArray(); if (WebUtil.DebugLevel >= 5) - WebUtil.LogOutgoingDetail(System.Text.Encoding.UTF8.GetString(data)); + WebUtil.LogOutgoingDetail("SEND", reqnum, System.Text.Encoding.UTF8.GetString(data)); Stream requestStream = null; try @@ -1058,21 +1051,20 @@ namespace OpenSim.Framework int tickdiff = Util.EnvironmentTickCountSubtract(tickstart); if (tickdiff > WebUtil.LongCallTime) + { m_log.InfoFormat( - "[LOGHTTP]: [FORMS]: Slow request {0} {1} {2} took {3}ms, {4}ms writing, {5}", - reqnum, - verb, - requestUrl, - tickdiff, - tickdata, + "[LOGHTTP]: Slow SynchronousRestForms request {0} {1} to {2} took {3}ms, {4}ms writing, {5}", + reqnum, verb, requestUrl, tickdiff, tickdata, obj.Length > WebUtil.MaxRequestDiagLength ? obj.Remove(WebUtil.MaxRequestDiagLength) : obj); + } else if (WebUtil.DebugLevel >= 4) - m_log.DebugFormat( - "[LOGHTTP]: HTTP OUT {0} took {1}ms, {2}ms writing", + { + m_log.DebugFormat("[LOGHTTP]: HTTP OUT {0} took {1}ms, {2}ms writing", reqnum, tickdiff, tickdata); + } if (WebUtil.DebugLevel >= 5) - WebUtil.LogResponseDetail(respstring); + WebUtil.LogResponseDetail(reqnum, respstring); return respstring; } @@ -1114,8 +1106,7 @@ namespace OpenSim.Framework int reqnum = WebUtil.RequestNumber++; if (WebUtil.DebugLevel >= 3) - m_log.DebugFormat( - "[LOGHTTP]: HTTP OUT {0} SynchronousRestObject {1} {2}", + m_log.DebugFormat("[LOGHTTP]: HTTP OUT {0} SynchronousRestObject {1} to {2}", reqnum, verb, requestUrl); int tickstart = Util.EnvironmentTickCount(); @@ -1155,7 +1146,7 @@ namespace OpenSim.Framework byte[] data = buffer.ToArray(); if (WebUtil.DebugLevel >= 5) - WebUtil.LogOutgoingDetail(System.Text.Encoding.UTF8.GetString(data)); + WebUtil.LogOutgoingDetail("SEND", reqnum, System.Text.Encoding.UTF8.GetString(data)); try { @@ -1185,7 +1176,8 @@ namespace OpenSim.Framework { using (Stream respStream = resp.GetResponseStream()) { - deserial = XMLResponseHelper.LogAndDeserialize(respStream, resp.ContentLength); + deserial = XMLResponseHelper.LogAndDeserialize( + reqnum, respStream, resp.ContentLength); } } else @@ -1236,18 +1228,13 @@ namespace OpenSim.Framework } m_log.InfoFormat( - "[LOGHTTP]: [SynchronousRestObjectRequester]: Slow request {0} {1} {2} took {3}ms, {4}ms writing, {5}", - reqnum, - verb, - requestUrl, - tickdiff, - tickdata, + "[LOGHTTP]: Slow SynchronousRestObject request {0} {1} to {2} took {3}ms, {4}ms writing, {5}", + reqnum, verb, requestUrl, tickdiff, tickdata, originalRequest); } else if (WebUtil.DebugLevel >= 4) { - m_log.DebugFormat( - "[LOGHTTP]: HTTP OUT {0} took {1}ms, {2}ms writing", + m_log.DebugFormat("[LOGHTTP]: HTTP OUT {0} took {1}ms, {2}ms writing", reqnum, tickdiff, tickdata); } } @@ -1263,7 +1250,7 @@ namespace OpenSim.Framework public static class XMLResponseHelper { - public static TResponse LogAndDeserialize(Stream respStream, long contentLength) + public static TResponse LogAndDeserialize(int reqnum, Stream respStream, long contentLength) { XmlSerializer deserializer = new XmlSerializer(typeof(TResponse)); @@ -1272,7 +1259,7 @@ namespace OpenSim.Framework byte[] data = new byte[contentLength]; Util.ReadStream(respStream, data); - WebUtil.LogResponseDetail(System.Text.Encoding.UTF8.GetString(data)); + WebUtil.LogResponseDetail(reqnum, System.Text.Encoding.UTF8.GetString(data)); using (MemoryStream temp = new MemoryStream(data)) return (TResponse)deserializer.Deserialize(temp); @@ -1284,4 +1271,81 @@ namespace OpenSim.Framework } } } + + + public static class XMLRPCRequester + { + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + public static Hashtable SendRequest(Hashtable ReqParams, string method, string url) + { + int reqnum = WebUtil.RequestNumber++; + + if (WebUtil.DebugLevel >= 3) + m_log.DebugFormat("[LOGHTTP]: HTTP OUT {0} XML-RPC '{1}' to {2}", + reqnum, method, url); + + int tickstart = Util.EnvironmentTickCount(); + string responseStr = null; + + try + { + ArrayList SendParams = new ArrayList(); + SendParams.Add(ReqParams); + + XmlRpcRequest Req = new XmlRpcRequest(method, SendParams); + + if (WebUtil.DebugLevel >= 5) + { + string str = Req.ToString(); + str = XElement.Parse(str).ToString(SaveOptions.DisableFormatting); + WebUtil.LogOutgoingDetail("SEND", reqnum, str); + } + + XmlRpcResponse Resp = Req.Send(url, 30000); + + try + { + responseStr = Resp.ToString(); + responseStr = XElement.Parse(responseStr).ToString(SaveOptions.DisableFormatting); + + if (WebUtil.DebugLevel >= 5) + WebUtil.LogResponseDetail(reqnum, responseStr); + } + catch (Exception e) + { + m_log.Error("Error parsing XML-RPC response", e); + } + + if (Resp.IsFault) + { + m_log.DebugFormat( + "[LOGHTTP]: XML-RPC request {0} '{1}' to {2} FAILED: FaultCode={3}, FaultMessage={4}", + reqnum, method, url, Resp.FaultCode, Resp.FaultString); + return null; + } + + Hashtable RespData = (Hashtable)Resp.Value; + return RespData; + } + finally + { + int tickdiff = Util.EnvironmentTickCountSubtract(tickstart); + if (tickdiff > WebUtil.LongCallTime) + { + m_log.InfoFormat( + "[LOGHTTP]: Slow XML-RPC request {0} '{1}' to {2} took {3}ms, {4}", + reqnum, method, url, tickdiff, + responseStr != null + ? (responseStr.Length > WebUtil.MaxRequestDiagLength ? responseStr.Remove(WebUtil.MaxRequestDiagLength) : responseStr) + : ""); + } + else if (WebUtil.DebugLevel >= 4) + { + m_log.DebugFormat("[LOGHTTP]: HTTP OUT {0} took {1}ms", reqnum, tickdiff); + } + } + } + + } } diff --git a/OpenSim/Services/Interfaces/OpenProfileClient.cs b/OpenSim/Services/Interfaces/OpenProfileClient.cs index 099b0c3..4126c35 100644 --- a/OpenSim/Services/Interfaces/OpenProfileClient.cs +++ b/OpenSim/Services/Interfaces/OpenProfileClient.cs @@ -35,7 +35,6 @@ using System.Reflection; using System.Text; using System.Xml; using log4net; -using Nwc.XmlRpc; using OpenMetaverse; using OpenSim.Framework; @@ -79,7 +78,12 @@ namespace OpenSim.Services.UserProfilesService Hashtable ReqHash = new Hashtable(); ReqHash["avatar_id"] = props.UserId.ToString(); - Hashtable profileData = GenericXMLRPCRequest(ReqHash, "avatar_properties_request", m_serverURI); + Hashtable profileData = XMLRPCRequester.SendRequest(ReqHash, "avatar_properties_request", m_serverURI); + + if (profileData == null) + return false; + if (!profileData.ContainsKey("data")) + return false; ArrayList dataArray = (ArrayList)profileData["data"]; @@ -128,66 +132,5 @@ namespace OpenSim.Services.UserProfilesService return true; } - - private Hashtable GenericXMLRPCRequest(Hashtable ReqParams, string method, string server) - { - ArrayList SendParams = new ArrayList(); - SendParams.Add(ReqParams); - - XmlRpcResponse Resp; - try - { - XmlRpcRequest Req = new XmlRpcRequest(method, SendParams); - Resp = Req.Send(server, 30000); - } - catch (WebException ex) - { - m_log.ErrorFormat("[PROFILE]: Unable to connect to Profile " + - "Server {0}. Exception {1}", server, ex); - - Hashtable ErrorHash = new Hashtable(); - ErrorHash["success"] = false; - ErrorHash["errorMessage"] = "Unable to fetch profile data at this time. "; - ErrorHash["errorURI"] = ""; - - return ErrorHash; - } - catch (SocketException ex) - { - m_log.ErrorFormat( - "[PROFILE]: Unable to connect to Profile Server {0}. Method {1}, params {2}. " + - "Exception {3}", server, method, ReqParams, ex); - - Hashtable ErrorHash = new Hashtable(); - ErrorHash["success"] = false; - ErrorHash["errorMessage"] = "Unable to fetch profile data at this time. "; - ErrorHash["errorURI"] = ""; - - return ErrorHash; - } - catch (XmlException ex) - { - m_log.ErrorFormat( - "[PROFILE]: Unable to connect to Profile Server {0}. Method {1}, params {2}. " + - "Exception {3}", server, method, ReqParams.ToString(), ex); - Hashtable ErrorHash = new Hashtable(); - ErrorHash["success"] = false; - ErrorHash["errorMessage"] = "Unable to fetch profile data at this time. "; - ErrorHash["errorURI"] = ""; - - return ErrorHash; - } - if (Resp.IsFault) - { - Hashtable ErrorHash = new Hashtable(); - ErrorHash["success"] = false; - ErrorHash["errorMessage"] = "Unable to fetch profile data at this time. "; - ErrorHash["errorURI"] = ""; - return ErrorHash; - } - Hashtable RespData = (Hashtable)Resp.Value; - - return RespData; - } } } diff --git a/prebuild.xml b/prebuild.xml index 577251b..9a419eb 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -93,6 +93,7 @@ + @@ -134,7 +135,6 @@ - -- cgit v1.1 From 463d0b2f8f0cd5f02c14391b763680b23c16e438 Mon Sep 17 00:00:00 2001 From: Oren Hurvitz Date: Thu, 24 Apr 2014 18:57:55 +0300 Subject: When linking a Hypergrid region, set the region's flags on the in-memory GridRegion immediately. (When using llTeleportAgent() this *specific* object is used for the teleport, so it should have the correct flags.) --- OpenSim/Services/GridService/HypergridLinker.cs | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/OpenSim/Services/GridService/HypergridLinker.cs b/OpenSim/Services/GridService/HypergridLinker.cs index bf52660..8a60264 100644 --- a/OpenSim/Services/GridService/HypergridLinker.cs +++ b/OpenSim/Services/GridService/HypergridLinker.cs @@ -68,10 +68,6 @@ namespace OpenSim.Services.GridService protected string m_ThisGatekeeper = string.Empty; protected Uri m_ThisGatekeeperURI = null; - // Hyperlink regions are hyperlinks on the map - public readonly Dictionary m_HyperlinkRegions = new Dictionary(); - protected Dictionary m_HyperlinkHandles = new Dictionary(); - protected GridRegion m_DefaultRegion; protected GridRegion DefaultRegion { @@ -409,7 +405,7 @@ namespace OpenSim.Services.GridService // Store the origin's coordinates somewhere regInfo.RegionSecret = handle.ToString(); - AddHyperlinkRegion(regInfo, handle); + AddHyperlinkRegion(ref regInfo, handle); m_log.InfoFormat("[HYPERGRID LINKER]: Successfully linked to region {0} with image {1}", regInfo.RegionName, regInfo.TerrainImage); return true; } @@ -489,11 +485,11 @@ namespace OpenSim.Services.GridService // return true; // } - private void AddHyperlinkRegion(GridRegion regionInfo, ulong regionHandle) + private void AddHyperlinkRegion(ref GridRegion regionInfo, ulong regionHandle) { RegionData rdata = m_GridService.RegionInfo2RegionData(regionInfo); - int flags = (int)OpenSim.Framework.RegionFlags.Hyperlink + (int)OpenSim.Framework.RegionFlags.NoDirectLogin + (int)OpenSim.Framework.RegionFlags.RegionOnline; - rdata.Data["flags"] = flags.ToString(); + regionInfo.Flags = OpenSim.Framework.RegionFlags.Hyperlink | OpenSim.Framework.RegionFlags.NoDirectLogin | OpenSim.Framework.RegionFlags.RegionOnline; + rdata.Data["flags"] = ((int)regionInfo.Flags).ToString(); m_Database.Store(rdata); } -- cgit v1.1 From 0d898d8d8a4dc5920dd17fbfd4f596da474862a6 Mon Sep 17 00:00:00 2001 From: Oren Hurvitz Date: Thu, 24 Apr 2014 19:08:50 +0300 Subject: Revert "When linking a Hypergrid region, set the region's flags on the in-memory GridRegion immediately." This reverts commit 463d0b2f8f0cd5f02c14391b763680b23c16e438. --- OpenSim/Services/GridService/HypergridLinker.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/OpenSim/Services/GridService/HypergridLinker.cs b/OpenSim/Services/GridService/HypergridLinker.cs index 8a60264..c6d2ee3 100644 --- a/OpenSim/Services/GridService/HypergridLinker.cs +++ b/OpenSim/Services/GridService/HypergridLinker.cs @@ -405,7 +405,7 @@ namespace OpenSim.Services.GridService // Store the origin's coordinates somewhere regInfo.RegionSecret = handle.ToString(); - AddHyperlinkRegion(ref regInfo, handle); + AddHyperlinkRegion(regInfo, handle); m_log.InfoFormat("[HYPERGRID LINKER]: Successfully linked to region {0} with image {1}", regInfo.RegionName, regInfo.TerrainImage); return true; } @@ -485,11 +485,11 @@ namespace OpenSim.Services.GridService // return true; // } - private void AddHyperlinkRegion(ref GridRegion regionInfo, ulong regionHandle) + private void AddHyperlinkRegion(GridRegion regionInfo, ulong regionHandle) { RegionData rdata = m_GridService.RegionInfo2RegionData(regionInfo); - regionInfo.Flags = OpenSim.Framework.RegionFlags.Hyperlink | OpenSim.Framework.RegionFlags.NoDirectLogin | OpenSim.Framework.RegionFlags.RegionOnline; - rdata.Data["flags"] = ((int)regionInfo.Flags).ToString(); + int flags = (int)OpenSim.Framework.RegionFlags.Hyperlink + (int)OpenSim.Framework.RegionFlags.NoDirectLogin + (int)OpenSim.Framework.RegionFlags.RegionOnline; + rdata.Data["flags"] = flags.ToString(); m_Database.Store(rdata); } -- cgit v1.1