diff --git a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs index 4b953c553e..67fc3456b0 100644 --- a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs +++ b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs @@ -107,6 +107,7 @@ namespace OpenSim.Framework.Servers.HttpServer protected ConcurrentDictionary m_simpleStreamHandlers = new ConcurrentDictionary(); protected ConcurrentDictionary m_simpleStreamVarPath = new ConcurrentDictionary(); protected ConcurrentDictionary m_indexPHPmethods = new ConcurrentDictionary(); + protected ConcurrentDictionary m_globalMethods = new ConcurrentDictionary(); protected IRequestHandler m_RootDefaultGET = null; // default method for root path. does override rpc xml and json, and old llsd login @@ -389,6 +390,11 @@ namespace OpenSim.Framework.Servers.HttpServer return new List(m_indexPHPmethods.Keys); } + public List GetGLobalMethodsKeys() + { + return new List(m_globalMethods.Keys); + } + private static string GetHandlerKey(string httpMethod, string path) { return httpMethod + ":" + path; @@ -547,11 +553,31 @@ namespace OpenSim.Framework.Servers.HttpServer public SimpleStreamMethod TryGetIndexPHPMethodHandler(string key) { - if(m_indexPHPmethods.TryGetValue(key, out SimpleStreamMethod sh)) + if (!string.IsNullOrWhiteSpace(key) && m_indexPHPmethods.TryGetValue(key, out SimpleStreamMethod sh)) return sh; return null; } + public void AddGloblaMethodHandler(string key, SimpleStreamMethod sh) + { + m_globalMethods.TryAdd(key, sh); + } + + public void RemoveGlobalPMethodHandler(string key) + { + m_globalMethods.TryRemove(key, out SimpleStreamMethod sh); + } + + public bool TryGetGlobalMethodHandler(string key, out SimpleStreamMethod sh) + { + if(string.IsNullOrWhiteSpace(key)) + { + sh = null; + return false; + } + return m_globalMethods.TryGetValue(key, out sh); + } + public void OnRequest(object source, RequestEventArgs args) { RequestNumber++; @@ -665,6 +691,16 @@ namespace OpenSim.Framework.Servers.HttpServer } default: // not sure about xmlrpc content type coerence at this point { + // let legacy datasnapshot work + if(request.QueryString.Count > 0 && request.QueryAsDictionary.TryGetValue("method", out string method)) + { + if(TryGetGlobalMethodHandler(method, out SimpleStreamMethod sm)) + { + sm?.Invoke(request, response); + break; + } + } + if (DebugLevel >= 3) LogIncomingToXmlRpcHandler(request); diff --git a/OpenSim/Region/OptionalModules/DataSnapshot/DataRequestHandler.cs b/OpenSim/Region/OptionalModules/DataSnapshot/DataRequestHandler.cs index 817170f352..981850f0c8 100644 --- a/OpenSim/Region/OptionalModules/DataSnapshot/DataRequestHandler.cs +++ b/OpenSim/Region/OptionalModules/DataSnapshot/DataRequestHandler.cs @@ -27,16 +27,15 @@ */ using System.Collections; +using System.Net; using System.Reflection; using System.Xml; using log4net; using OpenMetaverse; using OpenSim.Framework; -using OpenSim.Framework.Capabilities; using OpenSim.Framework.Servers; using OpenSim.Framework.Servers.HttpServer; using OpenSim.Region.Framework.Scenes; -using Caps = OpenSim.Framework.Capabilities.Caps; namespace OpenSim.Region.DataSnapshot { @@ -53,68 +52,31 @@ namespace OpenSim.Region.DataSnapshot m_externalData = externalData; //Register HTTP handler - if (MainServer.UnSecureInstance.AddHTTPHandler("collector", OnGetSnapshot)) - { - m_log.Info("[DATASNAPSHOT]: Set up snapshot service"); - } + MainServer.UnSecureInstance.AddGloblaMethodHandler("collector", OnGetSnapshot); // Register validation callback handler - MainServer.UnSecureInstance.AddHTTPHandler("validate", OnValidate); + MainServer.UnSecureInstance.AddGloblaMethodHandler("validate", OnValidate); + m_log.Info("[DATASNAPSHOT]: Set up snapshot service"); } - private string GetClientString(Hashtable request) - { - string clientstring = ""; - if (!request.ContainsKey("headers")) - return clientstring; - - Hashtable requestinfo = (Hashtable)request["headers"]; - if (requestinfo.ContainsKey("x-forwarded-for")) - { - object str = requestinfo["x-forwarded-for"]; - if (str != null) - { - if (!string.IsNullOrEmpty(str.ToString())) - { - return str.ToString(); - } - } - } - if (!requestinfo.ContainsKey("remote_addr")) - return clientstring; - - object remote_addrobj = requestinfo["remote_addr"]; - if (remote_addrobj != null) - { - if (!string.IsNullOrEmpty(remote_addrobj.ToString())) - { - clientstring = remote_addrobj.ToString(); - } - } - - return clientstring; - } - - public Hashtable OnGetSnapshot(Hashtable keysvals) + public void OnGetSnapshot(IOSHttpRequest req, IOSHttpResponse resp) { Hashtable reply = new Hashtable(); string reqtag; - string snapObj = (string)keysvals["region"]; - if(string.IsNullOrWhiteSpace(snapObj)) - reqtag = GetClientString(keysvals); + if(req.QueryAsDictionary.TryGetValue("region", out string snapObj) && !string.IsNullOrWhiteSpace(snapObj)) + reqtag = snapObj + req.RemoteIPEndPoint.Address.ToString(); else - reqtag = snapObj + GetClientString(keysvals); + reqtag = req.RemoteIPEndPoint.Address.ToString(); - - if(!string.IsNullOrWhiteSpace(reqtag)) + if (!string.IsNullOrWhiteSpace(reqtag)) { if(throotleGen.Contains(reqtag)) { - reply["str_response_string"] = "Please try your request again later"; - reply["int_response_code"] = 503; - reply["content_type"] = "text/plain"; + resp.StatusCode = (int)HttpStatusCode.ServiceUnavailable; + resp.StatusDescription = "Please try again later"; + resp.ContentType = "text/plain"; m_log.Debug("[DATASNAPSHOT] Collection request spam. reply try later"); - return reply; + return; } throotleGen.AddOrUpdate(reqtag, 0, 60); @@ -128,35 +90,28 @@ namespace OpenSim.Region.DataSnapshot XmlDocument response = m_externalData.GetSnapshot(snapObj); if(response == null) { - reply["str_response_string"] = "Please try your request again later"; - reply["int_response_code"] = 503; - reply["content_type"] = "text/plain"; + resp.StatusCode = (int)HttpStatusCode.ServiceUnavailable; + resp.ContentType = "text/plain"; m_log.Debug("[DATASNAPSHOT] Collection request spam. reply try later"); - return reply; + return; } - reply["str_response_string"] = response.OuterXml; - reply["int_response_code"] = 200; - reply["content_type"] = "text/xml"; - return reply; + resp.RawBuffer = Util.UTF8NBGetbytes(response.OuterXml); + resp.ContentType = "text/xml"; + resp.StatusCode = (int)HttpStatusCode.OK; } - public Hashtable OnValidate(Hashtable keysvals) + public void OnValidate(IOSHttpRequest req, IOSHttpResponse resp) { m_log.Debug("[DATASNAPSHOT] Received validation request"); - Hashtable reply = new Hashtable(); - int statuscode = 200; + resp.ContentType = "text/xml"; + resp.StatusCode = (int)HttpStatusCode.Forbidden; - string secret = (string)keysvals["secret"]; - if (secret == m_externalData.Secret.ToString()) - statuscode = 403; - - reply["str_response_string"] = string.Empty; - reply["int_response_code"] = statuscode; - reply["content_type"] = "text/plain"; - - return reply; + if(req.QueryAsDictionary.TryGetValue("secret", out string secret)) + { + if (secret == m_externalData.Secret.ToString()) + resp.StatusCode = (int)HttpStatusCode.OK; + } } - } }