diff --git a/OpenSim.Framework/UserProfileManager.cs b/OpenSim.Framework/UserProfileManager.cs index 22375bc3d3..ef5ab71618 100644 --- a/OpenSim.Framework/UserProfileManager.cs +++ b/OpenSim.Framework/UserProfileManager.cs @@ -32,166 +32,355 @@ namespace OpenSim.Framework.User DefaultStartupMsg = message; } + /* public virtual string ParseXMLRPC(string requestBody) + { + XmlRpcRequest request = (XmlRpcRequest)(new XmlRpcRequestDeserializer()).Deserialize(requestBody); + + Hashtable requestData = (Hashtable)request.Params[0]; + switch (request.MethodName) + { + case "login_to_simulator":*/ + public virtual string ParseXMLRPC(string requestBody) { + XmlRpcRequest request = (XmlRpcRequest)(new XmlRpcRequestDeserializer()).Deserialize(requestBody); - Hashtable requestData = (Hashtable)request.Params[0]; switch (request.MethodName) { case "login_to_simulator": - bool GoodXML = (requestData.Contains("first") && requestData.Contains("last") && requestData.Contains("passwd")); - bool GoodLogin = false; - string firstname = ""; - string lastname = ""; - string passwd = ""; + XmlRpcResponse response = XmlRpcLoginMethod(request); - if (GoodXML) - { - firstname = (string)requestData["first"]; - lastname = (string)requestData["last"]; - passwd = (string)requestData["passwd"]; - GoodLogin = AuthenticateUser(firstname, lastname, passwd); - } - - - if (!(GoodXML && GoodLogin)) - { - XmlRpcResponse LoginErrorResp = new XmlRpcResponse(); - Hashtable ErrorRespData = new Hashtable(); - ErrorRespData["reason"] = "key"; - ErrorRespData["message"] = "Error connecting to grid. Please double check your login details and check with the grid owner if you are sure these are correct"; - ErrorRespData["login"] = "false"; - LoginErrorResp.Value = ErrorRespData; - return (Regex.Replace(XmlRpcResponseSerializer.Singleton.Serialize(LoginErrorResp), " encoding=\"utf-16\"", "")); - } - - UserProfile TheUser = GetProfileByName(firstname, lastname); - - /* - if (!((TheUser.CurrentSessionID == null) && (TheUser.CurrentSecureSessionID == null))) - { - XmlRpcResponse PresenceErrorResp = new XmlRpcResponse(); - Hashtable PresenceErrorRespData = new Hashtable(); - PresenceErrorRespData["reason"] = "presence"; - PresenceErrorRespData["message"] = "You appear to be already logged in, if this is not the case please wait for your session to timeout, if this takes longer than a few minutes please contact the grid owner"; - PresenceErrorRespData["login"] = "false"; - PresenceErrorResp.Value = PresenceErrorRespData; - return (Regex.Replace(XmlRpcResponseSerializer.Singleton.Serialize(PresenceErrorResp), " encoding=\"utf-16\"", "")); - - }*/ - - try - { - LLUUID AgentID = TheUser.UUID; - TheUser.InitSessionData(); - // SimProfile SimInfo = new SimProfile(); - // SimInfo = SimInfo.LoadFromGrid(TheUser.homeregionhandle, GridURL, GridSendKey, GridRecvKey); - - XmlRpcResponse LoginGoodResp = new XmlRpcResponse(); - Hashtable LoginGoodData = new Hashtable(); - - Hashtable GlobalT = new Hashtable(); - GlobalT["sun_texture_id"] = "cce0f112-878f-4586-a2e2-a8f104bba271"; - GlobalT["cloud_texture_id"] = "fc4b9f0b-d008-45c6-96a4-01dd947ac621"; - GlobalT["moon_texture_id"] = "fc4b9f0b-d008-45c6-96a4-01dd947ac621"; - ArrayList GlobalTextures = new ArrayList(); - GlobalTextures.Add(GlobalT); - - Hashtable LoginFlagsHash = new Hashtable(); - LoginFlagsHash["daylight_savings"] = "N"; - LoginFlagsHash["stipend_since_login"] = "N"; - LoginFlagsHash["gendered"] = "Y"; - LoginFlagsHash["ever_logged_in"] = "Y"; - ArrayList LoginFlags = new ArrayList(); - LoginFlags.Add(LoginFlagsHash); - - Hashtable uiconfig = new Hashtable(); - uiconfig["allow_first_life"] = "Y"; - ArrayList ui_config = new ArrayList(); - ui_config.Add(uiconfig); - - Hashtable ClassifiedCategoriesHash = new Hashtable(); - ClassifiedCategoriesHash["category_name"] = "bla bla"; - ClassifiedCategoriesHash["category_id"] = (Int32)1; - ArrayList ClassifiedCategories = new ArrayList(); - ClassifiedCategories.Add(ClassifiedCategoriesHash); - - Console.WriteLine("copying inventory data to response"); - ArrayList AgentInventory = new ArrayList(); - foreach (InventoryFolder InvFolder in TheUser.Inventory.InventoryFolders.Values) - { - Hashtable TempHash = new Hashtable(); - TempHash["name"] = InvFolder.FolderName; - TempHash["parent_id"] = InvFolder.ParentID.ToStringHyphenated(); - TempHash["version"] = (Int32)InvFolder.Version; - TempHash["type_default"] = (Int32)InvFolder.DefaultType; - TempHash["folder_id"] = InvFolder.FolderID.ToStringHyphenated(); - AgentInventory.Add(TempHash); - } - - Hashtable InventoryRootHash = new Hashtable(); - InventoryRootHash["folder_id"] = TheUser.Inventory.InventoryRoot.FolderID.ToStringHyphenated(); - ArrayList InventoryRoot = new ArrayList(); - InventoryRoot.Add(InventoryRootHash); - - Hashtable InitialOutfitHash = new Hashtable(); - InitialOutfitHash["folder_name"] = "Nightclub Female"; - InitialOutfitHash["gender"] = "female"; - ArrayList InitialOutfit = new ArrayList(); - InitialOutfit.Add(InitialOutfitHash); - - uint circode = (uint)(Util.RandomClass.Next()); - //TheUser.AddSimCircuit(circode, SimInfo.UUID); - - LoginGoodData["last_name"] = TheUser.lastname ; - LoginGoodData["ui-config"] = ui_config; - LoginGoodData["sim_ip"] = "127.0.0.1"; //SimInfo.sim_ip.ToString(); - LoginGoodData["login-flags"] = LoginFlags; - LoginGoodData["global-textures"] = GlobalTextures; - LoginGoodData["classified_categories"] = ClassifiedCategories; - LoginGoodData["event_categories"] = new ArrayList(); - LoginGoodData["inventory-skeleton"] = AgentInventory; - LoginGoodData["inventory-skel-lib"] = new ArrayList(); - LoginGoodData["inventory-root"] = InventoryRoot; - LoginGoodData["event_notifications"] = new ArrayList(); - LoginGoodData["gestures"] = new ArrayList(); - LoginGoodData["inventory-lib-owner"] = new ArrayList(); - LoginGoodData["initial-outfit"] = InitialOutfit; - LoginGoodData["seconds_since_epoch"] = (Int32)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds; - LoginGoodData["start_location"] = "last"; - LoginGoodData["home"] = "{'region_handle':[r" + (997 * 256).ToString() + ",r" + (996 * 256).ToString() + "], 'position':[r" + TheUser.homepos.X.ToString() + ",r" + TheUser.homepos.Y.ToString() + ",r" + TheUser.homepos.Z.ToString() + "], 'look_at':[r" + TheUser.homelookat.X.ToString() + ",r" + TheUser.homelookat.Y.ToString() + ",r" + TheUser.homelookat.Z.ToString() + "]}"; - LoginGoodData["message"] = DefaultStartupMsg; - LoginGoodData["first_name"] = TheUser.firstname ; - LoginGoodData["circuit_code"] = (Int32)circode; - LoginGoodData["sim_port"] = 9000; //(Int32)SimInfo.sim_port; - LoginGoodData["secure_session_id"] = TheUser.CurrentSecureSessionID.ToStringHyphenated(); - LoginGoodData["look_at"] = "\n[r" + TheUser.homelookat.X.ToString() + ",r" + TheUser.homelookat.Y.ToString() + ",r" + TheUser.homelookat.Z.ToString() + "]\n"; - LoginGoodData["agent_id"] = AgentID.ToStringHyphenated(); - LoginGoodData["region_y"] = (Int32) 996 * 256; // (Int32)SimInfo.RegionLocY * 256; - LoginGoodData["region_x"] = (Int32) 997 * 256; //SimInfo.RegionLocX * 256; - LoginGoodData["seed_capability"] = null; - LoginGoodData["agent_access"] = "M"; - LoginGoodData["session_id"] = TheUser.CurrentSessionID.ToStringHyphenated(); - LoginGoodData["login"] = "true"; - - this.CustomiseResponse(ref LoginGoodData, TheUser); - LoginGoodResp.Value = LoginGoodData; - //TheUser.SendDataToSim(SimInfo); - return (Regex.Replace(XmlRpcResponseSerializer.Singleton.Serialize(LoginGoodResp), "utf-16", "utf-8")); - - } - catch (Exception E) - { - Console.WriteLine(E.ToString()); - } - - break; + return (Regex.Replace(XmlRpcResponseSerializer.Singleton.Serialize(response), "utf-16", "utf-8")); } return ""; } + /* public XmlRpcResponse XmlRpcLoginMethod(XmlRpcRequest request) + { + XmlRpcResponse response = new XmlRpcResponse(); + Hashtable requestData = (Hashtable)request.Params[0]; + + bool GoodXML = (requestData.Contains("first") && requestData.Contains("last") && requestData.Contains("passwd")); + bool GoodLogin = false; + string firstname = ""; + string lastname = ""; + string passwd = ""; + + if (GoodXML) + { + firstname = (string)requestData["first"]; + lastname = (string)requestData["last"]; + passwd = (string)requestData["passwd"]; + GoodLogin = AuthenticateUser(firstname, lastname, passwd); + } + + + if (!(GoodXML && GoodLogin)) + { + XmlRpcResponse LoginErrorResp = new XmlRpcResponse(); + Hashtable ErrorRespData = new Hashtable(); + ErrorRespData["reason"] = "key"; + ErrorRespData["message"] = "Error connecting to grid. Please double check your login details and check with the grid owner if you are sure these are correct"; + ErrorRespData["login"] = "false"; + LoginErrorResp.Value = ErrorRespData; + return (Regex.Replace(XmlRpcResponseSerializer.Singleton.Serialize(LoginErrorResp), " encoding=\"utf-16\"", "")); + } + + UserProfile TheUser = GetProfileByName(firstname, lastname); + + + if (!((TheUser.CurrentSessionID == null) && (TheUser.CurrentSecureSessionID == null))) + { + XmlRpcResponse PresenceErrorResp = new XmlRpcResponse(); + Hashtable PresenceErrorRespData = new Hashtable(); + PresenceErrorRespData["reason"] = "presence"; + PresenceErrorRespData["message"] = "You appear to be already logged in, if this is not the case please wait for your session to timeout, if this takes longer than a few minutes please contact the grid owner"; + PresenceErrorRespData["login"] = "false"; + PresenceErrorResp.Value = PresenceErrorRespData; + return (Regex.Replace(XmlRpcResponseSerializer.Singleton.Serialize(PresenceErrorResp), " encoding=\"utf-16\"", "")); + + } + + try + { + LLUUID AgentID = TheUser.UUID; + TheUser.InitSessionData(); + // SimProfile SimInfo = new SimProfile(); + // SimInfo = SimInfo.LoadFromGrid(TheUser.homeregionhandle, GridURL, GridSendKey, GridRecvKey); + + XmlRpcResponse LoginGoodResp = new XmlRpcResponse(); + Hashtable LoginGoodData = new Hashtable(); + + Hashtable GlobalT = new Hashtable(); + GlobalT["sun_texture_id"] = "cce0f112-878f-4586-a2e2-a8f104bba271"; + GlobalT["cloud_texture_id"] = "fc4b9f0b-d008-45c6-96a4-01dd947ac621"; + GlobalT["moon_texture_id"] = "fc4b9f0b-d008-45c6-96a4-01dd947ac621"; + ArrayList GlobalTextures = new ArrayList(); + GlobalTextures.Add(GlobalT); + + Hashtable LoginFlagsHash = new Hashtable(); + LoginFlagsHash["daylight_savings"] = "N"; + LoginFlagsHash["stipend_since_login"] = "N"; + LoginFlagsHash["gendered"] = "Y"; + LoginFlagsHash["ever_logged_in"] = "Y"; + ArrayList LoginFlags = new ArrayList(); + LoginFlags.Add(LoginFlagsHash); + + Hashtable uiconfig = new Hashtable(); + uiconfig["allow_first_life"] = "Y"; + ArrayList ui_config = new ArrayList(); + ui_config.Add(uiconfig); + + Hashtable ClassifiedCategoriesHash = new Hashtable(); + ClassifiedCategoriesHash["category_name"] = "bla bla"; + ClassifiedCategoriesHash["category_id"] = (Int32)1; + ArrayList ClassifiedCategories = new ArrayList(); + ClassifiedCategories.Add(ClassifiedCategoriesHash); + + Console.WriteLine("copying inventory data to response"); + ArrayList AgentInventory = new ArrayList(); + foreach (InventoryFolder InvFolder in TheUser.Inventory.InventoryFolders.Values) + { + Hashtable TempHash = new Hashtable(); + TempHash["name"] = InvFolder.FolderName; + TempHash["parent_id"] = InvFolder.ParentID.ToStringHyphenated(); + TempHash["version"] = (Int32)InvFolder.Version; + TempHash["type_default"] = (Int32)InvFolder.DefaultType; + TempHash["folder_id"] = InvFolder.FolderID.ToStringHyphenated(); + AgentInventory.Add(TempHash); + } + + Hashtable InventoryRootHash = new Hashtable(); + InventoryRootHash["folder_id"] = TheUser.Inventory.InventoryRoot.FolderID.ToStringHyphenated(); + ArrayList InventoryRoot = new ArrayList(); + InventoryRoot.Add(InventoryRootHash); + + Hashtable InitialOutfitHash = new Hashtable(); + InitialOutfitHash["folder_name"] = "Nightclub Female"; + InitialOutfitHash["gender"] = "female"; + ArrayList InitialOutfit = new ArrayList(); + InitialOutfit.Add(InitialOutfitHash); + + uint circode = (uint)(Util.RandomClass.Next()); + //TheUser.AddSimCircuit(circode, SimInfo.UUID); + + LoginGoodData["last_name"] = TheUser.lastname ; + LoginGoodData["ui-config"] = ui_config; + LoginGoodData["sim_ip"] = "127.0.0.1"; //SimInfo.sim_ip.ToString(); + LoginGoodData["login-flags"] = LoginFlags; + LoginGoodData["global-textures"] = GlobalTextures; + LoginGoodData["classified_categories"] = ClassifiedCategories; + LoginGoodData["event_categories"] = new ArrayList(); + LoginGoodData["inventory-skeleton"] = AgentInventory; + LoginGoodData["inventory-skel-lib"] = new ArrayList(); + LoginGoodData["inventory-root"] = InventoryRoot; + LoginGoodData["event_notifications"] = new ArrayList(); + LoginGoodData["gestures"] = new ArrayList(); + LoginGoodData["inventory-lib-owner"] = new ArrayList(); + LoginGoodData["initial-outfit"] = InitialOutfit; + LoginGoodData["seconds_since_epoch"] = (Int32)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds; + LoginGoodData["start_location"] = "last"; + LoginGoodData["home"] = "{'region_handle':[r" + (997 * 256).ToString() + ",r" + (996 * 256).ToString() + "], 'position':[r" + TheUser.homepos.X.ToString() + ",r" + TheUser.homepos.Y.ToString() + ",r" + TheUser.homepos.Z.ToString() + "], 'look_at':[r" + TheUser.homelookat.X.ToString() + ",r" + TheUser.homelookat.Y.ToString() + ",r" + TheUser.homelookat.Z.ToString() + "]}"; + LoginGoodData["message"] = DefaultStartupMsg; + LoginGoodData["first_name"] = TheUser.firstname ; + LoginGoodData["circuit_code"] = (Int32)circode; + LoginGoodData["sim_port"] = 9000; //(Int32)SimInfo.sim_port; + LoginGoodData["secure_session_id"] = TheUser.CurrentSecureSessionID.ToStringHyphenated(); + LoginGoodData["look_at"] = "\n[r" + TheUser.homelookat.X.ToString() + ",r" + TheUser.homelookat.Y.ToString() + ",r" + TheUser.homelookat.Z.ToString() + "]\n"; + LoginGoodData["agent_id"] = AgentID.ToStringHyphenated(); + LoginGoodData["region_y"] = (Int32) 996 * 256; // (Int32)SimInfo.RegionLocY * 256; + LoginGoodData["region_x"] = (Int32) 997 * 256; //SimInfo.RegionLocX * 256; + LoginGoodData["seed_capability"] = null; + LoginGoodData["agent_access"] = "M"; + LoginGoodData["session_id"] = TheUser.CurrentSessionID.ToStringHyphenated(); + LoginGoodData["login"] = "true"; + + this.CustomiseResponse(ref LoginGoodData, TheUser); + LoginGoodResp.Value = LoginGoodData; + //TheUser.SendDataToSim(SimInfo); + return (Regex.Replace(XmlRpcResponseSerializer.Singleton.Serialize(LoginGoodResp), "utf-16", "utf-8")); + + } + catch (Exception E) + { + Console.WriteLine(E.ToString()); + } + + break; + } + + return ""; + }*/ + + public XmlRpcResponse XmlRpcLoginMethod(XmlRpcRequest request) + { + XmlRpcResponse response = new XmlRpcResponse(); + Hashtable requestData = (Hashtable)request.Params[0]; + + bool GoodXML = (requestData.Contains("first") && requestData.Contains("last") && requestData.Contains("passwd")); + bool GoodLogin = false; + string firstname = ""; + string lastname = ""; + string passwd = ""; + + if (GoodXML) + { + firstname = (string)requestData["first"]; + lastname = (string)requestData["last"]; + passwd = (string)requestData["passwd"]; + GoodLogin = AuthenticateUser(firstname, lastname, passwd); + } + + + if (!(GoodXML && GoodLogin)) + { + response = CreateErrorConnectingToGridResponse(); + } + else + { + UserProfile TheUser = GetProfileByName(firstname, lastname); + //we need to sort out how sessions are logged out , currently the sim tells the gridserver + //but if as this suggests the userserver handles it then please have the sim telling the userserver instead + //as it really makes things messy for sandbox mode + //if (!((TheUser.CurrentSessionID == null) && (TheUser.CurrentSecureSessionID == null))) + // { + // response = CreateAlreadyLoggedInResponse(); + // } + //else + //{ + try + { + Hashtable responseData = new Hashtable(); + + LLUUID AgentID = TheUser.UUID; + TheUser.InitSessionData(); + // SimProfile SimInfo = new SimProfile(); + // SimInfo = SimInfo.LoadFromGrid(TheUser.homeregionhandle, GridURL, GridSendKey, GridRecvKey); + + + Hashtable GlobalT = new Hashtable(); + GlobalT["sun_texture_id"] = "cce0f112-878f-4586-a2e2-a8f104bba271"; + GlobalT["cloud_texture_id"] = "fc4b9f0b-d008-45c6-96a4-01dd947ac621"; + GlobalT["moon_texture_id"] = "fc4b9f0b-d008-45c6-96a4-01dd947ac621"; + ArrayList GlobalTextures = new ArrayList(); + GlobalTextures.Add(GlobalT); + + Hashtable LoginFlagsHash = new Hashtable(); + LoginFlagsHash["daylight_savings"] = "N"; + LoginFlagsHash["stipend_since_login"] = "N"; + LoginFlagsHash["gendered"] = "Y"; + LoginFlagsHash["ever_logged_in"] = "Y"; + ArrayList LoginFlags = new ArrayList(); + LoginFlags.Add(LoginFlagsHash); + + Hashtable uiconfig = new Hashtable(); + uiconfig["allow_first_life"] = "Y"; + ArrayList ui_config = new ArrayList(); + ui_config.Add(uiconfig); + + Hashtable ClassifiedCategoriesHash = new Hashtable(); + ClassifiedCategoriesHash["category_name"] = "bla bla"; + ClassifiedCategoriesHash["category_id"] = (Int32)1; + ArrayList ClassifiedCategories = new ArrayList(); + ClassifiedCategories.Add(ClassifiedCategoriesHash); + + ArrayList AgentInventory = new ArrayList(); + foreach (InventoryFolder InvFolder in TheUser.Inventory.InventoryFolders.Values) + { + Hashtable TempHash = new Hashtable(); + TempHash["name"] = InvFolder.FolderName; + TempHash["parent_id"] = InvFolder.ParentID.ToStringHyphenated(); + TempHash["version"] = (Int32)InvFolder.Version; + TempHash["type_default"] = (Int32)InvFolder.DefaultType; + TempHash["folder_id"] = InvFolder.FolderID.ToStringHyphenated(); + AgentInventory.Add(TempHash); + } + + Hashtable InventoryRootHash = new Hashtable(); + InventoryRootHash["folder_id"] = TheUser.Inventory.InventoryRoot.FolderID.ToStringHyphenated(); + ArrayList InventoryRoot = new ArrayList(); + InventoryRoot.Add(InventoryRootHash); + + Hashtable InitialOutfitHash = new Hashtable(); + InitialOutfitHash["folder_name"] = "Nightclub Female"; + InitialOutfitHash["gender"] = "female"; + ArrayList InitialOutfit = new ArrayList(); + InitialOutfit.Add(InitialOutfitHash); + + uint circode = (uint)(Util.RandomClass.Next()); + //TheUser.AddSimCircuit(circode, SimInfo.UUID); + + responseData["last_name"] = TheUser.lastname; + responseData["ui-config"] = ui_config; + responseData["sim_ip"] = "127.0.0.1"; //SimInfo.sim_ip.ToString(); + responseData["login-flags"] = LoginFlags; + responseData["global-textures"] = GlobalTextures; + responseData["classified_categories"] = ClassifiedCategories; + responseData["event_categories"] = new ArrayList(); + responseData["inventory-skeleton"] = AgentInventory; + responseData["inventory-skel-lib"] = new ArrayList(); + responseData["inventory-root"] = InventoryRoot; + responseData["event_notifications"] = new ArrayList(); + responseData["gestures"] = new ArrayList(); + responseData["inventory-lib-owner"] = new ArrayList(); + responseData["initial-outfit"] = InitialOutfit; + responseData["seconds_since_epoch"] = (Int32)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds; + responseData["start_location"] = "last"; + responseData["home"] = "{'region_handle':[r" + (997 * 256).ToString() + ",r" + (996 * 256).ToString() + "], 'position':[r" + TheUser.homepos.X.ToString() + ",r" + TheUser.homepos.Y.ToString() + ",r" + TheUser.homepos.Z.ToString() + "], 'look_at':[r" + TheUser.homelookat.X.ToString() + ",r" + TheUser.homelookat.Y.ToString() + ",r" + TheUser.homelookat.Z.ToString() + "]}"; + responseData["message"] = DefaultStartupMsg; + responseData["first_name"] = TheUser.firstname; + responseData["circuit_code"] = (Int32)circode; + responseData["sim_port"] = 9000; //(Int32)SimInfo.sim_port; + responseData["secure_session_id"] = TheUser.CurrentSecureSessionID.ToStringHyphenated(); + responseData["look_at"] = "\n[r" + TheUser.homelookat.X.ToString() + ",r" + TheUser.homelookat.Y.ToString() + ",r" + TheUser.homelookat.Z.ToString() + "]\n"; + responseData["agent_id"] = AgentID.ToStringHyphenated(); + responseData["region_y"] = (Int32)996 * 256; // (Int32)SimInfo.RegionLocY * 256; + responseData["region_x"] = (Int32)997 * 256; //SimInfo.RegionLocX * 256; + responseData["seed_capability"] = null; + responseData["agent_access"] = "M"; + responseData["session_id"] = TheUser.CurrentSessionID.ToStringHyphenated(); + responseData["login"] = "true"; + + this.CustomiseResponse(ref responseData, TheUser); + response.Value = responseData; + //TheUser.SendDataToSim(SimInfo); + + + + } + catch (Exception E) + { + Console.WriteLine(E.ToString()); + } + //} + } + return response; + } + + private static XmlRpcResponse CreateErrorConnectingToGridResponse() + { + XmlRpcResponse response = new XmlRpcResponse(); + Hashtable ErrorRespData = new Hashtable(); + ErrorRespData["reason"] = "key"; + ErrorRespData["message"] = "Error connecting to grid. Please double check your login details and check with the grid owner if you are sure these are correct"; + ErrorRespData["login"] = "false"; + response.Value = ErrorRespData; + return response; + } + + private static XmlRpcResponse CreateAlreadyLoggedInResponse() + { + XmlRpcResponse response = new XmlRpcResponse(); + Hashtable PresenceErrorRespData = new Hashtable(); + PresenceErrorRespData["reason"] = "presence"; + PresenceErrorRespData["message"] = "You appear to be already logged in, if this is not the case please wait for your session to timeout, if this takes longer than a few minutes please contact the grid owner"; + PresenceErrorRespData["login"] = "false"; + response.Value = PresenceErrorRespData; + return response; + } + public virtual void CustomiseResponse(ref Hashtable response, UserProfile theUser) { //default method set up to act as ogs user server @@ -203,8 +392,8 @@ namespace OpenSim.Framework.User response["home"] = "{'region_handle':[r" + (SimInfo.RegionLocX * 256).ToString() + ",r" + (SimInfo.RegionLocY * 256).ToString() + "], 'position':[r" + theUser.homepos.X.ToString() + ",r" + theUser.homepos.Y.ToString() + ",r" + theUser.homepos.Z.ToString() + "], 'look_at':[r" + theUser.homelookat.X.ToString() + ",r" + theUser.homelookat.Y.ToString() + ",r" + theUser.homelookat.Z.ToString() + "]}"; response["sim_ip"] = SimInfo.sim_ip.ToString(); response["sim_port"] = (Int32)SimInfo.sim_port; - response["region_y"] = (Int32) SimInfo.RegionLocY * 256; - response["region_x"] = (Int32) SimInfo.RegionLocX * 256; + response["region_y"] = (Int32)SimInfo.RegionLocY * 256; + response["region_x"] = (Int32)SimInfo.RegionLocX * 256; //default is ogs user server, so let the sim know about the user via a XmlRpcRequest Console.WriteLine(SimInfo.caps_url); diff --git a/OpenSim.RegionServer/CAPS/IXmlRPCHandler.cs b/OpenSim.RegionServer/CAPS/IXmlRPCHandler.cs deleted file mode 100644 index c3cbbcc85e..0000000000 --- a/OpenSim.RegionServer/CAPS/IXmlRPCHandler.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace OpenSim.CAPS -{ - public interface IXmlRPCHandler - { - string HandleRPC(string requestBody); - } -} diff --git a/OpenSim.RegionServer/CAPS/SimHttp.cs b/OpenSim.RegionServer/CAPS/SimHttp.cs deleted file mode 100644 index bfba635e45..0000000000 --- a/OpenSim.RegionServer/CAPS/SimHttp.cs +++ /dev/null @@ -1,241 +0,0 @@ -/* -Copyright (c) OpenSimCAPS project, http://osgrid.org/ - - -* All rights reserved. -* -* 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 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 ``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 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.Text; -using Nwc.XmlRpc; -using System.Threading; -using System.Text.RegularExpressions; -using System.Net; -using System.IO; -using System.Collections; -using System.Collections.Generic; -using libsecondlife; -using OpenSim.Framework.Console; -using OpenSim.Framework.Interfaces; -using OpenSim.Servers; - -namespace OpenSim.CAPS -{ - // Dummy HTTP server, does nothing useful for now - - public class SimCAPSHTTPServer : BaseHttpServer - { - private Thread m_workerThread; - private HttpListener m_httpListener; - private Dictionary m_restHandlers = new Dictionary(); - private Dictionary RPCHandlers = new Dictionary(); - private IGridServer m_gridServer; - private int m_port; - - public SimCAPSHTTPServer(IGridServer gridServer, int port) - { - OpenSim.Framework.Console.MainConsole.Instance.WriteLine("Starting up HTTP Server"); - m_workerThread = new Thread(new ThreadStart(StartHTTP)); - m_workerThread.Start(); - m_gridServer = gridServer; - m_port = port; - } - - public void StartHTTP() - { - try - { - OpenSim.Framework.Console.MainConsole.Instance.WriteLine("SimHttp.cs:StartHTTP() - Spawned main thread OK"); - m_httpListener = new HttpListener(); - - m_httpListener.Prefixes.Add("http://+:" + m_port + "/"); - m_httpListener.Start(); - - HttpListenerContext context; - while (true) - { - context = m_httpListener.GetContext(); - ThreadPool.QueueUserWorkItem(new WaitCallback(HandleRequest), context); - } - } - catch (Exception e) - { - OpenSim.Framework.Console.MainConsole.Instance.WriteLine(e.Message); - } - } - - public bool AddRestHandler(string path, IRestHandler handler) - { - if (!this.m_restHandlers.ContainsKey(path)) - { - this.m_restHandlers.Add(path, handler); - return true; - } - - //must already have a handler for that path so return false - return false; - } - - public bool AddXmlRPCHandler(string method, IXmlRPCHandler handler) - { - if (!this.RPCHandlers.ContainsKey(method)) - { - this.RPCHandlers.Add(method, handler); - return true; - } - - //must already have a handler for that path so return false - return false; - } - - protected virtual string ParseXMLRPC(string requestBody) - { - string responseString = ""; - try - { - XmlRpcRequest request = (XmlRpcRequest)(new XmlRpcRequestDeserializer()).Deserialize(requestBody); - - Hashtable requestData = (Hashtable)request.Params[0]; - switch (request.MethodName) - { - case "expect_user": - AgentCircuitData agent_data = new AgentCircuitData(); - agent_data.SessionID = new LLUUID((string)requestData["session_id"]); - agent_data.SecureSessionID = new LLUUID((string)requestData["secure_session_id"]); - agent_data.firstname = (string)requestData["firstname"]; - agent_data.lastname = (string)requestData["lastname"]; - agent_data.AgentID = new LLUUID((string)requestData["agent_id"]); - agent_data.circuitcode = Convert.ToUInt32(requestData["circuit_code"]); - if (m_gridServer.GetName() == "Remote") - { - ((RemoteGridBase) m_gridServer).agentcircuits.Add((uint)agent_data.circuitcode, agent_data); - } - responseString = ""; - break; - default: - if (this.RPCHandlers.ContainsKey(request.MethodName)) - { - //responseString = this.RPCHandlers[request.MethodName] - } - break; - } - } - catch (Exception e) - { - Console.WriteLine(e.ToString()); - } - return responseString; - } - - protected virtual string ParseREST(string requestBody, string requestURL, string requestMethod) - { - string[] path; - string pathDelimStr = "/"; - char[] pathDelimiter = pathDelimStr.ToCharArray(); - path = requestURL.Split(pathDelimiter); - - string responseString = ""; - - //path[0] should be empty so we are interested in path[1] - if (path.Length > 1) - { - if ((path[1] != "") && (this.m_restHandlers.ContainsKey(path[1]))) - { - responseString = this.m_restHandlers[path[1]].HandleREST(requestBody, requestURL, requestMethod); - } - } - - return responseString; - } - - protected virtual string ParseLLSDXML(string requestBody) - { - // dummy function for now - IMPLEMENT ME! - return ""; - } - - public virtual void HandleRequest(Object stateinfo) - { - // Console.WriteLine("new http incoming"); - HttpListenerContext context = (HttpListenerContext)stateinfo; - - HttpListenerRequest request = context.Request; - HttpListenerResponse response = context.Response; - - response.KeepAlive = false; - response.SendChunked = false; - - System.IO.Stream body = request.InputStream; - System.Text.Encoding encoding = System.Text.Encoding.UTF8; - System.IO.StreamReader reader = new System.IO.StreamReader(body, encoding); - - string requestBody = reader.ReadToEnd(); - body.Close(); - reader.Close(); - - //Console.WriteLine(request.HttpMethod + " " + request.RawUrl + " Http/" + request.ProtocolVersion.ToString() + " content type: " + request.ContentType); - //Console.WriteLine(requestBody); - - string responseString = ""; - switch (request.ContentType) - { - case "text/xml": - // must be XML-RPC, so pass to the XML-RPC parser - - responseString = ParseXMLRPC(requestBody); - response.AddHeader("Content-type", "text/xml"); - break; - - case "application/xml": - // probably LLSD we hope, otherwise it should be ignored by the parser - responseString = ParseLLSDXML(requestBody); - response.AddHeader("Content-type", "application/xml"); - break; - - case "application/x-www-form-urlencoded": - // a form data POST so send to the REST parser - responseString = ParseREST(requestBody, request.RawUrl, request.HttpMethod); - response.AddHeader("Content-type", "text/html"); - break; - - case null: - // must be REST or invalid crap, so pass to the REST parser - responseString = ParseREST(requestBody, request.RawUrl, request.HttpMethod); - response.AddHeader("Content-type", "text/html"); - break; - - } - - byte[] buffer = System.Text.Encoding.UTF8.GetBytes(responseString); - System.IO.Stream output = response.OutputStream; - response.SendChunked = false; - response.ContentLength64 = buffer.Length; - output.Write(buffer, 0, buffer.Length); - output.Close(); - } - } - - -} diff --git a/OpenSim.RegionServer/OpenSim.RegionServer.csproj b/OpenSim.RegionServer/OpenSim.RegionServer.csproj index d9d5f1a67f..13b976778a 100644 --- a/OpenSim.RegionServer/OpenSim.RegionServer.csproj +++ b/OpenSim.RegionServer/OpenSim.RegionServer.csproj @@ -117,7 +117,6 @@ Code - Code @@ -151,12 +150,6 @@ Code - - Code - - - Code - Code diff --git a/OpenSim.RegionServer/OpenSim.RegionServer.dll.build b/OpenSim.RegionServer/OpenSim.RegionServer.dll.build index ef7dce929a..0cb9bf612c 100644 --- a/OpenSim.RegionServer/OpenSim.RegionServer.dll.build +++ b/OpenSim.RegionServer/OpenSim.RegionServer.dll.build @@ -23,9 +23,6 @@ - - - diff --git a/OpenSim.RegionServer/OpenSimMain.cs b/OpenSim.RegionServer/OpenSimMain.cs index 07a2d6dbb2..651c0c69a8 100644 --- a/OpenSim.RegionServer/OpenSimMain.cs +++ b/OpenSim.RegionServer/OpenSimMain.cs @@ -45,6 +45,8 @@ using OpenSim.Assets; using OpenSim.CAPS; using OpenSim.Framework.Console; using OpenSim.Physics.Manager; +using Nwc.XmlRpc; +using OpenSim.Servers; namespace OpenSim { @@ -54,7 +56,8 @@ namespace OpenSim private World LocalWorld; private Grid GridServers; private SimConfig Cfg; - private SimCAPSHTTPServer HttpServer; + //private SimCAPSHTTPServer HttpServer; + private BaseHttpServer HttpServer; private AssetCache AssetCache; private InventoryCache InventoryCache; //public Dictionary ClientThreads = new Dictionary(); @@ -78,13 +81,13 @@ namespace OpenSim public bool user_accounts = false; protected ConsoleBase m_console; - - public OpenSimMain( bool sandBoxMode, bool startLoginServer, string physicsEngine ) + + public OpenSimMain(bool sandBoxMode, bool startLoginServer, string physicsEngine) { m_sandbox = sandBoxMode; m_loginserver = startLoginServer; m_physicsEngine = physicsEngine; - + m_console = new ConsoleBase("region-console.log", "Region", this); OpenSim.Framework.Console.MainConsole.Instance = m_console; } @@ -92,11 +95,11 @@ namespace OpenSim public virtual void StartUp() { GridServers = new Grid(); - if ( m_sandbox ) + if (m_sandbox) { GridServers.AssetDll = "OpenSim.GridInterfaces.Local.dll"; GridServers.GridDll = "OpenSim.GridInterfaces.Local.dll"; - + m_console.WriteLine("Starting in Sandbox mode"); } else @@ -108,7 +111,7 @@ namespace OpenSim } GridServers.Initialise(); - + startuptime = DateTime.Now; AssetCache = new AssetCache(GridServers.AssetServer); @@ -134,36 +137,74 @@ namespace OpenSim LocalWorld.PhysScene.SetTerrain(LocalWorld.LandMap); GridServers.AssetServer.SetServerInfo(Cfg.AssetURL, Cfg.AssetSendKey); - GridServers.GridServer.SetServerInfo(Cfg.GridURL, Cfg.GridSendKey, Cfg.GridRecvKey); + //GridServers.GridServer.SetServerInfo(Cfg.GridURL, Cfg.GridSendKey, Cfg.GridRecvKey); + IGridServer gridServer = GridServers.GridServer; + gridServer.SetServerInfo(Cfg.GridURL, Cfg.GridSendKey, Cfg.GridRecvKey); LocalWorld.LoadStorageDLL("OpenSim.Storage.LocalStorageDb4o.dll"); //all these dll names shouldn't be hard coded. LocalWorld.LoadPrimsFromStorage(); - if ( m_sandbox) + if (m_sandbox) { AssetCache.LoadDefaultTextureSet(); } - m_console.WriteLine("Main.cs:Startup() - Starting CAPS HTTP server"); - HttpServer = new SimCAPSHTTPServer(GridServers.GridServer, Cfg.IPListenPort); + m_console.WriteLine("Main.cs:Startup() - Initialising HTTP server"); + // HttpServer = new SimCAPSHTTPServer(GridServers.GridServer, Cfg.IPListenPort); + HttpServer = new BaseHttpServer(Cfg.IPListenPort); + + if (gridServer.GetName() == "Remote") + { + //we are in Grid mode so set a XmlRpc handler to handle "expect_user" calls from the user server + HttpServer.AddXmlRPCHandler("expect_user", + delegate(XmlRpcRequest request) + { + Hashtable requestData = (Hashtable)request.Params[0]; + AgentCircuitData agent_data = new AgentCircuitData(); + agent_data.SessionID = new LLUUID((string)requestData["session_id"]); + agent_data.SecureSessionID = new LLUUID((string)requestData["secure_session_id"]); + agent_data.firstname = (string)requestData["firstname"]; + agent_data.lastname = (string)requestData["lastname"]; + agent_data.AgentID = new LLUUID((string)requestData["agent_id"]); + agent_data.circuitcode = Convert.ToUInt32(requestData["circuit_code"]); + + ((RemoteGridBase)gridServer).agentcircuits.Add((uint)agent_data.circuitcode, agent_data); + + return new XmlRpcResponse(); + }); + } + LoginServer loginServer = null; if (m_loginserver && m_sandbox) { - loginServer = new LoginServer(GridServers.GridServer, Cfg.IPListenAddr, Cfg.IPListenPort, this.user_accounts); + loginServer = new LoginServer(gridServer, Cfg.IPListenAddr, Cfg.IPListenPort, this.user_accounts); loginServer.Startup(); - + } - if((m_loginserver) && (m_sandbox) && (user_accounts)) + + if ((m_loginserver) && (m_sandbox) && (user_accounts)) { + //sandbox mode with loginserver using accounts this.GridServers.UserServer = loginServer; HttpServer.AddRestHandler("Admin", new AdminWebFront("Admin", LocalWorld, loginServer)); + HttpServer.AddXmlRPCHandler("login_to_simulator", loginServer.LocalUserManager.XmlRpcLoginMethod); } - else + else if ((m_loginserver) && (m_sandbox)) { + //sandbox mode with loginserver not using accounts + HttpServer.AddRestHandler("Admin", new AdminWebFront("Admin", LocalWorld, null)); + HttpServer.AddXmlRPCHandler("login_to_simulator", loginServer.XmlRpcLoginMethod); + } + else + { + //not in sandbox mode so no loginserver, so we don't handle login attempts HttpServer.AddRestHandler("Admin", new AdminWebFront("Admin", LocalWorld, null)); } + m_console.WriteLine("Main.cs:Startup() - Starting HTTP server"); + HttpServer.Start(); + MainServerListener(); timer1.Enabled = true; @@ -207,12 +248,12 @@ namespace OpenSim int numBytes = Server.EndReceiveFrom(result, ref epSender); int packetEnd = numBytes - 1; packet = Packet.BuildPacket(RecvBuffer, ref packetEnd, ZeroBuffer); - + // This is either a new client or a packet to send to an old one - // if (OpenSimRoot.Instance.ClientThreads.ContainsKey(epSender)) + // if (OpenSimRoot.Instance.ClientThreads.ContainsKey(epSender)) // do we already have a circuit for this endpoint - if(this.clientCircuits.ContainsKey(epSender)) + if (this.clientCircuits.ContainsKey(epSender)) { ClientThreads[this.clientCircuits[epSender]].InPacket(packet); } @@ -223,7 +264,6 @@ namespace OpenSim SimClient newuser = new SimClient(epSender, useCircuit, LocalWorld, ClientThreads, AssetCache, GridServers.GridServer, this, InventoryCache, m_sandbox); if ((this.GridServers.UserServer != null) && (user_accounts)) { - Console.WriteLine("setting userserver"); newuser.UserServer = this.GridServers.UserServer; } //OpenSimRoot.Instance.ClientThreads.Add(epSender, newuser); @@ -256,11 +296,11 @@ namespace OpenSim } - public virtual void SendPacketTo(byte[] buffer, int size, SocketFlags flags, uint circuitcode )//EndPoint packetSender) + public virtual void SendPacketTo(byte[] buffer, int size, SocketFlags flags, uint circuitcode)//EndPoint packetSender) { // find the endpoint for this circuit EndPoint sendto = null; - foreach(KeyValuePair p in this.clientCircuits) + foreach (KeyValuePair p in this.clientCircuits) { if (p.Value == circuitcode) { @@ -304,7 +344,7 @@ namespace OpenSim { LocalWorld.Update(); } - + public void RunCmd(string command, string[] cmdparams) { switch (command) @@ -353,5 +393,5 @@ namespace OpenSim } } - + } diff --git a/OpenSim.RegionServer/UserServer/LocalUserProfileManager.cs b/OpenSim.RegionServer/UserServer/LocalUserProfileManager.cs index b31fedaee5..3ae7878faa 100644 --- a/OpenSim.RegionServer/UserServer/LocalUserProfileManager.cs +++ b/OpenSim.RegionServer/UserServer/LocalUserProfileManager.cs @@ -10,7 +10,7 @@ using libsecondlife; namespace OpenSim.UserServer { - class LocalUserProfileManager : UserProfileManager + public class LocalUserProfileManager : UserProfileManager { private IGridServer m_gridServer; private int m_port; diff --git a/OpenSim.RegionServer/UserServer/LoginServer.cs b/OpenSim.RegionServer/UserServer/LoginServer.cs index 7b4c1f09dc..a68e013622 100644 --- a/OpenSim.RegionServer/UserServer/LoginServer.cs +++ b/OpenSim.RegionServer/UserServer/LoginServer.cs @@ -50,7 +50,7 @@ namespace OpenSim.UserServer /// /// When running in local (default) mode , handles client logins. /// - public class LoginServer : LoginService , IUserServer + public class LoginServer : LoginService, IUserServer { private IGridServer m_gridServer; private ushort _loginPort = 8080; @@ -66,7 +66,15 @@ namespace OpenSim.UserServer private int m_simPort; private string m_simAddr; - public LoginServer(IGridServer gridServer, string simAddr, int simPort , bool useAccounts) + public LocalUserProfileManager LocalUserManager + { + get + { + return userManager; + } + } + + public LoginServer(IGridServer gridServer, string simAddr, int simPort, bool useAccounts) { m_gridServer = gridServer; m_simPort = simPort; @@ -74,6 +82,14 @@ namespace OpenSim.UserServer this.userAccounts = useAccounts; } + public void Startup() + { + this.InitializeLogin(); + //Thread runLoginProxy = new Thread(new ThreadStart(RunLogin)); + //runLoginProxy.IsBackground = true; + //runLoginProxy.Start(); + } + // InitializeLogin: initialize the login private void InitializeLogin() { @@ -94,129 +110,124 @@ namespace OpenSim.UserServer SR.Close(); this._mpasswd = EncodePassword("testpass"); - userManager = new LocalUserProfileManager(this.m_gridServer, m_simPort, m_simAddr ); + userManager = new LocalUserProfileManager(this.m_gridServer, m_simPort, m_simAddr); userManager.InitUserProfiles(); userManager.SetKeys("", "", "", "Welcome to OpenSim"); - loginServer = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); - loginServer.Bind(new IPEndPoint(remoteAddress, _loginPort)); - loginServer.Listen(1); + //loginServer = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); + // loginServer.Bind(new IPEndPoint(remoteAddress, _loginPort)); + //loginServer.Listen(1); } - public void Startup() - { - this.InitializeLogin(); - Thread runLoginProxy = new Thread(new ThreadStart(RunLogin)); - runLoginProxy.IsBackground = true; - runLoginProxy.Start(); - } - - private void RunLogin() - { - Console.WriteLine("Starting Login Server"); - try - { - for (; ; ) - { - Socket client = loginServer.Accept(); - IPEndPoint clientEndPoint = (IPEndPoint)client.RemoteEndPoint; - - - NetworkStream networkStream = new NetworkStream(client); - StreamReader networkReader = new StreamReader(networkStream); - StreamWriter networkWriter = new StreamWriter(networkStream); - - try - { - LoginRequest(networkReader, networkWriter); - } - catch (Exception e) - { - Console.WriteLine(e.Message); - } - - networkWriter.Close(); - networkReader.Close(); - networkStream.Close(); - - client.Close(); - - // send any packets queued for injection - - } - } - catch (Exception e) - { - Console.WriteLine(e.Message); - Console.WriteLine(e.StackTrace); - } - } - - // ProxyLogin: proxy a login request - private void LoginRequest(StreamReader reader, StreamWriter writer) - { - lock (this) - { - string line; - int contentLength = 0; - // read HTTP header - do - { - // read one line of the header - line = reader.ReadLine(); - - // check for premature EOF - if (line == null) - throw new Exception("EOF in client HTTP header"); - - // look for Content-Length - Match match = (new Regex(@"Content-Length: (\d+)$")).Match(line); - if (match.Success) - contentLength = Convert.ToInt32(match.Groups[1].Captures[0].ToString()); - } while (line != ""); - - // read the HTTP body into a buffer - char[] content = new char[contentLength]; - reader.Read(content, 0, contentLength); - - if (this.userAccounts) - { - //ask the UserProfile Manager to process the request - string reply = this.userManager.ParseXMLRPC(new String(content)); - // forward the XML-RPC response to the client - writer.WriteLine("HTTP/1.0 200 OK"); - writer.WriteLine("Content-type: text/xml"); - writer.WriteLine(); - writer.WriteLine(reply); - } - else - { - //handle ourselves - XmlRpcRequest request = (XmlRpcRequest)(new XmlRpcRequestDeserializer()).Deserialize(new String(content)); - if (request.MethodName == "login_to_simulator") - { - this.ProcessXmlRequest(request, writer); - } - else - { - XmlRpcResponse PresenceErrorResp = new XmlRpcResponse(); - Hashtable PresenceErrorRespData = new Hashtable(); - PresenceErrorRespData["reason"] = "XmlRequest"; ; - PresenceErrorRespData["message"] = "Unknown Rpc request"; - PresenceErrorRespData["login"] = "false"; - PresenceErrorResp.Value = PresenceErrorRespData; - string reply = Regex.Replace(XmlRpcResponseSerializer.Singleton.Serialize(PresenceErrorResp), " encoding=\"utf-16\"", ""); - writer.WriteLine("HTTP/1.0 200 OK"); - writer.WriteLine("Content-type: text/xml"); - writer.WriteLine(); - writer.WriteLine(reply); - } - } - } - } - - public bool ProcessXmlRequest(XmlRpcRequest request, StreamWriter writer) + /* private void RunLogin() + { + Console.WriteLine("Starting Login Server"); + try + { + for (; ; ) + { + Socket client = loginServer.Accept(); + IPEndPoint clientEndPoint = (IPEndPoint)client.RemoteEndPoint; + + + NetworkStream networkStream = new NetworkStream(client); + StreamReader networkReader = new StreamReader(networkStream); + StreamWriter networkWriter = new StreamWriter(networkStream); + + try + { + LoginRequest(networkReader, networkWriter); + } + catch (Exception e) + { + Console.WriteLine(e.Message); + } + + networkWriter.Close(); + networkReader.Close(); + networkStream.Close(); + + client.Close(); + + // send any packets queued for injection + + } + } + catch (Exception e) + { + Console.WriteLine(e.Message); + Console.WriteLine(e.StackTrace); + } + } + + // ProxyLogin: proxy a login request + private void LoginRequest(StreamReader reader, StreamWriter writer) + { + lock (this) + { + string line; + int contentLength = 0; + // read HTTP header + do + { + // read one line of the header + line = reader.ReadLine(); + + // check for premature EOF + if (line == null) + throw new Exception("EOF in client HTTP header"); + + // look for Content-Length + Match match = (new Regex(@"Content-Length: (\d+)$")).Match(line); + if (match.Success) + contentLength = Convert.ToInt32(match.Groups[1].Captures[0].ToString()); + } while (line != ""); + + // read the HTTP body into a buffer + char[] content = new char[contentLength]; + reader.Read(content, 0, contentLength); + + if (this.userAccounts) + { + //ask the UserProfile Manager to process the request + string reply = this.userManager.ParseXMLRPC(new String(content)); + // forward the XML-RPC response to the client + writer.WriteLine("HTTP/1.0 200 OK"); + writer.WriteLine("Content-type: text/xml"); + writer.WriteLine(); + writer.WriteLine(reply); + } + else + { + //handle ourselves + XmlRpcRequest request = (XmlRpcRequest)(new XmlRpcRequestDeserializer()).Deserialize(new String(content)); + if (request.MethodName == "login_to_simulator") + { + this.ProcessXmlRequest(request, writer); + } + else + { + XmlRpcResponse PresenceErrorResp = new XmlRpcResponse(); + Hashtable PresenceErrorRespData = new Hashtable(); + PresenceErrorRespData["reason"] = "XmlRequest"; ; + PresenceErrorRespData["message"] = "Unknown Rpc request"; + PresenceErrorRespData["login"] = "false"; + PresenceErrorResp.Value = PresenceErrorRespData; + string reply = Regex.Replace(XmlRpcResponseSerializer.Singleton.Serialize(PresenceErrorResp), " encoding=\"utf-16\"", ""); + writer.WriteLine("HTTP/1.0 200 OK"); + writer.WriteLine("Content-type: text/xml"); + writer.WriteLine(); + writer.WriteLine(reply); + } + } + } + } + */ + //public bool ProcessXmlRequest(XmlRpcRequest request, StreamWriter writer) + + public XmlRpcResponse XmlRpcLoginMethod(XmlRpcRequest request) { + Console.WriteLine("login attempt"); Hashtable requestData = (Hashtable)request.Params[0]; string first; string last; @@ -224,6 +235,8 @@ namespace OpenSim.UserServer LLUUID Agent; LLUUID Session; + XmlRpcResponse response = new XmlRpcResponse(); + //get login name if (requestData.Contains("first")) { @@ -254,18 +267,24 @@ namespace OpenSim.UserServer if (!Authenticate(first, last, passwd)) { - XmlRpcResponse PresenceErrorResp = new XmlRpcResponse(); - Hashtable PresenceErrorRespData = new Hashtable(); - PresenceErrorRespData["reason"] = "key"; ; - PresenceErrorRespData["message"] = "You have entered an invalid name/password combination. Check Caps/lock."; - PresenceErrorRespData["login"] = "false"; - PresenceErrorResp.Value = PresenceErrorRespData; - string reply = Regex.Replace(XmlRpcResponseSerializer.Singleton.Serialize(PresenceErrorResp), " encoding=\"utf-16\"", ""); - writer.WriteLine("HTTP/1.0 200 OK"); - writer.WriteLine("Content-type: text/xml"); - writer.WriteLine(); - writer.WriteLine(reply); - return false; + /* XmlRpcResponse PresenceErrorResp = new XmlRpcResponse(); + Hashtable PresenceErrorRespData = new Hashtable(); + PresenceErrorRespData["reason"] = "key"; ; + PresenceErrorRespData["message"] = "You have entered an invalid name/password combination. Check Caps/lock."; + PresenceErrorRespData["login"] = "false"; + PresenceErrorResp.Value = PresenceErrorRespData; + string reply = Regex.Replace(XmlRpcResponseSerializer.Singleton.Serialize(PresenceErrorResp), " encoding=\"utf-16\"", ""); + writer.WriteLine("HTTP/1.0 200 OK"); + writer.WriteLine("Content-type: text/xml"); + writer.WriteLine(); + writer.WriteLine(reply); + return false;*/ + + Hashtable loginError = new Hashtable(); + loginError["reason"] = "key"; ; + loginError["message"] = "You have entered an invalid name/password combination. Check Caps/lock."; + loginError["login"] = "false"; + response.Value = loginError; } NumClients++; @@ -291,15 +310,15 @@ namespace OpenSim.UserServer ArrayList GlobalTextures = new ArrayList(); GlobalTextures.Add(GlobalT); - XmlRpcResponse response = (XmlRpcResponse)(new XmlRpcResponseDeserializer()).Deserialize(this._defaultResponse); + response = (XmlRpcResponse)(new XmlRpcResponseDeserializer()).Deserialize(this._defaultResponse); Hashtable responseData = (Hashtable)response.Value; responseData["sim_port"] = m_simPort; responseData["sim_ip"] = m_simAddr; responseData["agent_id"] = Agent.ToStringHyphenated(); responseData["session_id"] = Session.ToStringHyphenated(); - responseData["secure_session_id"]= secureSess.ToStringHyphenated(); - responseData["circuit_code"] = (Int32)(Util.RandomClass.Next()); + responseData["secure_session_id"] = secureSess.ToStringHyphenated(); + responseData["circuit_code"] = (Int32)(Util.RandomClass.Next()); responseData["seconds_since_epoch"] = (Int32)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds; responseData["login-flags"] = LoginFlags; responseData["global-textures"] = GlobalTextures; @@ -337,16 +356,16 @@ namespace OpenSim.UserServer ((LocalGridBase)m_gridServer).AddNewSession(_login); } - // forward the XML-RPC response to the client - writer.WriteLine("HTTP/1.0 200 OK"); - writer.WriteLine("Content-type: text/xml"); - writer.WriteLine(); + /* // forward the XML-RPC response to the client + writer.WriteLine("HTTP/1.0 200 OK"); + writer.WriteLine("Content-type: text/xml"); + writer.WriteLine(); - XmlTextWriter responseWriter = new XmlTextWriter(writer); - XmlRpcResponseSerializer.Singleton.Serialize(responseWriter, response); - responseWriter.Close(); + XmlTextWriter responseWriter = new XmlTextWriter(writer); + XmlRpcResponseSerializer.Singleton.Serialize(responseWriter, response); + responseWriter.Close();*/ - return true; + return response; } protected virtual void CustomiseLoginResponse(Hashtable responseData, string first, string last) diff --git a/Servers/BaseHttpServer.cs b/Servers/BaseHttpServer.cs index 28849dca93..bac7e86715 100644 --- a/Servers/BaseHttpServer.cs +++ b/Servers/BaseHttpServer.cs @@ -1,10 +1,211 @@ using System; using System.Collections.Generic; +using System.Net; using System.Text; +using System.Text.RegularExpressions; +using System.Threading; +using OpenSim.CAPS; +using Nwc.XmlRpc; +using System.Collections; namespace OpenSim.Servers { public class BaseHttpServer { + protected Thread m_workerThread; + protected HttpListener m_httpListener; + protected Dictionary m_restHandlers = new Dictionary(); + protected Dictionary m_rpcHandlers = new Dictionary(); + protected int m_port; + + public BaseHttpServer(int port) + { + m_port = port; + } + + public bool AddRestHandler(string path, IRestHandler handler) + { + if (!this.m_restHandlers.ContainsKey(path)) + { + this.m_restHandlers.Add(path, handler); + return true; + } + + //must already have a handler for that path so return false + return false; + } + + public bool AddXmlRPCHandler(string method, XmlRpcMethod handler) + { + if (!this.m_rpcHandlers.ContainsKey(method)) + { + this.m_rpcHandlers.Add(method, handler); + return true; + } + + //must already have a handler for that path so return false + return false; + } + + protected virtual string ProcessXMLRPCMethod(string methodName, XmlRpcRequest request) + { + XmlRpcResponse response; + + XmlRpcMethod method; + if( this.m_rpcHandlers.TryGetValue( methodName, out method ) ) + { + response = method(request); + } + else + { + response = new XmlRpcResponse(); + Hashtable unknownMethodError = new Hashtable(); + unknownMethodError["reason"] = "XmlRequest"; ; + unknownMethodError["message"] = "Unknown Rpc request"; + unknownMethodError["login"] = "false"; + response.Value = unknownMethodError; + } + + return XmlRpcResponseSerializer.Singleton.Serialize(response); + } + + protected virtual string ParseREST(string requestBody, string requestURL, string requestMethod) + { + string[] path; + string pathDelimStr = "/"; + char[] pathDelimiter = pathDelimStr.ToCharArray(); + path = requestURL.Split(pathDelimiter); + + string responseString = ""; + + //path[0] should be empty so we are interested in path[1] + if (path.Length > 1) + { + if ((path[1] != "") && (this.m_restHandlers.ContainsKey(path[1]))) + { + responseString = this.m_restHandlers[path[1]].HandleREST(requestBody, requestURL, requestMethod); + } + } + + return responseString; + } + + protected virtual string ParseLLSDXML(string requestBody) + { + // dummy function for now - IMPLEMENT ME! + return ""; + } + + protected virtual string ParseXMLRPC(string requestBody) + { + string responseString = String.Empty; + + try + { + XmlRpcRequest request = (XmlRpcRequest)(new XmlRpcRequestDeserializer()).Deserialize(requestBody); + + string methodName = request.MethodName; + + responseString = ProcessXMLRPCMethod(methodName, request ); + } + catch (Exception e) + { + Console.WriteLine(e.ToString()); + } + return responseString; + } + + public virtual void HandleRequest(Object stateinfo) + { + HttpListenerContext context = (HttpListenerContext)stateinfo; + + HttpListenerRequest request = context.Request; + HttpListenerResponse response = context.Response; + + response.KeepAlive = false; + response.SendChunked = false; + + System.IO.Stream body = request.InputStream; + System.Text.Encoding encoding = System.Text.Encoding.UTF8; + System.IO.StreamReader reader = new System.IO.StreamReader(body, encoding); + + string requestBody = reader.ReadToEnd(); + body.Close(); + reader.Close(); + + //Console.WriteLine(request.HttpMethod + " " + request.RawUrl + " Http/" + request.ProtocolVersion.ToString() + " content type: " + request.ContentType); + //Console.WriteLine(requestBody); + + string responseString = ""; + switch (request.ContentType) + { + case "text/xml": + // must be XML-RPC, so pass to the XML-RPC parser + + responseString = ParseXMLRPC(requestBody); + responseString = Regex.Replace(responseString, "utf-16", "utf-8"); + + response.AddHeader("Content-type", "text/xml"); + break; + + case "application/xml": + // probably LLSD we hope, otherwise it should be ignored by the parser + responseString = ParseLLSDXML(requestBody); + response.AddHeader("Content-type", "application/xml"); + break; + + case "application/x-www-form-urlencoded": + // a form data POST so send to the REST parser + responseString = ParseREST(requestBody, request.RawUrl, request.HttpMethod); + response.AddHeader("Content-type", "text/html"); + break; + + case null: + // must be REST or invalid crap, so pass to the REST parser + responseString = ParseREST(requestBody, request.RawUrl, request.HttpMethod); + response.AddHeader("Content-type", "text/html"); + break; + + } + + byte[] buffer = System.Text.Encoding.UTF8.GetBytes(responseString); + System.IO.Stream output = response.OutputStream; + response.SendChunked = false; + response.ContentLength64 = buffer.Length; + output.Write(buffer, 0, buffer.Length); + output.Close(); + } + + public void Start() + { + OpenSim.Framework.Console.MainConsole.Instance.WriteLine("BaseHttpServer.cs: Starting up HTTP Server"); + + m_workerThread = new Thread(new ThreadStart(StartHTTP)); + m_workerThread.IsBackground = true; + m_workerThread.Start(); + } + + private void StartHTTP() + { + try + { + OpenSim.Framework.Console.MainConsole.Instance.WriteLine("BaseHttpServer.cs: StartHTTP() - Spawned main thread OK"); + m_httpListener = new HttpListener(); + + m_httpListener.Prefixes.Add("http://+:" + m_port + "/"); + m_httpListener.Start(); + + HttpListenerContext context; + while (true) + { + context = m_httpListener.GetContext(); + ThreadPool.QueueUserWorkItem(new WaitCallback(HandleRequest), context); + } + } + catch (Exception e) + { + OpenSim.Framework.Console.MainConsole.Instance.WriteLine(e.Message); + } + } } } diff --git a/OpenSim.RegionServer/CAPS/IRestHandler.cs b/Servers/IRestHandler.cs similarity index 100% rename from OpenSim.RegionServer/CAPS/IRestHandler.cs rename to Servers/IRestHandler.cs diff --git a/Servers/OpenSim.Servers.csproj b/Servers/OpenSim.Servers.csproj index c983fca377..9710f4710b 100644 --- a/Servers/OpenSim.Servers.csproj +++ b/Servers/OpenSim.Servers.csproj @@ -96,6 +96,8 @@ Code + + diff --git a/Servers/OpenSim.Servers.dll.build b/Servers/OpenSim.Servers.dll.build index 8600ab573a..48e8dec3c8 100644 --- a/Servers/OpenSim.Servers.dll.build +++ b/Servers/OpenSim.Servers.dll.build @@ -12,6 +12,8 @@ + + diff --git a/Servers/XmlRpcMethod.cs b/Servers/XmlRpcMethod.cs new file mode 100644 index 0000000000..22954051e2 --- /dev/null +++ b/Servers/XmlRpcMethod.cs @@ -0,0 +1,7 @@ +using System; +using Nwc.XmlRpc; + +namespace OpenSim.Servers +{ + public delegate XmlRpcResponse XmlRpcMethod( XmlRpcRequest request ); +}