From e0418da6e116fc80a2730f966b0c79e72fc6b781 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sun, 26 Apr 2020 16:54:58 +0100 Subject: [PATCH] change region avatarhandlers --- .../Servers/HttpServer/BaseHttpServer.cs | 174 ++-- .../HttpServer/Interfaces/IHttpServer.cs | 2 +- .../Servers/HttpServer/OSHttpRequest.cs | 4 +- OpenSim/Region/Application/OpenSimBase.cs | 49 -- .../Handlers/Simulation/AgentHandlers.cs | 748 +++++++++--------- .../SimulationServiceInConnector.cs | 4 +- OpenSim/Server/ServerMain.cs | 7 +- 7 files changed, 519 insertions(+), 469 deletions(-) diff --git a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs index 12afb76e6d..86cab0026e 100644 --- a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs +++ b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs @@ -98,16 +98,15 @@ namespace OpenSim.Framework.Servers.HttpServer protected Dictionary m_rpcHandlersKeepAlive = new Dictionary(); protected DefaultLLSDMethod m_defaultLlsdHandler = null; // <-- Moving away from the monolithic.. and going to /registered/ protected Dictionary m_llsdHandlers = new Dictionary(); - protected ConcurrentDictionary m_streamHandlers = new ConcurrentDictionary(); - protected ConcurrentDictionary m_simpleStreamHandlers = new ConcurrentDictionary(); protected Dictionary m_HTTPHandlers = new Dictionary(); // protected Dictionary m_agentHandlers = new Dictionary(); - protected ConcurrentDictionary m_pollHandlers = - new ConcurrentDictionary(); + protected ConcurrentDictionary m_pollHandlers = new ConcurrentDictionary(); + protected Dictionary m_WebSocketHandlers = new Dictionary(); + protected ConcurrentDictionary m_streamHandlers = new ConcurrentDictionary(); + protected ConcurrentDictionary m_simpleStreamHandlers = new ConcurrentDictionary(); + protected ConcurrentDictionary m_simpleStreamVarPath = new ConcurrentDictionary(); protected ConcurrentDictionary m_indexPHPmethods = new ConcurrentDictionary(); - protected Dictionary m_WebSocketHandlers = - new Dictionary(); protected uint m_port; protected bool m_ssl; @@ -344,10 +343,13 @@ namespace OpenSim.Framework.Servers.HttpServer m_streamHandlers.TryAdd(handler.Path, handler); } - public void AddSimpleStreamHandler(ISimpleStreamHandler handler) + public void AddSimpleStreamHandler(ISimpleStreamHandler handler, bool varPath = false) { // m_log.DebugFormat("[BASE HTTP SERVER]: Adding handler key {0}", handlerKey); - m_simpleStreamHandlers.TryAdd(handler.Path, handler); + if(varPath) + m_simpleStreamVarPath.TryAdd(handler.Path, handler); + else + m_simpleStreamHandlers.TryAdd(handler.Path, handler); } public void AddWebSocketHandler(string servicepath, WebSocketRequestDelegate handler) @@ -487,30 +489,6 @@ namespace OpenSim.Framework.Servers.HttpServer return new List(m_pollHandlers.Keys); } -// // Note that the agent string is provided simply to differentiate -// // the handlers - it is NOT required to be an actual agent header -// // value. -// public bool AddAgentHandler(string agent, IHttpAgentHandler handler) -// { -// lock (m_agentHandlers) -// { -// if (!m_agentHandlers.ContainsKey(agent)) -// { -// m_agentHandlers.Add(agent, handler); -// return true; -// } -// } -// -// //must already have a handler for that path so return false -// return false; -// } -// -// public List GetAgentHandlerKeys() -// { -// lock (m_agentHandlers) -// return new List(m_agentHandlers.Keys); -// } - public bool AddLLSDHandler(string path, LLSDMethod handler) { lock (m_llsdHandlers) @@ -565,12 +543,12 @@ namespace OpenSim.Framework.Servers.HttpServer { psEvArgs.RequestsReceived++; PollServiceHttpRequest psreq = new PollServiceHttpRequest(psEvArgs, context, request); - psEvArgs.Request?.Invoke(psreq.RequestID, new OSHttpRequest(context, request)); + psEvArgs.Request?.Invoke(psreq.RequestID, new OSHttpRequest(request)); m_pollServiceManager.Enqueue(psreq); } else { - OnHandleRequestIOThread(context, request); + OnHandleRequestIOThread(request); } } catch (Exception e) @@ -579,9 +557,9 @@ namespace OpenSim.Framework.Servers.HttpServer } } - private void OnHandleRequestIOThread(IHttpClientContext context, IHttpRequest request) + private void OnHandleRequestIOThread(IHttpRequest request) { - OSHttpRequest req = new OSHttpRequest(context, request); + OSHttpRequest req = new OSHttpRequest(request); WebSocketRequestDelegate dWebSocketRequestDelegate = null; lock (m_WebSocketHandlers) { @@ -590,12 +568,11 @@ namespace OpenSim.Framework.Servers.HttpServer } if (dWebSocketRequestDelegate != null) { - dWebSocketRequestDelegate(req.Url.AbsolutePath, new WebSocketHttpServerHandler(req, context, 8192)); + dWebSocketRequestDelegate(req.Url.AbsolutePath, new WebSocketHttpServerHandler(req, request.Context, 8192)); return; } - OSHttpResponse resp = new OSHttpResponse(new HttpResponse(context, request)); - HandleRequest(req, resp); + HandleRequest(req, new OSHttpResponse(req)); } /// @@ -641,7 +618,7 @@ namespace OpenSim.Framework.Servers.HttpServer // } // } string path = request.UriPath; - if (path!="/" && TryGetSimpleStreamHandler(path, out ISimpleStreamHandler hdr)) + if (path != "/" && (TryGetSimpleStreamHandler(path, out ISimpleStreamHandler hdr) || TryGetSimpleStreamVarPath(path, out hdr))) { hdr.Handle(request, response); if (request.InputStream != null && request.InputStream.CanRead) @@ -652,7 +629,6 @@ namespace OpenSim.Framework.Servers.HttpServer return; } - path = request.RawUrl; string handlerKey = GetHandlerKey(request.HttpMethod, path); byte[] buffer = null; @@ -1083,24 +1059,37 @@ namespace OpenSim.Framework.Servers.HttpServer { return m_simpleStreamHandlers.TryGetValue(uripath, out handler); } -// private bool TryGetAgentHandler(OSHttpRequest request, OSHttpResponse response, out IHttpAgentHandler agentHandler) -// { -// agentHandler = null; -// -// lock (m_agentHandlers) -// { -// foreach (IHttpAgentHandler handler in m_agentHandlers.Values) -// { -// if (handler.Match(request, response)) -// { -// agentHandler = handler; -// return true; -// } -// } -// } -// -// return false; -// } + + private bool TryGetSimpleStreamVarPath(string uripath, out ISimpleStreamHandler handler) + { + handler = null; + if(uripath.Length < 3) + return false; + int indx = uripath.IndexOf('/', 2); + if(indx < 0 || indx == uripath.Length - 1) + return false; + + return m_simpleStreamVarPath.TryGetValue(uripath.Substring(0,indx), out handler); + } + + // private bool TryGetAgentHandler(OSHttpRequest request, OSHttpResponse response, out IHttpAgentHandler agentHandler) + // { + // agentHandler = null; + // + // lock (m_agentHandlers) + // { + // foreach (IHttpAgentHandler handler in m_agentHandlers.Values) + // { + // if (handler.Match(request, response)) + // { + // agentHandler = handler; + // return true; + // } + // } + // } + // + // return false; + // } /// /// Try all the registered xmlrpc handlers when an xmlrpc request is received. @@ -2127,7 +2116,9 @@ namespace OpenSim.Framework.Servers.HttpServer public void RemoveSimpleStreamHandler(string path) { - m_simpleStreamHandlers.TryRemove(path, out ISimpleStreamHandler dummy); + if(m_simpleStreamHandlers.TryRemove(path, out ISimpleStreamHandler dummy)) + return; + m_simpleStreamVarPath.TryRemove(path, out ISimpleStreamHandler dummy2); } public void RemoveHTTPHandler(string httpMethod, string path) @@ -2282,4 +2273,67 @@ namespace OpenSim.Framework.Servers.HttpServer return; } } + + public class IndexPHPHandler : SimpleStreamHandler + { + BaseHttpServer m_server; + + public IndexPHPHandler(BaseHttpServer server) + : base("/index.php") + { + m_server = server; + } + + protected override void ProcessRequest(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) + { + httpResponse.KeepAlive = false; + if (m_server == null || !m_server.HTTPDRunning) + { + httpResponse.StatusCode = (int)HttpStatusCode.NotFound; + return; + } + + if (httpRequest.QueryString.Count == 0) + { + httpResponse.StatusCode = (int)HttpStatusCode.Redirect; + httpResponse.AddHeader("Location", "http://opensimulator.org"); + return; + } + if (httpRequest.QueryFlags.Contains("about")) + { + + httpResponse.StatusCode = (int)HttpStatusCode.Redirect; + httpResponse.AddHeader("Location", "http://opensimulator.org/wiki/0.9.2.0_Release"); + return; + } + if (!httpRequest.QueryAsDictionary.TryGetValue("method", out string methods) || string.IsNullOrWhiteSpace(methods)) + { + httpResponse.StatusCode = (int)HttpStatusCode.NotFound; ; + return; + } + + string[] splited = methods.Split(new char[] { ',' }); + string method = splited[0]; + if (string.IsNullOrWhiteSpace(method)) + { + httpResponse.StatusCode = (int)HttpStatusCode.NotFound; + return; + } + + SimpleStreamMethod sh = m_server.TryGetIndexPHPMethodHandler(method); + if (sh == null) + { + httpResponse.StatusCode = (int)HttpStatusCode.NotFound; + return; + } + try + { + sh?.Invoke(httpRequest, httpResponse); + } + catch + { + httpResponse.StatusCode = (int)HttpStatusCode.InternalServerError; + } + } + } } diff --git a/OpenSim/Framework/Servers/HttpServer/Interfaces/IHttpServer.cs b/OpenSim/Framework/Servers/HttpServer/Interfaces/IHttpServer.cs index 6c89b40150..bce4531b4a 100644 --- a/OpenSim/Framework/Servers/HttpServer/Interfaces/IHttpServer.cs +++ b/OpenSim/Framework/Servers/HttpServer/Interfaces/IHttpServer.cs @@ -97,7 +97,7 @@ namespace OpenSim.Framework.Servers.HttpServer /// /// void AddStreamHandler(IRequestHandler handler); - void AddSimpleStreamHandler(ISimpleStreamHandler handler); + void AddSimpleStreamHandler(ISimpleStreamHandler handler, bool varPath = false); bool AddXmlRPCHandler(string method, XmlRpcMethod handler); bool AddXmlRPCHandler(string method, XmlRpcMethod handler, bool keepAlive); diff --git a/OpenSim/Framework/Servers/HttpServer/OSHttpRequest.cs b/OpenSim/Framework/Servers/HttpServer/OSHttpRequest.cs index ffb54689be..8022ed4a71 100644 --- a/OpenSim/Framework/Servers/HttpServer/OSHttpRequest.cs +++ b/OpenSim/Framework/Servers/HttpServer/OSHttpRequest.cs @@ -214,10 +214,10 @@ namespace OpenSim.Framework.Servers.HttpServer public OSHttpRequest() {} - public OSHttpRequest(IHttpClientContext context, IHttpRequest req) + public OSHttpRequest(IHttpRequest req) { m_request = req; - m_context = context; + m_context = req.Context; if (null != req.Headers["content-encoding"]) { diff --git a/OpenSim/Region/Application/OpenSimBase.cs b/OpenSim/Region/Application/OpenSimBase.cs index a41045bb0b..7a367c1ea5 100755 --- a/OpenSim/Region/Application/OpenSimBase.cs +++ b/OpenSim/Region/Application/OpenSimBase.cs @@ -870,55 +870,6 @@ namespace OpenSim } } - public class IndexPHPHandler : SimpleStreamHandler - { - BaseHttpServer m_server; - - public IndexPHPHandler(BaseHttpServer server) - : base("/index.php") - { - m_server = server; - } - - protected override void ProcessRequest(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) - { - httpResponse.KeepAlive = false; - if(m_server == null || !m_server.HTTPDRunning) - { - httpResponse.StatusCode = (int)HttpStatusCode.NotFound; - return; - } - - if (!httpRequest.QueryAsDictionary.TryGetValue("method", out string methods) || string.IsNullOrWhiteSpace(methods)) - { - httpResponse.StatusCode = (int)HttpStatusCode.NotFound; - return; - } - - string[] splited = methods.Split(new char[]{','}); - string method = splited[0]; - if (string.IsNullOrWhiteSpace(method)) - { - httpResponse.StatusCode = (int)HttpStatusCode.NotFound; - return; - } - - SimpleStreamMethod sh = m_server.TryGetIndexPHPMethodHandler(method); - if (sh == null) - { - httpResponse.StatusCode = (int)HttpStatusCode.NotFound; - return; - } - try - { - sh?.Invoke(httpRequest, httpResponse); - } - catch - { - httpResponse.StatusCode = (int)HttpStatusCode.InternalServerError; - } - } - } /// /// Handler to supply the current extended status of this sim to a user configured URI diff --git a/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs b/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs index 73bab6166b..02694eef66 100644 --- a/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs +++ b/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs @@ -51,265 +51,6 @@ 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() { } - - 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; - UUID regionID; - string action; - if (!Utils.GetParams((string)request["uri"], out agentID, out regionID, 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("DELETE")) - { - string auth_token = string.Empty; - if (request.ContainsKey("auth")) - auth_token = request["auth"].ToString(); - - DoAgentDelete(request, responsedata, agentID, action, regionID, auth_token); - return responsedata; - } - else if (method.Equals("QUERYACCESS")) - { - DoQueryAccess(request, responsedata, agentID, regionID); - return responsedata; - } - else - { - m_log.ErrorFormat("[AGENT HANDLER]: method {0} not supported in agent message {1} (caller is {2})", method, (string)request["uri"], Util.GetCallerIP(request)); - responsedata["int_response_code"] = HttpStatusCode.MethodNotAllowed; - responsedata["str_response_string"] = "Method not allowed"; - - return responsedata; - } - } - - protected virtual void DoQueryAccess(Hashtable request, Hashtable responsedata, UUID agentID, UUID regionID) - { - if (m_SimulationService == null) - { - m_log.Debug("[AGENT HANDLER]: Agent QUERY called. Harmless but useless."); - responsedata["content_type"] = "application/json"; - responsedata["int_response_code"] = HttpStatusCode.NotImplemented; - responsedata["str_response_string"] = string.Empty; - - return; - } - - Culture.SetCurrentCulture(); - - // m_log.DebugFormat("[AGENT HANDLER]: Received QUERYACCESS with {0}", (string)request["body"]); - OSDMap args = Utils.GetOSDMap((string)request["body"]); - - bool viaTeleport = true; - OSD tmpOSD; - if (args.TryGetValue("viaTeleport",out tmpOSD)) - viaTeleport = tmpOSD.AsBoolean(); - - Vector3 position = Vector3.Zero; - if (args.TryGetValue("position", out tmpOSD)) - position = Vector3.Parse(tmpOSD.AsString()); - - string agentHomeURI = null; - if (args.TryGetValue("agent_home_uri", out tmpOSD)) - agentHomeURI = tmpOSD.AsString(); - - // Decode the legacy (string) version and extract the number - float theirVersion = 0f; - if (args.TryGetValue("my_version", out tmpOSD)) - { - string theirVersionStr = tmpOSD.AsString(); - string[] parts = theirVersionStr.Split(new char[] {'/'}); - if (parts.Length > 1) - theirVersion = float.Parse(parts[1], Culture.FormatProvider); - } - - EntityTransferContext ctx = new EntityTransferContext(); - if (args.TryGetValue("context", out tmpOSD) && tmpOSD is OSDMap) - ctx.Unpack((OSDMap)tmpOSD); - - // Decode the new versioning data - float minVersionRequired = 0f; - float maxVersionRequired = 0f; - float minVersionProvided = 0f; - float maxVersionProvided = 0f; - - if (args.TryGetValue("simulation_service_supported_min", out tmpOSD)) - minVersionProvided = (float)tmpOSD.AsReal(); - if (args.TryGetValue("simulation_service_supported_max", out tmpOSD)) - maxVersionProvided = (float)tmpOSD.AsReal(); - - if (args.TryGetValue("simulation_service_accepted_min", out tmpOSD)) - minVersionRequired = (float)tmpOSD.AsReal(); - if (args.TryGetValue("simulation_service_accepted_max", out tmpOSD)) - maxVersionRequired = (float)tmpOSD.AsReal(); - - responsedata["int_response_code"] = HttpStatusCode.OK; - OSDMap resp = new OSDMap(3); - - float version = 0f; - - float outboundVersion = 0f; - float inboundVersion = 0f; - - if (minVersionProvided == 0f) // string version or older - { - // If there is no version in the packet at all we're looking at 0.6 or - // even more ancient. Refuse it. - if(theirVersion == 0f) - { - resp["success"] = OSD.FromBoolean(false); - resp["reason"] = OSD.FromString("Your region is running a old version of opensim no longer supported. Consider updating it"); - responsedata["str_response_string"] = OSDParser.SerializeJsonString(resp, true); - return; - } - - version = theirVersion; - - if (version < VersionInfo.SimulationServiceVersionAcceptedMin || - version > VersionInfo.SimulationServiceVersionAcceptedMax ) - { - resp["success"] = OSD.FromBoolean(false); - resp["reason"] = OSD.FromString(String.Format("Your region protocol version is {0} and we accept only {1} - {2}. No version overlap.", theirVersion, VersionInfo.SimulationServiceVersionAcceptedMin, VersionInfo.SimulationServiceVersionAcceptedMax)); - responsedata["str_response_string"] = OSDParser.SerializeJsonString(resp, true); - return; - } - } - else - { - // Test for no overlap - if (minVersionProvided > VersionInfo.SimulationServiceVersionAcceptedMax || - maxVersionProvided < VersionInfo.SimulationServiceVersionAcceptedMin) - { - resp["success"] = OSD.FromBoolean(false); - resp["reason"] = OSD.FromString(String.Format("Your region provide protocol versions {0} - {1} and we accept only {2} - {3}. No version overlap.", minVersionProvided, maxVersionProvided, VersionInfo.SimulationServiceVersionAcceptedMin, VersionInfo.SimulationServiceVersionAcceptedMax)); - responsedata["str_response_string"] = OSDParser.SerializeJsonString(resp, true); - return; - } - if (minVersionRequired > VersionInfo.SimulationServiceVersionSupportedMax || - maxVersionRequired < VersionInfo.SimulationServiceVersionSupportedMin) - { - resp["success"] = OSD.FromBoolean(false); - resp["reason"] = OSD.FromString(String.Format("You require region protocol versions {0} - {1} and we provide only {2} - {3}. No version overlap.", minVersionRequired, maxVersionRequired, VersionInfo.SimulationServiceVersionSupportedMin, VersionInfo.SimulationServiceVersionSupportedMax)); - responsedata["str_response_string"] = OSDParser.SerializeJsonString(resp, true); - return; - } - - // Determine versions to use - // This is intentionally inverted. Inbound and Outbound refer to the direction of the transfer. - // Therefore outbound means from the sender to the receier and inbound means from the receiver to the sender. - // So outbound is what we will accept and inbound is what we will send. Confused yet? - outboundVersion = Math.Min(maxVersionProvided, VersionInfo.SimulationServiceVersionAcceptedMax); - inboundVersion = Math.Min(maxVersionRequired, VersionInfo.SimulationServiceVersionSupportedMax); - } - - List features = new List(); - - if (args.TryGetValue("features", out tmpOSD) && tmpOSD is OSDArray) - { - OSDArray array = (OSDArray)tmpOSD; - - foreach (OSD o in array) - features.Add(new UUID(o.AsString())); - } - - GridRegion destination = new GridRegion(); - destination.RegionID = regionID; - - string reason; - // We're sending the version numbers down to the local connector to do the varregion check. - ctx.InboundVersion = inboundVersion; - ctx.OutboundVersion = outboundVersion; - if (minVersionProvided == 0f) - { - ctx.InboundVersion = version; - ctx.OutboundVersion = version; - } - - bool result = m_SimulationService.QueryAccess(destination, agentID, agentHomeURI, viaTeleport, position, features, ctx, out reason); - m_log.DebugFormat("[AGENT HANDLER]: QueryAccess returned {0} ({1}). Version={2}, {3}/{4}", - result, reason, version, inboundVersion, outboundVersion); - - resp["success"] = OSD.FromBoolean(result); - resp["reason"] = OSD.FromString(reason); - string legacyVersion = String.Format(Culture.FormatProvider,"SIMULATION/{0}", version); - resp["version"] = OSD.FromString(legacyVersion); - resp["negotiated_inbound_version"] = OSD.FromReal(inboundVersion); - resp["negotiated_outbound_version"] = OSD.FromReal(outboundVersion); - - OSDArray featuresWanted = new OSDArray(); - foreach (UUID feature in features) - featuresWanted.Add(OSD.FromString(feature.ToString())); - - resp["features"] = featuresWanted; - - // We must preserve defaults here, otherwise a false "success" will not be put into the JSON map! - responsedata["str_response_string"] = OSDParser.SerializeJsonString(resp, true); - -// Console.WriteLine("str_response_string [{0}]", responsedata["str_response_string"]); - } - - protected void DoAgentDelete(Hashtable request, Hashtable responsedata, UUID id, string action, UUID regionID, string auth_token) - { - if (string.IsNullOrEmpty(action)) - m_log.DebugFormat("[AGENT HANDLER]: >>> DELETE <<< RegionID: {0}; from: {1}; auth_code: {2}", regionID, Util.GetCallerIP(request), auth_token); - else - m_log.DebugFormat("[AGENT HANDLER]: Release {0} to RegionID: {1}", id, regionID); - - GridRegion destination = new GridRegion(); - destination.RegionID = regionID; - - if (action.Equals("release")) - ReleaseAgent(regionID, id); - else - Util.FireAndForget( - o => m_SimulationService.CloseAgent(destination, id, auth_token), null, "AgentHandler.DoAgentDelete"); - - responsedata["int_response_code"] = HttpStatusCode.OK; - responsedata["str_response_string"] = "OpenSim agent " + id.ToString(); - - //m_log.DebugFormat("[AGENT HANDLER]: Agent {0} Released/Deleted from region {1}", id, regionID); - } - - protected virtual void ReleaseAgent(UUID regionID, UUID id) - { - m_SimulationService.ReleaseAgent(regionID, id, ""); - } - } - public class AgentPostHandler : BaseStreamHandler { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -405,19 +146,17 @@ namespace OpenSim.Server.Handlers.Simulation return encoding.GetBytes("false"); } - DoAgentPost(keysvals, responsedata, agentID); + DoAgentPost(keysvals, httpResponse, agentID); - httpResponse.StatusCode = (int)responsedata["int_response_code"]; - return encoding.GetBytes((string)responsedata["str_response_string"]); + return httpResponse.RawBuffer; } - protected void DoAgentPost(Hashtable request, Hashtable responsedata, UUID id) + protected void DoAgentPost(Hashtable request, IOSHttpResponse response, UUID id) { OSDMap args = Utils.GetOSDMap((string)request["body"]); if (args == null) { - responsedata["int_response_code"] = HttpStatusCode.BadRequest; - responsedata["str_response_string"] = "Bad request"; + response.StatusCode = (int)HttpStatusCode.BadRequest; return; } @@ -445,8 +184,7 @@ namespace OpenSim.Server.Handlers.Simulation 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"; + response.StatusCode = (int)HttpStatusCode.BadRequest; return; } @@ -469,10 +207,6 @@ namespace OpenSim.Server.Handlers.Simulation OSDMap resp = new OSDMap(2); string reason = String.Empty; - // This is the meaning of POST agent - //m_regionClient.AdjustUserInformation(aCircuit); - //bool result = m_SimulationService.CreateAgent(destination, aCircuit, teleportFlags, out reason); - bool result = CreateAgent(source, gatekeeper, destination, aCircuit, data.flags, data.fromLogin, ctx, out reason); resp["reason"] = OSD.FromString(reason); @@ -480,9 +214,10 @@ namespace OpenSim.Server.Handlers.Simulation // Let's also send out the IP address of the caller back to the caller (HG 1.5) resp["your_ip"] = OSD.FromString(GetCallerIP(request)); - // TODO: add reason if not String.Empty? - responsedata["int_response_code"] = HttpStatusCode.OK; - responsedata["str_response_string"] = OSDParser.SerializeJsonString(resp); + response.StatusCode = (int)HttpStatusCode.OK; + byte[] respData = Encoding.UTF8.GetBytes(OSDParser.SerializeJsonString(resp)); + response.RawBuffer = respData; + response.RawBufferLen = respData.Length; } protected virtual AgentDestinationData CreateAgentDestinationData() @@ -580,53 +315,114 @@ namespace OpenSim.Server.Handlers.Simulation } } - public class AgentPutHandler : BaseStreamHandler + public class AgentSimpleHandler : SimpleStreamHandler { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private ISimulationService m_SimulationService; protected bool m_Proxy = false; - public AgentPutHandler(ISimulationService service) : - base("PUT", "/agent") + public AgentSimpleHandler(ISimulationService service) : base("/agent") { m_SimulationService = service; } - public AgentPutHandler(string path) : - base("PUT", path) + protected override void ProcessRequest(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) { - m_SimulationService = null; + httpResponse.KeepAlive = false; + httpResponse.ContentType = "application/json"; + if (m_SimulationService == null) + { + httpResponse.StatusCode = (int)HttpStatusCode.InternalServerError; + httpResponse.RawBuffer = Util.UTF8.GetBytes("false"); + return; + } + + if (!Utils.GetParams(httpRequest.UriPath, out UUID agentID, out UUID regionID, out string action)) + { + m_log.InfoFormat("[AGENT HANDLER]: Invalid parameters for agent message {0}", httpRequest.UriPath); + + httpResponse.StatusCode = (int)HttpStatusCode.NotFound; + httpResponse.RawBuffer = Util.UTF8.GetBytes("false"); + return; + } + + switch(httpRequest.HttpMethod) + { + case "QUERYACCESS": + { + if (agentID == UUID.Zero || regionID == UUID.Zero) + { + httpResponse.StatusCode = (int)HttpStatusCode.BadRequest; + httpResponse.RawBuffer = Util.UTF8.GetBytes("false"); + return; + } + OSDMap args = Deserialize(httpRequest); + if (args == null) + { + httpResponse.StatusCode = (int)HttpStatusCode.BadRequest; + httpResponse.RawBuffer = Util.UTF8.GetBytes("false"); + return; + } + DoQueryAccess(args, httpResponse, agentID, regionID); + break; + } + case "PUT": + { + OSDMap args = Deserialize(httpRequest); + if (args == null) + { + httpResponse.StatusCode = (int)HttpStatusCode.BadRequest; + httpResponse.RawBuffer = Util.UTF8.GetBytes("false"); + return; + } + + DoAgentPut(args, httpResponse); + break; + } + case "POST": + { + if (agentID == UUID.Zero) + { + httpResponse.StatusCode = (int)HttpStatusCode.BadRequest; + httpResponse.RawBuffer = Util.UTF8.GetBytes("false"); + return; + } + OSDMap args = Deserialize(httpRequest); + if (args == null) + { + httpResponse.StatusCode = (int)HttpStatusCode.BadRequest; + httpResponse.RawBuffer = Util.UTF8.GetBytes("false"); + return; + } + DoAgentPost(args, httpRequest, httpResponse, agentID); + break; + } + case "DELETE": + { + if (agentID == UUID.Zero || regionID == UUID.Zero) + { + httpResponse.StatusCode = (int)HttpStatusCode.BadRequest; + httpResponse.RawBuffer = Util.UTF8.GetBytes("false"); + return; + } + httpRequest.QueryAsDictionary.TryGetValue("auth", out string auth_token); + + DoAgentDelete(httpRequest, httpResponse, agentID, action, regionID, auth_token); + break; + } + default: + { + httpResponse.StatusCode = (int)HttpStatusCode.MethodNotAllowed; + httpResponse.RawBuffer = Util.UTF8.GetBytes("false"); + return; + } + } } - protected override byte[] ProcessRequest(string path, Stream request, - IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) + private OSDMap Deserialize(IOSHttpRequest httpRequest) { -// m_log.DebugFormat("[SIMULATION]: Stream handler called"); - - Hashtable keysvals = new Hashtable(); - Hashtable headervals = new Hashtable(); - - string[] querystringkeys = httpRequest.QueryString.AllKeys; - string[] rHeaders = httpRequest.Headers.AllKeys; - - keysvals.Add("uri", httpRequest.RawUrl); - keysvals.Add("content-type", httpRequest.ContentType); - keysvals.Add("http-method", httpRequest.HttpMethod); - - foreach (string queryname in querystringkeys) - keysvals.Add(queryname, httpRequest.QueryString[queryname]); - - foreach (string headername in rHeaders) - headervals[headername] = httpRequest.Headers[headername]; - - keysvals.Add("headers", headervals); - keysvals.Add("querystringkeys", querystringkeys); - - String requestBody; - Encoding encoding = Encoding.UTF8; - - Stream inputStream = request; + Stream inputStream = httpRequest.InputStream; Stream innerStream = null; try { @@ -635,58 +431,306 @@ namespace OpenSim.Server.Handlers.Simulation innerStream = inputStream; inputStream = new GZipStream(innerStream, CompressionMode.Decompress); } - - using (StreamReader reader = new StreamReader(inputStream, encoding)) - { - requestBody = reader.ReadToEnd(); - } + return (OSDMap)OSDParser.DeserializeJson(inputStream); + } + catch + { + return null; } finally { if (innerStream != null) innerStream.Dispose(); - inputStream.Dispose(); } - - keysvals.Add("body", requestBody); - - httpResponse.StatusCode = 200; - httpResponse.ContentType = "text/html"; - httpResponse.KeepAlive = false; - - Hashtable responsedata = new Hashtable(); - - UUID agentID; - UUID regionID; - string action; - - if (!Utils.GetParams((string)keysvals["uri"], out agentID, out regionID, out action)) - { - m_log.InfoFormat("[AGENT HANDLER]: Invalid parameters for agent message {0}", keysvals["uri"]); - - httpResponse.StatusCode = 404; - - return encoding.GetBytes("false"); - } - - DoAgentPut(keysvals, responsedata); - - httpResponse.StatusCode = (int)responsedata["int_response_code"]; - return encoding.GetBytes((string)responsedata["str_response_string"]); } - protected void DoAgentPut(Hashtable request, Hashtable responsedata) + protected virtual void DoQueryAccess(OSDMap args, IOSHttpResponse httpResponse, UUID agentID, UUID regionID) { - // TODO: Encode the ENtityTransferContext + bool viaTeleport = true; + OSD tmpOSD; + if (args.TryGetValue("viaTeleport", out tmpOSD)) + viaTeleport = tmpOSD.AsBoolean(); - OSDMap args = Utils.GetOSDMap((string)request["body"]); - if (args == null) + Vector3 position = Vector3.Zero; + if (args.TryGetValue("position", out tmpOSD)) + position = Vector3.Parse(tmpOSD.AsString()); + + string agentHomeURI = null; + if (args.TryGetValue("agent_home_uri", out tmpOSD)) + agentHomeURI = tmpOSD.AsString(); + + // Decode the legacy (string) version and extract the number + float theirVersion = 0f; + if (args.TryGetValue("my_version", out tmpOSD)) { - responsedata["int_response_code"] = HttpStatusCode.BadRequest; - responsedata["str_response_string"] = "Bad request"; + string theirVersionStr = tmpOSD.AsString(); + string[] parts = theirVersionStr.Split(new char[] { '/' }); + if (parts.Length > 1) + theirVersion = float.Parse(parts[1], Culture.FormatProvider); + } + + EntityTransferContext ctx = new EntityTransferContext(); + if (args.TryGetValue("context", out tmpOSD) && tmpOSD is OSDMap) + ctx.Unpack((OSDMap)tmpOSD); + + // Decode the new versioning data + float minVersionRequired = 0f; + float maxVersionRequired = 0f; + float minVersionProvided = 0f; + float maxVersionProvided = 0f; + + if (args.TryGetValue("simulation_service_supported_min", out tmpOSD)) + minVersionProvided = (float)tmpOSD.AsReal(); + if (args.TryGetValue("simulation_service_supported_max", out tmpOSD)) + maxVersionProvided = (float)tmpOSD.AsReal(); + + if (args.TryGetValue("simulation_service_accepted_min", out tmpOSD)) + minVersionRequired = (float)tmpOSD.AsReal(); + if (args.TryGetValue("simulation_service_accepted_max", out tmpOSD)) + maxVersionRequired = (float)tmpOSD.AsReal(); + + OSDMap resp = new OSDMap(3); + + float version = 0f; + + httpResponse.StatusCode = (int)HttpStatusCode.OK; + + + float outboundVersion = 0f; + float inboundVersion = 0f; + + if (minVersionProvided == 0f) // string version or older + { + // If there is no version in the packet at all we're looking at 0.6 or + // even more ancient. Refuse it. + if (theirVersion == 0f) + { + resp["success"] = OSD.FromBoolean(false); + resp["reason"] = OSD.FromString("Your region is running a old version of opensim no longer supported. Consider updating it"); + httpResponse.RawBuffer = Util.UTF8.GetBytes(OSDParser.SerializeJsonString(resp, true)); + return; + } + + version = theirVersion; + + if (version < VersionInfo.SimulationServiceVersionAcceptedMin || + version > VersionInfo.SimulationServiceVersionAcceptedMax) + { + resp["success"] = OSD.FromBoolean(false); + resp["reason"] = OSD.FromString(String.Format("Your region protocol version is {0} and we accept only {1} - {2}. No version overlap.", theirVersion, VersionInfo.SimulationServiceVersionAcceptedMin, VersionInfo.SimulationServiceVersionAcceptedMax)); + httpResponse.RawBuffer = Util.UTF8.GetBytes(OSDParser.SerializeJsonString(resp, true)); + return; + } + } + else + { + // Test for no overlap + if (minVersionProvided > VersionInfo.SimulationServiceVersionAcceptedMax || + maxVersionProvided < VersionInfo.SimulationServiceVersionAcceptedMin) + { + resp["success"] = OSD.FromBoolean(false); + resp["reason"] = OSD.FromString(String.Format("Your region provide protocol versions {0} - {1} and we accept only {2} - {3}. No version overlap.", minVersionProvided, maxVersionProvided, VersionInfo.SimulationServiceVersionAcceptedMin, VersionInfo.SimulationServiceVersionAcceptedMax)); + httpResponse.RawBuffer = Util.UTF8.GetBytes(OSDParser.SerializeJsonString(resp, true)); + return; + } + if (minVersionRequired > VersionInfo.SimulationServiceVersionSupportedMax || + maxVersionRequired < VersionInfo.SimulationServiceVersionSupportedMin) + { + resp["success"] = OSD.FromBoolean(false); + resp["reason"] = OSD.FromString(String.Format("You require region protocol versions {0} - {1} and we provide only {2} - {3}. No version overlap.", minVersionRequired, maxVersionRequired, VersionInfo.SimulationServiceVersionSupportedMin, VersionInfo.SimulationServiceVersionSupportedMax)); + httpResponse.RawBuffer = Util.UTF8.GetBytes(OSDParser.SerializeJsonString(resp, true)); + return; + } + + // Determine versions to use + // This is intentionally inverted. Inbound and Outbound refer to the direction of the transfer. + // Therefore outbound means from the sender to the receier and inbound means from the receiver to the sender. + // So outbound is what we will accept and inbound is what we will send. Confused yet? + outboundVersion = Math.Min(maxVersionProvided, VersionInfo.SimulationServiceVersionAcceptedMax); + inboundVersion = Math.Min(maxVersionRequired, VersionInfo.SimulationServiceVersionSupportedMax); + } + + List features = new List(); + + if (args.TryGetValue("features", out tmpOSD) && tmpOSD is OSDArray) + { + OSDArray array = (OSDArray)tmpOSD; + + foreach (OSD o in array) + features.Add(new UUID(o.AsString())); + } + + GridRegion destination = new GridRegion(); + destination.RegionID = regionID; + + string reason; + // We're sending the version numbers down to the local connector to do the varregion check. + ctx.InboundVersion = inboundVersion; + ctx.OutboundVersion = outboundVersion; + if (minVersionProvided == 0f) + { + ctx.InboundVersion = version; + ctx.OutboundVersion = version; + } + + bool result = m_SimulationService.QueryAccess(destination, agentID, agentHomeURI, viaTeleport, position, features, ctx, out reason); + m_log.DebugFormat("[AGENT HANDLER]: QueryAccess returned {0} ({1}). Version={2}, {3}/{4}", + result, reason, version, inboundVersion, outboundVersion); + + resp["success"] = OSD.FromBoolean(result); + resp["reason"] = OSD.FromString(reason); + string legacyVersion = String.Format(Culture.FormatProvider, "SIMULATION/{0}", version); + resp["version"] = OSD.FromString(legacyVersion); + resp["negotiated_inbound_version"] = OSD.FromReal(inboundVersion); + resp["negotiated_outbound_version"] = OSD.FromReal(outboundVersion); + + OSDArray featuresWanted = new OSDArray(); + foreach (UUID feature in features) + featuresWanted.Add(OSD.FromString(feature.ToString())); + + resp["features"] = featuresWanted; + + if(result) + httpResponse.KeepAlive = true; + + // We must preserve defaults here, otherwise a false "success" will not be put into the JSON map! + httpResponse.RawBuffer = Util.UTF8.GetBytes(OSDParser.SerializeJsonString(resp, true)); + + // console.WriteLine("str_response_string [{0}]", responsedata["str_response_string"]); + } + + protected void DoAgentDelete(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse, UUID agentID, string action, UUID regionID, string auth_token) + { + if (string.IsNullOrEmpty(action)) + m_log.DebugFormat("[AGENT HANDLER]: >>> DELETE <<< RegionID: {0}; from: {1}; auth_code: {2}", + regionID, httpRequest.RemoteIPEndPoint.Address.ToString(), auth_token); + else + m_log.DebugFormat("[AGENT HANDLER]: Release {0} to RegionID: {1}", agentID, regionID); + + + if (action.Equals("release")) + m_SimulationService.ReleaseAgent(regionID, agentID, ""); + else + { + GridRegion destination = new GridRegion(); + destination.RegionID = regionID; + Util.FireAndForget( + o => m_SimulationService.CloseAgent(destination, agentID, auth_token), null, "AgentHandler.DoAgentDelete"); + } + + httpResponse.StatusCode = (int)HttpStatusCode.OK; + httpResponse.RawBuffer = Util.UTF8.GetBytes("OpenSim agent " + agentID.ToString()); + + //m_log.DebugFormat("[AGENT HANDLER]: Agent {0} Released/Deleted from region {1}", id, regionID); + } + + protected void DoAgentPost(OSDMap args, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse, UUID agentID) + { + OSD tmpOSD; + EntityTransferContext ctx = new EntityTransferContext(); + if (args.TryGetValue("context", out tmpOSD) && tmpOSD is OSDMap) + ctx.Unpack((OSDMap)tmpOSD); + + AgentDestinationData data = CreateAgentDestinationData(); + UnpackData(args, data); + + GridRegion destination = new GridRegion(); + destination.RegionID = data.uuid; + destination.RegionLocX = data.x; + destination.RegionLocY = data.y; + destination.RegionName = data.name; + + GridRegion gatekeeper = ExtractGatekeeper(data); + + AgentCircuitData aCircuit = new AgentCircuitData(); + try + { + aCircuit.UnpackAgentCircuitData(args); + } + catch (Exception ex) + { + m_log.InfoFormat("[AGENT HANDLER]: exception on unpacking ChildCreate message {0}", ex.Message); + httpResponse.StatusCode = (int)HttpStatusCode.BadRequest; + httpResponse.RawBuffer = Util.UTF8.GetBytes("false"); return; } + GridRegion source = null; + + if (args.TryGetValue("source_uuid", out tmpOSD)) + { + source = new GridRegion(); + source.RegionID = UUID.Parse(tmpOSD.AsString()); + source.RegionLocX = Int32.Parse(args["source_x"].AsString()); + source.RegionLocY = Int32.Parse(args["source_y"].AsString()); + source.RegionName = args["source_name"].AsString(); + + if (args.TryGetValue("source_server_uri", out tmpOSD)) + source.RawServerURI = tmpOSD.AsString(); + else + source.RawServerURI = null; + } + + OSDMap resp = new OSDMap(2); + string reason = String.Empty; + + bool result = CreateAgent(source, gatekeeper, destination, aCircuit, data.flags, data.fromLogin, ctx, out reason); + + resp["reason"] = OSD.FromString(reason); + resp["success"] = OSD.FromBoolean(result); + // Let's also send out the IP address of the caller back to the caller (HG 1.5) + resp["your_ip"] = OSD.FromString(httpRequest.RemoteIPEndPoint.Address.ToString()); + + httpResponse.StatusCode = (int)HttpStatusCode.OK; + httpResponse.RawBuffer = Util.UTF8.GetBytes(OSDParser.SerializeJsonString(resp)); + } + + protected virtual AgentDestinationData CreateAgentDestinationData() + { + return new AgentDestinationData(); + } + + protected virtual void UnpackData(OSDMap args, AgentDestinationData data) + { + OSD tmpOSD; + // retrieve the input arguments + if (args.TryGetValue("destination_x", out tmpOSD) && tmpOSD != null) + Int32.TryParse(tmpOSD.AsString(), out data.x); + else + m_log.WarnFormat(" -- request didn't have destination_x"); + + if (args.TryGetValue("destination_y", out tmpOSD) && tmpOSD != null) + Int32.TryParse(tmpOSD.AsString(), out data.y); + else + m_log.WarnFormat(" -- request didn't have destination_y"); + + if (args.TryGetValue("destination_uuid", out tmpOSD) && tmpOSD != null) + UUID.TryParse(tmpOSD.AsString(), out data.uuid); + + if (args.TryGetValue("destination_name", out tmpOSD) && tmpOSD != null) + data.name = tmpOSD.ToString(); + + if (args.TryGetValue("teleport_flags", out tmpOSD) && tmpOSD != null) + data.flags = tmpOSD.AsUInteger(); + } + + protected virtual GridRegion ExtractGatekeeper(AgentDestinationData data) + { + return null; + } + + // subclasses can override this + protected virtual bool CreateAgent(GridRegion source, GridRegion gatekeeper, GridRegion destination, + AgentCircuitData aCircuit, uint teleportFlags, bool fromLogin, EntityTransferContext ctx, out string reason) + { + reason = String.Empty; + bool ret = m_SimulationService.CreateAgent(source, destination, aCircuit, teleportFlags, ctx, out reason); + // m_log.DebugFormat("[AGENT HANDLER]: SYNC CreateAgent {0} {1}", ret.ToString(), reason); + return ret; + } + + protected void DoAgentPut(OSDMap args, IOSHttpResponse httpResponse) + { // retrieve the input arguments OSD tmpOSD; EntityTransferContext ctx = new EntityTransferContext(); @@ -730,8 +774,8 @@ namespace OpenSim.Server.Handlers.Simulation 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"; + httpResponse.StatusCode = (int)HttpStatusCode.BadRequest; + httpResponse.RawBuffer = Util.UTF8.GetBytes("false"); return; } @@ -749,16 +793,17 @@ namespace OpenSim.Server.Handlers.Simulation catch (Exception ex) { m_log.InfoFormat("[AGENT HANDLER]: exception on unpacking ChildAgentUpdate message {0}", ex.Message); + httpResponse.StatusCode = (int)HttpStatusCode.BadRequest; + httpResponse.RawBuffer = Util.UTF8.GetBytes("false"); return; } //agent.Dump(); // This is one of the meanings of PUT agent result = m_SimulationService.UpdateAgent(destination, agent); - } - responsedata["int_response_code"] = HttpStatusCode.OK; - responsedata["str_response_string"] = result.ToString(); + httpResponse.StatusCode = (int)HttpStatusCode.OK; + httpResponse.RawBuffer = Util.UTF8.GetBytes(result.ToString()); //responsedata["str_response_string"] = OSDParser.SerializeJsonString(resp); ??? instead } @@ -767,8 +812,7 @@ namespace OpenSim.Server.Handlers.Simulation { // The data and protocols are already defined so this is just a dummy to satisfy the interface // TODO: make this end-to-end - EntityTransferContext ctx = new EntityTransferContext(); - return m_SimulationService.UpdateAgent(destination, agent, ctx); + return m_SimulationService.UpdateAgent(destination, agent, new EntityTransferContext()); } } diff --git a/OpenSim/Server/Handlers/Simulation/SimulationServiceInConnector.cs b/OpenSim/Server/Handlers/Simulation/SimulationServiceInConnector.cs index 0da08f8a70..ef34c4aef2 100644 --- a/OpenSim/Server/Handlers/Simulation/SimulationServiceInConnector.cs +++ b/OpenSim/Server/Handlers/Simulation/SimulationServiceInConnector.cs @@ -49,9 +49,7 @@ namespace OpenSim.Server.Handlers.Simulation // This one MUST be a stream handler because compressed fatpacks // are pure binary and shoehorning that into a string with UTF-8 // encoding breaks it - server.AddStreamHandler(new AgentPostHandler(m_LocalSimulationService)); - server.AddStreamHandler(new AgentPutHandler(m_LocalSimulationService)); - server.AddHTTPHandler("/agent/", new AgentHandler(m_LocalSimulationService).Handler); + server.AddSimpleStreamHandler(new AgentSimpleHandler(m_LocalSimulationService), true); server.AddHTTPHandler("/object/", new ObjectHandler(m_LocalSimulationService).Handler); } } diff --git a/OpenSim/Server/ServerMain.cs b/OpenSim/Server/ServerMain.cs index c180ca639a..56ac55defd 100644 --- a/OpenSim/Server/ServerMain.cs +++ b/OpenSim/Server/ServerMain.cs @@ -157,13 +157,16 @@ namespace OpenSim.Server if (parts.Length > 1) friendlyName = parts[1]; - IHttpServer server; + BaseHttpServer server; if (port != 0) - server = MainServer.GetHttpServer(port); + server = (BaseHttpServer)MainServer.GetHttpServer(port); else server = MainServer.Instance; + if (friendlyName == "LLLoginServiceInConnector") + server.AddSimpleStreamHandler(new IndexPHPHandler(server)); + m_log.InfoFormat("[SERVER]: Loading {0} on port {1}", friendlyName, server.Port); IServiceConnector connector = null;