From d15a3b10a3031b9552d67d2e2d435a689b448e2f Mon Sep 17 00:00:00 2001 From: Oren Hurvitz Date: Thu, 24 Apr 2014 14:19:03 +0300 Subject: [PATCH 1/6] 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 - .../HttpServer/JsonRpcRequestManager.cs | 171 ++++++++---------- OpenSim/Framework/WebUtil.cs | 24 +-- .../Simulation/SimulationServiceConnector.cs | 10 +- 5 files changed, 92 insertions(+), 124 deletions(-) diff --git a/OpenSim/Data/MySQL/MySQLUserProfilesData.cs b/OpenSim/Data/MySQL/MySQLUserProfilesData.cs index cc4c5b0576..e301bbe130 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 0f5b4c83ea..549409105e 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 a44f471e17..ed6a14cd81 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(); + throw new ArgumentNullException("parameters"); - using (Stream dataStream = webRequest.GetRequestStream()) - dataStream.Write(content, 0, content.Length); - - WebResponse webResponse = null; + 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 (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 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; } + response = (OSDMap)response["_Result"]; + + OSD data; + + if (response.ContainsKey("error")) + { + data = response["error"]; + m_log.DebugFormat("JsonRpc request '{0}' returned an error: {1}", + method, OSDParser.SerializeJsonString(data)); + return false; + } + + if (!response.ContainsKey("result")) + { + 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); + if (string.IsNullOrEmpty(jsonId)) + jsonId = UUID.Random().ToString(); - WebResponse webResponse = null; + 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 768ff16485..8f5bc0cdb3 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 a5520c4170..d9fe5a014d 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; From d62f0bc35d966ca4099e43026b90ab24cd768e4b Mon Sep 17 00:00:00 2001 From: Oren Hurvitz Date: Sun, 2 Mar 2014 14:43:43 +0200 Subject: [PATCH 2/6] Refactored: moved OpenProfileClient to a location where it can be used by both the Simulators and Robust --- .../Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs | 1 + .../UserProfiles => Services/Interfaces}/OpenProfileClient.cs | 2 +- prebuild.xml | 2 ++ 3 files changed, 4 insertions(+), 1 deletion(-) rename OpenSim/{Region/CoreModules/Avatar/UserProfiles => Services/Interfaces}/OpenProfileClient.cs (99%) diff --git a/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs b/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs index d05b1f6db4..3d45f1d57d 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/Region/CoreModules/Avatar/UserProfiles/OpenProfileClient.cs b/OpenSim/Services/Interfaces/OpenProfileClient.cs similarity index 99% rename from OpenSim/Region/CoreModules/Avatar/UserProfiles/OpenProfileClient.cs rename to OpenSim/Services/Interfaces/OpenProfileClient.cs index 23de3f599d..099b0c3138 100644 --- a/OpenSim/Region/CoreModules/Avatar/UserProfiles/OpenProfileClient.cs +++ b/OpenSim/Services/Interfaces/OpenProfileClient.cs @@ -39,7 +39,7 @@ using Nwc.XmlRpc; using OpenMetaverse; using OpenSim.Framework; -namespace OpenSim.Region.CoreModules.Avatar.UserProfiles +namespace OpenSim.Services.UserProfilesService { /// /// A client for accessing a profile server using the OpenProfile protocol. diff --git a/prebuild.xml b/prebuild.xml index 09c429aa7e..577251b60e 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -133,6 +133,8 @@ + + From e8a2eff2e83cba74e84970136dd486beededc1de Mon Sep 17 00:00:00 2001 From: Oren Hurvitz Date: Thu, 24 Apr 2014 14:20:48 +0300 Subject: [PATCH 3/6] 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 3d45f1d57d..1ee2a7bb84 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 + if (!GetProfileData(ref props, foreign, out result)) { - GetProfileData(ref props, out result); - } - catch (Exception e) - { - 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"; From bc06db3df45d8dd61338c5b1426fd0161731f7cd Mon Sep 17 00:00:00 2001 From: Oren Hurvitz Date: Thu, 24 Apr 2014 14:21:05 +0300 Subject: [PATCH 4/6] - 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 --- .../Servers/HttpServer/BaseHttpServer.cs | 2 +- OpenSim/Framework/WebUtil.cs | 212 ++++++++++++------ .../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 4f71db9346..e8aa278175 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 8f5bc0cdb3..d7f6bc8ffe 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 099b0c3138..4126c3592f 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 577251b60e..9a419eb3c2 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -93,6 +93,7 @@ + @@ -134,7 +135,6 @@ - From 463d0b2f8f0cd5f02c14391b763680b23c16e438 Mon Sep 17 00:00:00 2001 From: Oren Hurvitz Date: Thu, 24 Apr 2014 18:57:55 +0300 Subject: [PATCH 5/6] 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 bf52660a0d..8a60264e80 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); } From 0d898d8d8a4dc5920dd17fbfd4f596da474862a6 Mon Sep 17 00:00:00 2001 From: Oren Hurvitz Date: Thu, 24 Apr 2014 19:08:50 +0300 Subject: [PATCH 6/6] 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 8a60264e80..c6d2ee32ca 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); }