diff --git a/OpenSim/ApplicationPlugins/Rest/Regions/RegionDetails.cs b/OpenSim/ApplicationPlugins/Rest/Regions/RegionDetails.cs
new file mode 100644
index 0000000000..7fc12671c9
--- /dev/null
+++ b/OpenSim/ApplicationPlugins/Rest/Regions/RegionDetails.cs
@@ -0,0 +1,72 @@
+/*
+* Copyright (c) Contributors, http://opensimulator.org/
+* See CONTRIBUTORS.TXT for a full list of copyright holders.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+* * Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in the
+* documentation and/or other materials provided with the distribution.
+* * Neither the name of the OpenSim Project nor the
+* names of its contributors may be used to endorse or promote products
+* derived from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+*/
+
+using libsecondlife;
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Xml.Serialization;
+using OpenSim.Framework;
+using OpenSim.Region.Environment.Scenes;
+
+namespace OpenSim.ApplicationPlugins.Rest.Regions
+{
+ [XmlRoot(ElementName="region")]
+ public class RegionDetails
+ {
+ public string region_name;
+ public string region_id;
+ public uint region_x;
+ public uint region_y;
+ public string region_owner;
+ public string region_owner_id;
+ public uint region_http_port;
+ public string region_server_uri;
+ public string region_external_hostname;
+
+ public RegionDetails()
+ {
+ }
+
+ public RegionDetails(RegionInfo regInfo)
+ {
+ region_name = regInfo.RegionName;
+ region_id = regInfo.RegionID.ToString();
+ region_x = regInfo.RegionLocX;
+ region_y = regInfo.RegionLocY;
+ region_owner_id = regInfo.MasterAvatarAssignedUUID.ToString();
+ region_http_port = regInfo.HttpPort;
+ region_server_uri = regInfo.ServerURI;
+ region_external_hostname = regInfo.ExternalHostName;
+
+ if (!String.IsNullOrEmpty(regInfo.MasterAvatarFirstName))
+ region_owner = String.Format("{0} {1}", regInfo.MasterAvatarFirstName,
+ regInfo.MasterAvatarLastName);
+ }
+ }
+}
\ No newline at end of file
diff --git a/OpenSim/ApplicationPlugins/Rest/Regions/RestRegionPlugin.cs b/OpenSim/ApplicationPlugins/Rest/Regions/RestRegionPlugin.cs
new file mode 100644
index 0000000000..8a6fb092aa
--- /dev/null
+++ b/OpenSim/ApplicationPlugins/Rest/Regions/RestRegionPlugin.cs
@@ -0,0 +1,162 @@
+/*
+* Copyright (c) Contributors, http://opensimulator.org/
+* See CONTRIBUTORS.TXT for a full list of copyright holders.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+* * Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in the
+* documentation and/or other materials provided with the distribution.
+* * Neither the name of the OpenSim Project nor the
+* names of its contributors may be used to endorse or promote products
+* derived from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+*/
+
+using System;
+using System.Threading;
+using System.Collections;
+using System.Collections.Generic;
+using System.IO;
+using System.Net;
+using System.Reflection;
+using System.Text.RegularExpressions;
+using System.Timers;
+using System.Xml;
+using System.Xml.Serialization;
+using libsecondlife;
+using Mono.Addins;
+using Nwc.XmlRpc;
+using Nini.Config;
+using OpenSim.Framework;
+using OpenSim.Framework.Console;
+using OpenSim.Framework.Servers;
+using OpenSim.Framework.Communications;
+using OpenSim.Region.Environment.Scenes;
+using OpenSim.ApplicationPlugins.Rest;
+
+[assembly : Addin]
+[assembly : AddinDependency("OpenSim", "0.5")]
+
+namespace OpenSim.ApplicationPlugins.Rest.Regions
+{
+
+ [Extension("/OpenSim/Startup")]
+ public class RestRegionPlugin : RestPlugin
+ {
+ private static readonly log4net.ILog _log =
+ log4net.LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+
+ #region overriding properties
+ public override string Name
+ {
+ get { return "REGION"; }
+ }
+
+ public override string ConfigName
+ {
+ get { return "RestRegionPlugin"; }
+ }
+ #endregion overriding properties
+
+ #region overriding methods
+ ///
+ /// This method is called by OpenSimMain immediately after loading the
+ /// plugin and after basic server setup, but before running any server commands.
+ ///
+ ///
+ /// Note that entries MUST be added to the active configuration files before
+ /// the plugin can be enabled.
+ ///
+ public override void Initialise(OpenSimMain openSim)
+ {
+ try
+ {
+ base.Initialise(openSim);
+ if (IsEnabled)
+ m_log.InfoFormat("{0} Rest Plugins Enabled", MsgID);
+ else
+ m_log.WarnFormat("{0} Rest Plugins are disabled", MsgID);
+
+ // add REST method handlers
+ AddRestStreamHandler("GET", "/regions/", GetHandler);
+ }
+ catch (Exception e)
+ {
+ _log.WarnFormat("{0} Initialization failed: {1}", MsgID, e.Message);
+ _log.DebugFormat("{0} Initialization failed: {1}", MsgID, e.ToString());
+ }
+ }
+
+ public override void Close()
+ {
+ }
+ #endregion overriding methods
+
+ #region methods
+ public string GetHandler(string request, string path, string param)
+ {
+ m_log.DebugFormat("{0} GET path {1} param {2}", MsgID, path, param);
+
+ // param empty: regions list
+ if (String.IsNullOrEmpty(param)) return GetHandlerRegions();
+
+ return GetHandlerRegion(param);
+ }
+
+ public string GetHandlerRegions()
+ {
+ StringWriter sw = new StringWriter();
+ XmlTextWriter xw = new XmlTextWriter(sw);
+ xw.Formatting = Formatting.Indented;
+
+ xw.WriteStartElement(String.Empty, "regions", String.Empty);
+ foreach (Scene s in App.SceneManager.Scenes)
+ {
+ xw.WriteStartElement(String.Empty, "uuid", String.Empty);
+ xw.WriteString(s.RegionInfo.RegionID.ToString());
+ xw.WriteEndElement();
+ }
+ xw.WriteEndElement();
+ xw.Close();
+
+ return sw.ToString();
+ }
+
+ public string GetHandlerRegion(string param)
+ {
+ string[] comps = param.Split('/');
+ LLUUID regionID = (LLUUID)comps[0];
+ _log.DebugFormat("{0} region UUID {1}", MsgID, regionID.ToString());
+
+ if (LLUUID.Zero == regionID) throw new Exception("missing region ID");
+
+ Scene scene = null;
+ App.SceneManager.TryGetScene(regionID, out scene);
+
+ XmlSerializer xs = new XmlSerializer(typeof(RegionDetails));
+ StringWriter sw = new StringWriter();
+ XmlTextWriter xw = new XmlTextWriter(sw);
+ xw.Formatting = Formatting.Indented;
+
+ xs.Serialize(xw, new RegionDetails(scene.RegionInfo));
+ xw.Close();
+
+ return sw.ToString();
+ }
+ #endregion methods
+ }
+}
diff --git a/OpenSim/ApplicationPlugins/Rest/RestPlugin.cs b/OpenSim/ApplicationPlugins/Rest/RestPlugin.cs
new file mode 100644
index 0000000000..0e54f4d9a3
--- /dev/null
+++ b/OpenSim/ApplicationPlugins/Rest/RestPlugin.cs
@@ -0,0 +1,246 @@
+/*
+* Copyright (c) Contributors, http://opensimulator.org/
+* See CONTRIBUTORS.TXT for a full list of copyright holders.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+* * Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in the
+* documentation and/or other materials provided with the distribution.
+* * Neither the name of the OpenSim Project nor the
+* names of its contributors may be used to endorse or promote products
+* derived from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+*/
+
+using System;
+using System.Threading;
+using System.Collections;
+using System.Collections.Generic;
+using System.Net;
+using System.Reflection;
+using System.Timers;
+using libsecondlife;
+using Mono.Addins;
+using Nwc.XmlRpc;
+using Nini.Config;
+using OpenSim.Framework;
+using OpenSim.Framework.Console;
+using OpenSim.Framework.Servers;
+using OpenSim.Framework.Communications;
+using OpenSim.Region.Environment.Scenes;
+
+// [assembly : Addin]
+// [assembly : AddinDependency("OpenSim", "0.5")]
+
+namespace OpenSim.ApplicationPlugins.Rest
+{
+
+ // [Extension("/OpenSim/Startup")]
+ public abstract class RestPlugin : IApplicationPlugin
+ {
+ #region properties
+
+ protected static readonly log4net.ILog m_log =
+ log4net.LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+
+ private IConfig _config; // Configuration source: Rest Plugins
+ private IConfig _pluginConfig; // Configuration source: Plugin specific
+ private OpenSimMain _app; // The 'server'
+ private BaseHttpServer _httpd; // The server's RPC interface
+ private string _prefix; // URL prefix below which all REST URLs are living
+
+ private string _godkey;
+ private int _reqk;
+
+ [ThreadStaticAttribute]
+ private static string _threadRequestID = String.Empty;
+
+ ///
+ /// Return an ever increasing request ID for logging
+ ///
+ protected string RequestID
+ {
+ get { return _reqk++.ToString(); }
+ set { _reqk = Convert.ToInt32(value); }
+ }
+
+ ///
+ /// Thread-constant message IDs for logging.
+ ///
+ protected string MsgID
+ {
+ get { return String.Format("[REST-{0}] #{1}", Name, _threadRequestID); }
+ set { _threadRequestID = value; }
+ }
+
+ ///
+ /// Returns true if Rest Plugins are enabled.
+ ///
+ public bool PluginsAreEnabled
+ {
+ get { return null != _config; }
+ }
+
+ ///
+ /// Returns true if specific Rest Plugin is enabled.
+ ///
+ public bool IsEnabled
+ {
+ get
+ {
+ return (null != _pluginConfig) && _pluginConfig.GetBoolean("enabled", false);
+ }
+ }
+
+ ///
+ /// OpenSimMain application
+ ///
+ public OpenSimMain App
+ {
+ get { return _app; }
+ }
+
+ ///
+ /// RPC server
+ ///
+ public BaseHttpServer HttpServer
+ {
+ get { return _httpd; }
+ }
+
+ ///
+ /// URL prefix to use for all REST handlers
+ ///
+ public string Prefix
+ {
+ get { return _prefix; }
+ }
+
+ ///
+ /// Configuration of the plugin
+ ///
+ public IConfig Config
+ {
+ get { return _pluginConfig; }
+ }
+
+ ///
+ /// Name of the plugin
+ ///
+ public abstract string Name { get; }
+
+ ///
+ /// Return the config section name
+ ///
+ public abstract string ConfigName { get; }
+ #endregion properties
+
+
+ #region methods
+ ///
+ /// This method is called by OpenSimMain immediately after loading the
+ /// plugin and after basic server setup, but before running any server commands.
+ ///
+ ///
+ /// Note that entries MUST be added to the active configuration files before
+ /// the plugin can be enabled.
+ ///
+ public virtual void Initialise(OpenSimMain openSim)
+ {
+ RequestID = "0";
+ MsgID = RequestID;
+
+ try
+ {
+ if ((_config = openSim.ConfigSource.Configs["RestPlugins"]) == null) {
+ m_log.WarnFormat("{0} Rest Plugins not configured", MsgID);
+ return;
+ }
+
+ if (!_config.GetBoolean("enabled", false))
+ {
+ m_log.WarnFormat("{0} Rest Plugins are disabled", MsgID);
+ return;
+ }
+
+ _app = openSim;
+ _httpd = openSim.HttpServer;
+
+ // Retrieve GOD key value, if any.
+ _godkey = _config.GetString("god_key", String.Empty);
+ // Retrive prefix if any.
+ _prefix = _config.GetString("prefix", "/admin");
+
+ // Get plugin specific config
+ _pluginConfig = openSim.ConfigSource.Configs[ConfigName];
+
+ m_log.InfoFormat("{0} Rest Plugins Enabled", MsgID);
+ }
+ catch (Exception e)
+ {
+ // we can safely ignore this, as it just means that
+ // the key lookup in Configs failed, which signals to
+ // us that noone is interested in our services...they
+ // don't know what they are missing out on...
+ // NOTE: Under the present OpenSim implementation it is
+ // not possible for the openSim pointer to be null. However
+ // were the implementation to be changed, this could
+ // result in a silent initialization failure. Harmless
+ // except for lack of function and lack of any
+ // diagnostic indication as to why. The same is true if
+ // the HTTP server reference is bad.
+ // We should at least issue a message...
+ m_log.WarnFormat("{0} Initialization failed: {1}", MsgID, e.Message);
+ m_log.DebugFormat("{0} Initialization failed: {1}", MsgID, e.ToString());
+ }
+ }
+
+
+ private List _handlers = new List();
+
+ public void AddRestStreamHandler(string httpMethod, string path, RestMethod method)
+ {
+ if (!path.StartsWith(_prefix))
+ {
+ path = String.Format("{0}{1}", _prefix, path);
+ }
+
+ RestStreamHandler h = new RestStreamHandler(httpMethod, path, method);
+ _httpd.AddStreamHandler(h);
+ _handlers.Add(h);
+
+ m_log.DebugFormat("{0} Added REST handler {1} {2}", MsgID, httpMethod, path);
+ }
+
+
+ public bool VerifyGod(string key)
+ {
+ if (String.IsNullOrEmpty(key)) return false;
+ return key == _godkey;
+ }
+
+ public virtual void Close()
+ {
+ foreach (RestStreamHandler h in _handlers)
+ {
+ _httpd.RemoveStreamHandler(h.HttpMethod, h.Path);
+ }
+ _handlers = null;
+ }
+ #endregion methods
+ }
+}