From a8901a40f4526720f68049706cabd34cf9717172 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Thu, 31 Dec 2009 09:25:16 -0800 Subject: Simulation handlers (agents & objects) completed. --- .../Server/Handlers/Simulation/AgentHandlers.cs | 244 ++++++++++++++++++++- .../Server/Handlers/Simulation/ObjectHandlers.cs | 191 ++++++++++++++++ .../Simulation/SimulationServiceInConnector.cs | 19 +- OpenSim/Server/Handlers/Simulation/Utils.cs | 103 +++++++++ 4 files changed, 544 insertions(+), 13 deletions(-) create mode 100644 OpenSim/Server/Handlers/Simulation/ObjectHandlers.cs create mode 100644 OpenSim/Server/Handlers/Simulation/Utils.cs (limited to 'OpenSim/Server/Handlers') diff --git a/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs b/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs index 3da72c7..4966f66 100644 --- a/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs +++ b/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs @@ -26,6 +26,7 @@ */ using System; +using System.Collections; using System.IO; using System.Reflection; using System.Net; @@ -45,6 +46,247 @@ using log4net; namespace OpenSim.Server.Handlers.Simulation { + public class AgentHandler + { + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private ISimulationService m_SimulationService; + + public AgentHandler(ISimulationService sim) + { + m_SimulationService = sim; + } + + public Hashtable Handler(Hashtable request) + { + //m_log.Debug("[CONNECTION DEBUGGING]: AgentHandler Called"); + + m_log.Debug("---------------------------"); + m_log.Debug(" >> uri=" + request["uri"]); + m_log.Debug(" >> content-type=" + request["content-type"]); + m_log.Debug(" >> http-method=" + request["http-method"]); + m_log.Debug("---------------------------\n"); + + Hashtable responsedata = new Hashtable(); + responsedata["content_type"] = "text/html"; + responsedata["keepalive"] = false; + + + UUID agentID; + string action; + ulong regionHandle; + if (!Utils.GetParams((string)request["uri"], out agentID, out regionHandle, out action)) + { + m_log.InfoFormat("[AGENT HANDLER]: Invalid parameters for agent message {0}", request["uri"]); + responsedata["int_response_code"] = 404; + responsedata["str_response_string"] = "false"; + + return responsedata; + } + + // Next, let's parse the verb + string method = (string)request["http-method"]; + if (method.Equals("PUT")) + { + DoAgentPut(request, responsedata); + return responsedata; + } + else if (method.Equals("POST")) + { + DoAgentPost(request, responsedata, agentID); + return responsedata; + } + else if (method.Equals("GET")) + { + DoAgentGet(request, responsedata, agentID, regionHandle); + return responsedata; + } + else if (method.Equals("DELETE")) + { + DoAgentDelete(request, responsedata, agentID, action, regionHandle); + return responsedata; + } + else + { + m_log.InfoFormat("[AGENT HANDLER]: method {0} not supported in agent message", method); + responsedata["int_response_code"] = HttpStatusCode.MethodNotAllowed; + responsedata["str_response_string"] = "Method not allowed"; + + return responsedata; + } + + } + + protected virtual void DoAgentPost(Hashtable request, Hashtable responsedata, UUID id) + { + OSDMap args = Utils.GetOSDMap((string)request["body"]); + if (args == null) + { + responsedata["int_response_code"] = HttpStatusCode.BadRequest; + responsedata["str_response_string"] = "Bad request"; + return; + } + + // retrieve the regionhandle + ulong regionhandle = 0; + if (args["destination_handle"] != null) + UInt64.TryParse(args["destination_handle"].AsString(), out regionhandle); + + AgentCircuitData aCircuit = new AgentCircuitData(); + try + { + aCircuit.UnpackAgentCircuitData(args); + } + catch (Exception ex) + { + m_log.InfoFormat("[AGENT HANDLER]: exception on unpacking ChildCreate message {0}", ex.Message); + responsedata["int_response_code"] = HttpStatusCode.BadRequest; + responsedata["str_response_string"] = "Bad request"; + return; + } + + OSDMap resp = new OSDMap(2); + string reason = String.Empty; + uint teleportFlags = 0; + if (args.ContainsKey("teleport_flags")) + { + teleportFlags = args["teleport_flags"].AsUInteger(); + } + + // This is the meaning of POST agent + //m_regionClient.AdjustUserInformation(aCircuit); + bool result = m_SimulationService.CreateAgent(regionhandle, aCircuit, teleportFlags, out reason); + + resp["reason"] = OSD.FromString(reason); + resp["success"] = OSD.FromBoolean(result); + + // TODO: add reason if not String.Empty? + responsedata["int_response_code"] = HttpStatusCode.OK; + responsedata["str_response_string"] = OSDParser.SerializeJsonString(resp); + } + + protected virtual void DoAgentPut(Hashtable request, Hashtable responsedata) + { + OSDMap args = Utils.GetOSDMap((string)request["body"]); + if (args == null) + { + responsedata["int_response_code"] = HttpStatusCode.BadRequest; + responsedata["str_response_string"] = "Bad request"; + return; + } + + // retrieve the regionhandle + ulong regionhandle = 0; + if (args["destination_handle"] != null) + UInt64.TryParse(args["destination_handle"].AsString(), out regionhandle); + + string messageType; + if (args["message_type"] != null) + messageType = args["message_type"].AsString(); + else + { + m_log.Warn("[AGENT HANDLER]: Agent Put Message Type not found. "); + messageType = "AgentData"; + } + + bool result = true; + if ("AgentData".Equals(messageType)) + { + AgentData agent = new AgentData(); + try + { + agent.Unpack(args); + } + catch (Exception ex) + { + m_log.InfoFormat("[AGENT HANDLER]: exception on unpacking ChildAgentUpdate message {0}", ex.Message); + responsedata["int_response_code"] = HttpStatusCode.BadRequest; + responsedata["str_response_string"] = "Bad request"; + return; + } + + //agent.Dump(); + // This is one of the meanings of PUT agent + result = m_SimulationService.UpdateAgent(regionhandle, agent); + + } + else if ("AgentPosition".Equals(messageType)) + { + AgentPosition agent = new AgentPosition(); + try + { + agent.Unpack(args); + } + catch (Exception ex) + { + m_log.InfoFormat("[AGENT HANDLER]: exception on unpacking ChildAgentUpdate message {0}", ex.Message); + return; + } + //agent.Dump(); + // This is one of the meanings of PUT agent + result = m_SimulationService.UpdateAgent(regionhandle, agent); + + } + + responsedata["int_response_code"] = HttpStatusCode.OK; + responsedata["str_response_string"] = result.ToString(); + //responsedata["str_response_string"] = OSDParser.SerializeJsonString(resp); ??? instead + } + + protected virtual void DoAgentGet(Hashtable request, Hashtable responsedata, UUID id, ulong regionHandle) + { + IAgentData agent = null; + bool result = m_SimulationService.RetrieveAgent(regionHandle, id, out agent); + OSDMap map = null; + if (result) + { + if (agent != null) // just to make sure + { + map = agent.Pack(); + string strBuffer = ""; + try + { + strBuffer = OSDParser.SerializeJsonString(map); + } + catch (Exception e) + { + m_log.WarnFormat("[AGENT HANDLER]: Exception thrown on serialization of DoAgentGet: {0}", e.Message); + responsedata["int_response_code"] = HttpStatusCode.InternalServerError; + // ignore. buffer will be empty, caller should check. + } + + responsedata["content_type"] = "application/json"; + responsedata["int_response_code"] = HttpStatusCode.OK; + responsedata["str_response_string"] = strBuffer; + } + else + { + responsedata["int_response_code"] = HttpStatusCode.InternalServerError; + responsedata["str_response_string"] = "Internal error"; + } + } + else + { + responsedata["int_response_code"] = HttpStatusCode.NotFound; + responsedata["str_response_string"] = "Not Found"; + } + } + + protected virtual void DoAgentDelete(Hashtable request, Hashtable responsedata, UUID id, string action, ulong regionHandle) + { + //m_log.Debug(" >>> DoDelete action:" + action + "; regionHandle:" + regionHandle); + + if (action.Equals("release")) + m_SimulationService.ReleaseAgent(regionHandle, id, ""); + else + m_SimulationService.CloseAgent(regionHandle, id); + + responsedata["int_response_code"] = HttpStatusCode.OK; + responsedata["str_response_string"] = "OpenSim agent " + id.ToString(); + + m_log.Debug("[AGENT HANDLER]: Agent Deleted."); + } + } + public class AgentGetHandler : BaseStreamHandler { // TODO: unused: private ISimulationService m_SimulationService; @@ -153,7 +395,7 @@ namespace OpenSim.Server.Handlers.Simulation // m_regionClient.AdjustUserInformation(aCircuit); // Finally! - bool success = m_SimulationService.CreateAgent(regionhandle, aCircuit, out reason); + bool success = m_SimulationService.CreateAgent(regionhandle, aCircuit, /*!!!*/0, out reason); OSDMap resp = new OSDMap(1); diff --git a/OpenSim/Server/Handlers/Simulation/ObjectHandlers.cs b/OpenSim/Server/Handlers/Simulation/ObjectHandlers.cs new file mode 100644 index 0000000..8c3af72 --- /dev/null +++ b/OpenSim/Server/Handlers/Simulation/ObjectHandlers.cs @@ -0,0 +1,191 @@ +/* + * 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.IO; +using System.Reflection; +using System.Net; +using System.Text; + +using OpenSim.Server.Base; +using OpenSim.Server.Handlers.Base; +using OpenSim.Services.Interfaces; +using OpenSim.Framework; +using OpenSim.Framework.Servers.HttpServer; + +using OpenMetaverse; +using OpenMetaverse.StructuredData; +using Nini.Config; +using log4net; + + +namespace OpenSim.Server.Handlers.Simulation +{ + public class ObjectHandler + { + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private ISimulationService m_SimulationService; + + public ObjectHandler(ISimulationService sim) + { + m_SimulationService = sim; + } + + public Hashtable Handler(Hashtable request) + { + m_log.Debug("[CONNECTION DEBUGGING]: ObjectHandler Called"); + + m_log.Debug("---------------------------"); + m_log.Debug(" >> uri=" + request["uri"]); + m_log.Debug(" >> content-type=" + request["content-type"]); + m_log.Debug(" >> http-method=" + request["http-method"]); + m_log.Debug("---------------------------\n"); + + Hashtable responsedata = new Hashtable(); + responsedata["content_type"] = "text/html"; + + UUID objectID; + string action; + ulong regionHandle; + if (!Utils.GetParams((string)request["uri"], out objectID, out regionHandle, out action)) + { + m_log.InfoFormat("[REST COMMS]: Invalid parameters for object message {0}", request["uri"]); + responsedata["int_response_code"] = 404; + responsedata["str_response_string"] = "false"; + + return responsedata; + } + + // Next, let's parse the verb + string method = (string)request["http-method"]; + if (method.Equals("POST")) + { + DoObjectPost(request, responsedata, regionHandle); + return responsedata; + } + else if (method.Equals("PUT")) + { + DoObjectPut(request, responsedata, regionHandle); + return responsedata; + } + //else if (method.Equals("DELETE")) + //{ + // DoObjectDelete(request, responsedata, agentID, action, regionHandle); + // return responsedata; + //} + else + { + m_log.InfoFormat("[REST COMMS]: method {0} not supported in object message", method); + responsedata["int_response_code"] = HttpStatusCode.MethodNotAllowed; + responsedata["str_response_string"] = "Mthod not allowed"; + + return responsedata; + } + + } + + protected virtual void DoObjectPost(Hashtable request, Hashtable responsedata, ulong regionhandle) + { + OSDMap args = Utils.GetOSDMap((string)request["body"]); + if (args == null) + { + responsedata["int_response_code"] = 400; + responsedata["str_response_string"] = "false"; + return; + } + + string sogXmlStr = "", extraStr = "", stateXmlStr = ""; + if (args["sog"] != null) + sogXmlStr = args["sog"].AsString(); + if (args["extra"] != null) + extraStr = args["extra"].AsString(); + + IScene s = m_SimulationService.GetScene(regionhandle); + ISceneObject sog = null; + try + { + //sog = SceneObjectSerializer.FromXml2Format(sogXmlStr); + sog = s.DeserializeObject(sogXmlStr); + sog.ExtraFromXmlString(extraStr); + } + catch (Exception ex) + { + m_log.InfoFormat("[REST COMMS]: exception on deserializing scene object {0}", ex.Message); + responsedata["int_response_code"] = HttpStatusCode.BadRequest; + responsedata["str_response_string"] = "Bad request"; + return; + } + + if ((args["state"] != null) && s.AllowScriptCrossings) + { + stateXmlStr = args["state"].AsString(); + if (stateXmlStr != "") + { + try + { + sog.SetState(stateXmlStr, s); + } + catch (Exception ex) + { + m_log.InfoFormat("[REST COMMS]: exception on setting state for scene object {0}", ex.Message); + // ignore and continue + } + } + } + // This is the meaning of POST object + bool result = m_SimulationService.CreateObject(regionhandle, sog, false); + + responsedata["int_response_code"] = HttpStatusCode.OK; + responsedata["str_response_string"] = result.ToString(); + } + + protected virtual void DoObjectPut(Hashtable request, Hashtable responsedata, ulong regionhandle) + { + OSDMap args = Utils.GetOSDMap((string)request["body"]); + if (args == null) + { + responsedata["int_response_code"] = 400; + responsedata["str_response_string"] = "false"; + return; + } + + UUID userID = UUID.Zero, itemID = UUID.Zero; + if (args["userid"] != null) + userID = args["userid"].AsUUID(); + if (args["itemid"] != null) + itemID = args["itemid"].AsUUID(); + + // This is the meaning of PUT object + bool result = m_SimulationService.CreateObject(regionhandle, userID, itemID); + + responsedata["int_response_code"] = 200; + responsedata["str_response_string"] = result.ToString(); + } + + } +} \ No newline at end of file diff --git a/OpenSim/Server/Handlers/Simulation/SimulationServiceInConnector.cs b/OpenSim/Server/Handlers/Simulation/SimulationServiceInConnector.cs index fe93fa5..b2aa52f 100644 --- a/OpenSim/Server/Handlers/Simulation/SimulationServiceInConnector.cs +++ b/OpenSim/Server/Handlers/Simulation/SimulationServiceInConnector.cs @@ -47,13 +47,6 @@ namespace OpenSim.Server.Handlers.Simulation if (serverConfig == null) throw new Exception("No section 'SimulationService' in config file"); - bool authentication = serverConfig.GetBoolean("RequireAuthentication", false); - - if (authentication) - m_AuthenticationService = scene.RequestModuleInterface(); - - bool foreignGuests = serverConfig.GetBoolean("AllowForeignGuests", false); - //string simService = serverConfig.GetString("LocalServiceModule", // String.Empty); @@ -69,12 +62,14 @@ namespace OpenSim.Server.Handlers.Simulation //System.Console.WriteLine("XXXXXXXXXXXXXXXXXXX m_AssetSetvice == null? " + ((m_AssetService == null) ? "yes" : "no")); - server.AddStreamHandler(new AgentGetHandler(m_SimulationService, m_AuthenticationService)); - server.AddStreamHandler(new AgentPostHandler(m_SimulationService, m_AuthenticationService, foreignGuests)); - server.AddStreamHandler(new AgentPutHandler(m_SimulationService, m_AuthenticationService)); - server.AddStreamHandler(new AgentDeleteHandler(m_SimulationService, m_AuthenticationService)); + //server.AddStreamHandler(new AgentGetHandler(m_SimulationService, m_AuthenticationService)); + //server.AddStreamHandler(new AgentPostHandler(m_SimulationService, m_AuthenticationService)); + //server.AddStreamHandler(new AgentPutHandler(m_SimulationService, m_AuthenticationService)); + //server.AddStreamHandler(new AgentDeleteHandler(m_SimulationService, m_AuthenticationService)); + server.AddHTTPHandler("/agent/", new AgentHandler(m_SimulationService).Handler); + server.AddHTTPHandler("/object/", new ObjectHandler(m_SimulationService).Handler); + //server.AddStreamHandler(new ObjectPostHandler(m_SimulationService, authentication)); - //server.AddStreamHandler(new NeighborPostHandler(m_SimulationService, authentication)); } } } diff --git a/OpenSim/Server/Handlers/Simulation/Utils.cs b/OpenSim/Server/Handlers/Simulation/Utils.cs new file mode 100644 index 0000000..1f2f851 --- /dev/null +++ b/OpenSim/Server/Handlers/Simulation/Utils.cs @@ -0,0 +1,103 @@ +/* + * 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.Generic; +using System.Reflection; + +using OpenMetaverse; +using OpenMetaverse.StructuredData; + +using log4net; + +namespace OpenSim.Server.Handlers.Simulation +{ + public class Utils + { + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + /// + /// Extract the param from an uri. + /// + /// Something like this: /agent/uuid/ or /agent/uuid/handle/release + /// uuid on uuid field + /// optional action + public static bool GetParams(string uri, out UUID uuid, out ulong regionHandle, out string action) + { + uuid = UUID.Zero; + action = ""; + regionHandle = 0; + + uri = uri.Trim(new char[] { '/' }); + string[] parts = uri.Split('/'); + if (parts.Length <= 1) + { + return false; + } + else + { + if (!UUID.TryParse(parts[1], out uuid)) + return false; + + if (parts.Length >= 3) + UInt64.TryParse(parts[2], out regionHandle); + if (parts.Length >= 4) + action = parts[3]; + + return true; + } + } + + public static OSDMap GetOSDMap(string data) + { + OSDMap args = null; + try + { + OSD buffer; + // We should pay attention to the content-type, but let's assume we know it's Json + buffer = OSDParser.DeserializeJson(data); + if (buffer.Type == OSDType.Map) + { + args = (OSDMap)buffer; + return args; + } + else + { + // uh? + m_log.Debug(("[REST COMMS]: Got OSD of unexpected type " + buffer.Type.ToString())); + return null; + } + } + catch (Exception ex) + { + m_log.Debug("[REST COMMS]: exception on parse of REST message " + ex.Message); + return null; + } + } + + } +} -- cgit v1.1