Update svn properties, formatting cleanup.

This commit is contained in:
Jeff Ames
2008-08-28 14:41:54 +00:00
parent 086284da55
commit 3bf8858727
37 changed files with 505 additions and 709 deletions

View File

@@ -23,7 +23,6 @@
* 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;
@@ -41,11 +40,11 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
public delegate void RestMethodHandler(RequestData rdata);
public delegate RequestData RestMethodAllocator(OSHttpRequest request, OSHttpResponse response, string path);
/// <summary>
/// This interface represents the boundary between the general purpose
/// REST plugin handling, and the functionally specific handlers. The
/// handler knows only to initialize and terminate all such handlers
/// handler knows only to initialize and terminate all such handlers
/// that it finds. Implementing this interface identifies the class as
/// a REST handler implementation.
/// </summary>
@@ -55,7 +54,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
string MsgId { get; }
string RequestId { get; }
void AddPathHandler(RestMethodHandler mh, string path, RestMethodAllocator ma);
void AddStreamHandler(string httpMethod, string path, RestMethod method);

View File

@@ -23,7 +23,6 @@
* 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;
@@ -44,14 +43,14 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
/// <summary>
/// This class represents the current REST request. It
/// encapsulates the request/response state and takes care
/// encapsulates the request/response state and takes care
/// of response generation without exposing the REST handler
/// to the actual mechanisms involved.
///
/// This structure is created on entry to the Handler
/// method and is disposed of upon return. It is part of
/// the plug-in infrastructure, rather than the functionally
/// specific REST handler, and fundamental changes to
/// specific REST handler, and fundamental changes to
/// this should be reflected in the Rest HandlerVersion. The
/// object is instantiated, and may be extended by, any
/// given handler. See the inventory handler for an example
@@ -84,7 +83,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
// Storing information in body will suppress the return of
// statusBody which is only intended to report status on
// requests which do not themselves ordinarily generate
// an informational response. All of this is handled in
// an informational response. All of this is handled in
// Respond().
internal byte[] buffer = null;
@@ -92,8 +91,8 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
internal string bodyType = "text/html";
// The encoding in effect is set to a server default. It may
// subsequently be overridden by a Content header. This
// value is established during construction and is used
// subsequently be overridden by a Content header. This
// value is established during construction and is used
// wherever encoding services are needed.
internal Encoding encoding = Rest.Encoding;
@@ -110,7 +109,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
// The path part of the URI is decomposed. pathNodes
// is an array of every element in the URI. Parameters
// is an array that contains only those nodes that
// is an array that contains only those nodes that
// are not a part of the authority prefix
private string[] pathNodes = null;
@@ -118,7 +117,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
private static readonly string[] EmptyPath = { String.Empty };
// The status code gets set during the course of processing
// and is the HTTP completion code. The status body is
// and is the HTTP completion code. The status body is
// initialized during construction, is appended to during the
// course of execution, and is finalized during Respond
// processing.
@@ -166,7 +165,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
// force selection of a particular authentication model
// (choosing from amongst those supported of course)
//
internal bool authenticated = false;
internal string scheme = null;
internal string realm = Rest.Realm;
@@ -183,7 +182,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
internal string userPass = String.Empty;
// Session related tables. These are only needed if QOP is set to "auth-sess"
// and for now at least, it is not. Session related authentication is of
// and for now at least, it is not. Session related authentication is of
// questionable merit in the context of REST anyway, but it is, arguably, more
// secure.
@@ -199,23 +198,23 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
private static Regex schema = new Regex("^\\s*(?<scheme>\\w+)\\s*.*",
RegexOptions.Compiled | RegexOptions.IgnoreCase);
private static Regex basicParms = new Regex("^\\s*(?:\\w+)\\s+(?<pval>\\S+)\\s*",
RegexOptions.Compiled | RegexOptions.IgnoreCase);
private static Regex digestParm1 = new Regex("\\s*(?<parm>\\w+)\\s*=\\s*\"(?<pval>[^\"]+)\"",
RegexOptions.Compiled | RegexOptions.IgnoreCase);
private static Regex digestParm2 = new Regex("\\s*(?<parm>\\w+)\\s*=\\s*(?<pval>[^\\p{P}\\s]+)",
RegexOptions.Compiled | RegexOptions.IgnoreCase);
private static Regex reuserPass = new Regex("(?<user>[^:]+):(?<pass>[\\S\\s]*)",
RegexOptions.Compiled | RegexOptions.IgnoreCase);
// For efficiency, we create static instances of these objects
private static MD5 md5hash = MD5.Create();
private static StringComparer sc = StringComparer.OrdinalIgnoreCase;
#region properties
@@ -228,15 +227,15 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
}
/// <summary>
/// Return a boolean indication of whether or no an authenticated user is
/// associated with this request. This could be wholly integrated, but
/// Return a boolean indication of whether or no an authenticated user is
/// associated with this request. This could be wholly integrated, but
/// that would make authentication mandatory.
/// </summary>
internal bool IsAuthenticated
{
get
{
{
if (Rest.Authenticate)
{
if (!authenticated)
@@ -258,31 +257,31 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
internal string[] PathNodes
{
get
{
{
return pathNodes;
}
}
/// <summary>
/// Access to all non-prefix 'nodes' in the supplied URI as an
/// array of strings. These identify a specific resource that
/// array of strings. These identify a specific resource that
/// is managed by the authority (the prefix).
/// </summary>
internal string[] Parameters
{
get
{
{
return parameters;
}
}
#endregion properties
#region constructors
// Constructor
internal RequestData(OSHttpRequest p_request, OSHttpResponse p_response, string p_qprefix)
{
@@ -315,7 +314,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
/// Realm, domain, etc.
///
/// This method checks to see if the current request is already
/// authenticated for this domain. If it is, then it returns
/// authenticated for this domain. If it is, then it returns
/// true. If it is not, then it issues a challenge to the client
/// and responds negatively to the request.
///
@@ -339,7 +338,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
Rest.Log.DebugFormat("{0} Challenge reason: No authorization data", MsgId);
DoChallenge();
}
// So, we have authentication data, now we have to check to
// see what we got and whether or not it is valid for the
// current domain. To do this we need to interpret the data
@@ -438,7 +437,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
// The service provider can force a particular scheme by
// assigning a value to scheme.
// Basic authentication is pretty simple.
// Just specify the realm in question.
@@ -468,8 +467,8 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
sbuilder.Append(" ");
// Specify the effective realm. This should
// never be null if we are uthenticating, as it is required for all
// authentication schemes. It defines, in conjunction with the
// never be null if we are uthenticating, as it is required for all
// authentication schemes. It defines, in conjunction with the
// absolute URI information, the domain to which the authentication
// applies. It is an arbitrary string. I *believe* this allows an
// authentication to apply to disjoint resources within the same
@@ -485,7 +484,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
}
// Share our nonce. This is *uniquely* generated each time a 401 is
// returned. We do not generate a very sophisticated nonce at the
// returned. We do not generate a very sophisticated nonce at the
// moment (it's simply a base64 encoded UUID).
if (nonce != null)
@@ -532,7 +531,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
sbuilder.Append(Rest.CS_COMMA);
}
// Theoretically QOP is optional, but it is required by a compliant
// Theoretically QOP is optional, but it is required by a compliant
// with current versions of the scheme. In fact IE requires that QOP
// be specified and will refuse to authenticate otherwise.
@@ -555,7 +554,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
}
// We don't know the userid that will be used
// so we cannot make any authentication domain
// so we cannot make any authentication domain
// assumptions. So the prefix will determine
// this.
@@ -582,7 +581,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
/// understand this and also expect it to be the first one
/// offered. So we do.
/// OpenSim also needs this, as it is the only scheme that allows
/// authentication using the hashed passwords stored in the
/// authentication using the hashed passwords stored in the
/// user database.
/// </summary>
@@ -599,7 +598,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
foreach (Match m in matches)
{
authparms.Add("response",m.Groups["pval"].Value);
Rest.Log.DebugFormat("{0} Parameter matched : {1} = {2}",
Rest.Log.DebugFormat("{0} Parameter matched : {1} = {2}",
MsgId, "response", m.Groups["pval"].Value);
}
@@ -623,7 +622,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
}
/// <summary>
/// This method provides validation in support of the BASIC
/// This method provides validation in support of the BASIC
/// authentication method. This is not normaly expected to be
/// used, but is included for completeness (and because I tried
/// it first).
@@ -664,12 +663,12 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
string last;
// Distinguish the parts, if necessary
if ((x=user.IndexOf(Rest.C_SPACE)) != -1)
{
first = user.Substring(0,x);
last = user.Substring(x+1);
}
}
else
{
first = user;
@@ -685,9 +684,9 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
HA1 = HashToString(pass);
HA1 = HashToString(String.Format("{0}:{1}",HA1,udata.PasswordSalt));
return (0 == sc.Compare(HA1, udata.PasswordHash));
}
#endregion authentication_basic
@@ -712,7 +711,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
foreach (Match m in matches)
{
authparms.Add(m.Groups["parm"].Value,m.Groups["pval"].Value);
Rest.Log.DebugFormat("{0} String Parameter matched : {1} = {2}",
Rest.Log.DebugFormat("{0} String Parameter matched : {1} = {2}",
MsgId, m.Groups["parm"].Value,m.Groups["pval"].Value);
}
@@ -723,7 +722,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
foreach (Match m in matches)
{
authparms.Add(m.Groups["parm"].Value,m.Groups["pval"].Value);
Rest.Log.DebugFormat("{0} Tokenized Parameter matched : {1} = {2}",
Rest.Log.DebugFormat("{0} Tokenized Parameter matched : {1} = {2}",
MsgId, m.Groups["parm"].Value,m.Groups["pval"].Value);
}
@@ -760,7 +759,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
if (!authparms.TryGetValue("nonce", out nonce) || nonce == null)
{
Rest.Log.WarnFormat("{0} Authentication failed: nonce missing", MsgId);
Rest.Log.WarnFormat("{0} Authentication failed: nonce missing", MsgId);
break;
}
@@ -771,7 +770,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
{
if (temp != opaque)
{
Rest.Log.WarnFormat("{0} Authentication failed: bad opaque value", MsgId);
Rest.Log.WarnFormat("{0} Authentication failed: bad opaque value", MsgId);
break;
}
}
@@ -783,7 +782,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
{
if (temp != algorithm)
{
Rest.Log.WarnFormat("{0} Authentication failed: bad algorithm value", MsgId);
Rest.Log.WarnFormat("{0} Authentication failed: bad algorithm value", MsgId);
break;
}
}
@@ -800,7 +799,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
if (!authparms.ContainsKey("cnonce"))
{
Rest.Log.WarnFormat("{0} Authentication failed: cnonce missing", MsgId);
Rest.Log.WarnFormat("{0} Authentication failed: cnonce missing", MsgId);
break;
}
@@ -808,7 +807,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
if (!authparms.TryGetValue("nc", out nck) || nck == null)
{
Rest.Log.WarnFormat("{0} Authentication failed: cnonce counter missing", MsgId);
Rest.Log.WarnFormat("{0} Authentication failed: cnonce counter missing", MsgId);
break;
}
@@ -820,7 +819,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
if (Rest.Hex2Int(ncl) >= Rest.Hex2Int(nck))
{
Rest.Log.WarnFormat("{0} Authentication failed: bad cnonce counter", MsgId);
Rest.Log.WarnFormat("{0} Authentication failed: bad cnonce counter", MsgId);
break;
}
cntable[nonce] = nck;
@@ -840,12 +839,12 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
// these MUST NOT be present.
if (authparms.ContainsKey("cnonce"))
{
Rest.Log.WarnFormat("{0} Authentication failed: invalid cnonce", MsgId);
Rest.Log.WarnFormat("{0} Authentication failed: invalid cnonce", MsgId);
break;
}
if (authparms.ContainsKey("nc"))
{
Rest.Log.WarnFormat("{0} Authentication failed: invalid cnonce counter[2]", MsgId);
Rest.Log.WarnFormat("{0} Authentication failed: invalid cnonce counter[2]", MsgId);
break;
}
}
@@ -854,7 +853,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
authenticated = ValidateDigest(userName, nonce, cnonce, nck, authPrefix, response);
}
}
while (false);
}
@@ -864,10 +863,10 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
/// <summary>
/// This mechanism is used by the digest authentication mechanism
/// to return the user's password. In fact, because the OpenSim
/// user's passwords are already hashed, and the HTTP mechanism
/// does not supply an open password, the hashed passwords cannot
/// user's passwords are already hashed, and the HTTP mechanism
/// does not supply an open password, the hashed passwords cannot
/// be used unless the client has used the same salting mechanism
/// to has the password before using it in the authentication
/// to has the password before using it in the authentication
/// algorithn. This is not inconceivable...
/// </summary>
@@ -879,12 +878,12 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
string last;
// Distinguish the parts, if necessary
if ((x=user.IndexOf(Rest.C_SPACE)) != -1)
{
first = user.Substring(0,x);
last = user.Substring(x+1);
}
}
else
{
first = user;
@@ -955,7 +954,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
HA2 = HashToString(patt);
// Generate Digest
if (qop != String.Empty)
{
patt = String.Format("{0}:{1}:{2}:{3}:{4}:{5}", HA1, nonce, nck, cnonce, qop, HA2);
@@ -1011,7 +1010,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
}
/// <summary>
/// Indicate a functionally-dependent conclusion to the
/// Indicate a functionally-dependent conclusion to the
/// request. See Rest.cs for a list of possible values.
/// </summary>
@@ -1023,7 +1022,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
/// <summary>
/// Indicate that a request should be redirected, using
/// the HTTP completion codes. Permanent and temporary
/// redirections may be indicated. The supplied URL is
/// redirections may be indicated. The supplied URL is
/// the new location of the resource.
/// </summary>
@@ -1057,7 +1056,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
}
/// <summary>
/// For the more adventurous. This failure also includes a
/// For the more adventurous. This failure also includes a
/// specified entity to be appended to the code-related
/// status string.
/// </summary>
@@ -1101,12 +1100,12 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
fail = true;
// Respond to the client's request, tag the response (for the
// Respond to the client's request, tag the response (for the
// benefit of trace) to indicate the reason.
Respond(String.Format("Failure response: ({0}) : {1}",
code, Rest.HttpStatusDesc[code]));
// Finally initialize and the throw a RestException. All of the
// handler's infrastructure knows that this is a "normal"
// completion from a code point-of-view.
@@ -1129,7 +1128,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
Fail(Rest.HttpStatusCodeNotImplemented, "request rejected (not implemented)");
}
// This MUST be called by an agent handler before it returns
// This MUST be called by an agent handler before it returns
// control to Handle, otherwise the request will be ignored.
// This is called implciitly for the REST stream handlers and
// is harmless if it is called twice.
@@ -1222,7 +1221,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
}
// Set the status code & description. If nothing has been stored,
// Set the status code & description. If nothing has been stored,
// we consider that a success.
if (statusCode == 0)
@@ -1236,7 +1235,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
// For a redirect we need to set the relocation header accordingly
if (response.StatusCode == (int) Rest.HttpStatusCodeTemporaryRedirect ||
if (response.StatusCode == (int) Rest.HttpStatusCodeTemporaryRedirect ||
response.StatusCode == (int) Rest.HttpStatusCodePermanentRedirect)
{
Rest.Log.DebugFormat("{0} Re-direct location is {1}", MsgId, redirectLocation);
@@ -1252,7 +1251,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
// We've left the setting of handled' until the
// last minute because the header settings included
// above are pretty harmless. But everything from
// here on down probably leaves the response
// here on down probably leaves the response
// element unusable by anyone else.
handled = true;
@@ -1267,7 +1266,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
if (buffer != null && buffer.Length != 0)
{
Rest.Log.DebugFormat("{0} Entity buffer, length = {1} : <{2}>",
Rest.Log.DebugFormat("{0} Entity buffer, length = {1} : <{2}>",
MsgId, buffer.Length, encoding.GetString(buffer));
response.OutputStream.Write(buffer, 0, buffer.Length);
}
@@ -1295,11 +1294,11 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
{
if (Rest.DEBUG)
{
Rest.Log.DebugFormat("{0} Adding header: <{1}: {2}>",
Rest.Log.DebugFormat("{0} Adding header: <{1}: {2}>",
MsgId, hdr, data);
if (response.Headers.Get(hdr) != null)
{
Rest.Log.DebugFormat("{0} Multipe {1} headers will be generated>",
Rest.Log.DebugFormat("{0} Multipe {1} headers will be generated>",
MsgId, hdr);
}
}
@@ -1313,7 +1312,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
Rest.Log.DebugFormat("{0} Removing header: <{1}>", MsgId, hdr);
if (response.Headers.Get(hdr) == null)
{
Rest.Log.DebugFormat("{0} No such header existed",
Rest.Log.DebugFormat("{0} No such header existed",
MsgId, hdr);
}
}
@@ -1326,7 +1325,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
{
for (int i=0;i<response.Headers.Count;i++)
{
Rest.Log.DebugFormat("{0} Header[{1}] : {2}", MsgId, i,
Rest.Log.DebugFormat("{0} Header[{1}] : {2}", MsgId, i,
response.Headers.Get(i));
}
}
@@ -1404,7 +1403,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
// If we succeeded in getting a path, perform any
// additional pre-processing required.
if (path != null)
if (path != null)
{
if (Rest.ExtendedEscape)
{
@@ -1442,14 +1441,14 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
{
parameters = new string[0];
}
// Generate a debug list of the decoded parameters
if (Rest.DEBUG && prfxlen < path.Length-1)
{
Rest.Log.DebugFormat("{0} URI: Parameters: {1}", MsgId, path.Substring(prfxlen));
for (int i = 0; i < parameters.Length; i++)
{
{
Rest.Log.DebugFormat("{0} Parameter[{1}]: {2}", MsgId, i, parameters[i]);
}
}

View File

@@ -23,7 +23,7 @@
* 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;
@@ -38,11 +38,9 @@ using Nini.Config;
namespace OpenSim.ApplicationPlugins.Rest.Inventory
{
public class Rest
{
internal static readonly log4net.ILog Log =
internal static readonly log4net.ILog Log =
log4net.LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
internal static bool DEBUG = Log.IsDebugEnabled;
@@ -77,7 +75,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
/// HTTP requires that status information be generated for PUT
/// and POST opertaions. This is in support of that. The
/// operation verb gets substituted into the first string,
/// and the completion code is inserted into the tail. The
/// and the completion code is inserted into the tail. The
/// strings are put here to encourage consistency.
/// </summary>
@@ -88,7 +86,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
static Rest()
{
HttpStatusDesc = new Dictionary<int,string>();
HttpStatusDesc = new Dictionary<int,string>();
if (HttpStatusCodeArray.Length != HttpStatusDescArray.Length)
{
Log.ErrorFormat("{0} HTTP Status Code and Description arrays do not match");
@@ -143,7 +141,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
/// supported by all servers. See Respond
/// to see how these are handled.
/// </summary>
// REST AGENT 1.0 interpretations
public const string GET = "get"; // information retrieval - server state unchanged
public const string HEAD = "head"; // same as get except only the headers are returned.
@@ -175,7 +173,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
public static readonly char C_PERIOD = '.';
public static readonly char C_COMMA = ',';
public static readonly char C_DQUOTE = '"';
public static readonly string CS_SPACE = " ";
public static readonly string CS_SLASH = "/";
public static readonly string CS_PATHSEP = "/";
@@ -184,7 +182,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
public static readonly string CS_PERIOD = ".";
public static readonly string CS_COMMA = ",";
public static readonly string CS_DQUOTE = "\"";
public static readonly char[] CA_SPACE = { C_SPACE };
public static readonly char[] CA_SLASH = { C_SLASH };
public static readonly char[] CA_PATHSEP = { C_PATHSEP };
@@ -392,7 +390,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
public const string AS_DIGEST = "Digest";
/// Supported Digest algorithms
public const string Digest_MD5 = "MD5"; // assumedd efault if omitted
public const string Digest_MD5Sess = "MD5-sess";
@@ -440,7 +438,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
int val = 0;
int sum = 0;
string tmp = null;
if (hex != null)
{
tmp = hex.ToLower();
@@ -455,7 +453,6 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
}
return sum;
}
// Nonce management
@@ -465,17 +462,15 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
return StringToBase64(CreationDate + Guid.NewGuid().ToString());
}
// Dump he specified data stream;
// Dump the specified data stream
public static void Dump(byte[] data)
{
char[] buffer = new char[Rest.DumpLineSize];
int cc = 0;
for (int i = 0; i < data.Length; i++)
{
if (i % Rest.DumpLineSize == 0) Console.Write("\n{0}: ",i.ToString("d8"));
if (i % 4 == 0) Console.Write(" ");
@@ -494,7 +489,6 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
Console.Write(" |"+(new String(buffer))+"|");
cc = 0;
}
}
// Finish off any incomplete line
@@ -504,33 +498,29 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
for (int i = cc ; i < Rest.DumpLineSize; i++)
{
if (i % 4 == 0) Console.Write(" ");
Console.Write(" ");
Console.Write(" ");
buffer[i % Rest.DumpLineSize] = ' ';
}
Console.WriteLine(" |"+(new String(buffer))+"|");
}
else
{
Console.Write("\n");
Console.Write("\n");
}
}
}
// Local exception type
public class RestException : Exception
{
internal int statusCode;
internal string statusDesc;
internal string httpmethod;
internal string httppath;
public RestException(string msg) : base(msg)
{
public RestException(string msg) : base(msg)
{
}
}
}

View File

@@ -23,7 +23,6 @@
* 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;
@@ -40,10 +39,8 @@ using OpenSim.Framework.Communications.Cache;
namespace OpenSim.ApplicationPlugins.Rest.Inventory
{
public class RestAssetServices : IRest
{
private bool enabled = false;
private string qPrefix = "assets";
@@ -52,7 +49,6 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
public RestAssetServices()
{
Rest.Log.InfoFormat("{0} Asset services initializing", MsgId);
Rest.Log.InfoFormat("{0} Using REST Implementation Version {1}", MsgId, Rest.Version);
@@ -73,7 +69,6 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
enabled = true;
Rest.Log.InfoFormat("{0} Asset services initialization complete", MsgId);
}
// Post-construction, pre-enabled initialization opportunity
@@ -84,7 +79,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
}
// Called by the plug-in to halt REST processing. Local processing is
// disabled, and control blocks until all current processing has
// disabled, and control blocks until all current processing has
// completed. No new processing will be started
public void Close()
@@ -111,14 +106,13 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
private void DoAsset(RequestData rparm)
{
if (!enabled) return;
AssetRequestData rdata = (AssetRequestData) rparm;
Rest.Log.DebugFormat("{0} REST Asset handler ENTRY", MsgId);
// Now that we know this is a serious attempt to
// Now that we know this is a serious attempt to
// access inventory data, we should find out who
// is asking, and make sure they are authorized
// to do so. We need to validate the caller's
@@ -129,9 +123,9 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
// With the present HTTP server we can't use the
// builtin authentication mechanisms because they
// would be enforced for all in-bound requests.
// Instead we look at the headers ourselves and
// Instead we look at the headers ourselves and
// handle authentication directly.
try
{
if (!rdata.IsAuthenticated)
@@ -144,13 +138,13 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
if (e.statusCode == Rest.HttpStatusCodeNotAuthorized)
{
Rest.Log.WarnFormat("{0} User not authenticated", MsgId);
Rest.Log.DebugFormat("{0} Authorization header: {1}", MsgId,
Rest.Log.DebugFormat("{0} Authorization header: {1}", MsgId,
rdata.request.Headers.Get("Authorization"));
}
else
{
Rest.Log.ErrorFormat("{0} User authentication failed", MsgId);
Rest.Log.DebugFormat("{0} Authorization header: {1}", MsgId,
Rest.Log.DebugFormat("{0} Authorization header: {1}", MsgId,
rdata.request.Headers.Get("Authorization"));
}
throw (e);
@@ -173,7 +167,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
case "post" :
case "delete" :
default :
Rest.Log.WarnFormat("{0} Asset: Method not supported: {1}",
Rest.Log.WarnFormat("{0} Asset: Method not supported: {1}",
MsgId, rdata.method);
rdata.Fail(Rest.HttpStatusCodeBadRequest,String.Format("method <{0}> not supported", rdata.method));
break;
@@ -186,14 +180,12 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
}
Rest.Log.DebugFormat("{0} REST Asset handler EXIT", MsgId);
}
#endregion Interface
private void DoGet(AssetRequestData rdata)
{
bool istexture = false;
Rest.Log.DebugFormat("{0} REST Asset handler, Method = <{1}> ENTRY", MsgId, rdata.method);
@@ -203,13 +195,11 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
if (rdata.Parameters.Length == 1)
{
LLUUID uuid = new LLUUID(rdata.Parameters[0]);
AssetBase asset = Rest.AssetServices.GetAsset(uuid, istexture);
if (asset != null)
{
Rest.Log.DebugFormat("{0} Asset located <{1}>", MsgId, rdata.Parameters[0]);
rdata.initXmlWriter();
@@ -237,7 +227,6 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
rdata.Complete();
rdata.Respond("Asset " + rdata.method + ": Normal completion");
}
private void DoPut(AssetRequestData rdata)
@@ -255,7 +244,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
if (!xml.ReadToFollowing("Asset"))
{
Rest.Log.DebugFormat("{0} Invalid request data: <{1}>", MsgId, rdata.path);
rdata.Fail(Rest.HttpStatusCodeBadRequest,"invalid request data");
rdata.Fail(Rest.HttpStatusCodeBadRequest,"invalid request data");
}
AssetBase asset = new AssetBase();
@@ -272,12 +261,11 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
else
{
Rest.Log.DebugFormat("{0} Invalid parameters: <{1}>", MsgId, rdata.path);
rdata.Fail(Rest.HttpStatusCodeNotFound, "invalid parameters");
rdata.Fail(Rest.HttpStatusCodeNotFound, "invalid parameters");
}
rdata.Complete();
rdata.Respond("Asset " + rdata.method + ": Normal completion");
}
internal class AssetRequestData : RequestData
@@ -287,6 +275,5 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
{
}
}
}
}

View File

@@ -23,7 +23,6 @@
* 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;
@@ -35,7 +34,6 @@ using OpenSim.ApplicationPlugins.Rest;
namespace OpenSim.ApplicationPlugins.Rest.Inventory
{
/// <remarks>
/// The class signature reveals the roles that RestHandler plays.
///
@@ -74,10 +72,10 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
/// <summary>
/// This static initializer scans the ASSEMBLY for classes that
/// export the IRest interface and builds a list of them. These
/// are later activated by the handler. To add a new handler it
/// are later activated by the handler. To add a new handler it
/// is only necessary to create a new services class that implements
/// the IRest interface, and recompile the handler. This gives
/// all of the build-time flexibility of a modular approach
/// all of the build-time flexibility of a modular approach
/// while not introducing yet-another module loader. Note that
/// multiple assembles can still be built, each with its own set
/// of handlers. Examples of services classes are RestInventoryServices
@@ -86,13 +84,12 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
static RestHandler()
{
Module[] mods = Assembly.GetExecutingAssembly().GetModules();
foreach (Module m in mods)
{
Type[] types = m.GetTypes();
foreach (Type t in types)
foreach (Type t in types)
{
try
{
@@ -108,7 +105,6 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
}
}
}
}
#endregion local static state
@@ -117,13 +113,13 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
/// <summary>
/// This routine loads all of the handlers discovered during
/// instance initialization.
/// instance initialization.
/// A table of all loaded and successfully constructed handlers
/// is built, and this table is then used by the constructor to
/// initialize each of the handlers in turn.
/// NOTE: The loading process does not automatically imply that
/// the handler has registered any kind of an interface, that
/// may be (optionally) done by the handler either during
/// the handler has registered any kind of an interface, that
/// may be (optionally) done by the handler either during
/// construction, or during initialization.
///
/// I was not able to make this code work within a constructor
@@ -136,7 +132,6 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
{
if (!handlersLoaded)
{
ConstructorInfo ci;
Object ht;
@@ -167,8 +162,8 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
// Name is used to differentiate the message header.
public override string Name
{
public override string Name
{
get { return "HANDLER"; }
}
@@ -181,7 +176,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
// We have to rename these because we want
// to be able to share the values with other
// classes in our assembly and the base
// classes in our assembly and the base
// names are protected.
public string MsgId
@@ -211,7 +206,6 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
{
try
{
// This plugin will only be enabled if the broader
// REST plugin mechanism is enabled.
@@ -222,7 +216,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
// IsEnabled is implemented by the base class and
// reflects an overall RestPlugin status
if (!IsEnabled)
if (!IsEnabled)
{
Rest.Log.WarnFormat("{0} Plugins are disabled", MsgId);
return;
@@ -278,15 +272,15 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
Rest.DumpLineSize);
}
// Load all of the handlers present in the
// Load all of the handlers present in the
// assembly
// In principle, as we're an application plug-in,
// most of what needs to be done could be done using
// static resources, however the Open Sim plug-in
// model makes this an instance, so that's what we
// static resources, however the Open Sim plug-in
// model makes this an instance, so that's what we
// need to be.
// There is only one Communications manager per
// There is only one Communications manager per
// server, and by inference, only one each of the
// user, asset, and inventory servers. So we can cache
// those using a static initializer.
@@ -329,13 +323,12 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
{
Rest.Log.ErrorFormat("{0} Plugin initialization has failed: {1}", MsgId, e.Message);
}
}
/// <summary>
/// In the interests of efficiency, and because we cannot determine whether
/// or not this instance will actually be harvested, we clobber the only
/// anchoring reference to the working state for this plug-in. What the
/// anchoring reference to the working state for this plug-in. What the
/// call to close does is irrelevant to this class beyond knowing that it
/// can nullify the reference when it returns.
/// To make sure everything is copacetic we make sure the primary interface
@@ -344,7 +337,6 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
public override void Close()
{
Rest.Log.InfoFormat("{0} Plugin is terminating", MsgId);
try
@@ -352,12 +344,11 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
RemoveAgentHandler(Rest.Name, this);
}
catch (KeyNotFoundException){}
foreach (IRest handler in handlers)
{
handler.Close();
}
}
#endregion overriding methods
@@ -383,7 +374,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
foreach (string key in pathHandlers.Keys)
{
Rest.Log.DebugFormat("{0} Match testing {1} against agent prefix <{2}>", MsgId, path, key);
// Note that Match will not necessarily find the handler that will
// actually be used - it does no test for the "closest" fit. It
// simply reflects that at least one possible handler exists.
@@ -393,7 +384,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
Rest.Log.DebugFormat("{0} Matched prefix <{1}>", MsgId, key);
// This apparently odd evaluation is needed to prevent a match
// on anything other than a URI token boundary. Otherwise we
// on anything other than a URI token boundary. Otherwise we
// may match on URL's that were not intended for this handler.
return ( path.Length == key.Length ||
@@ -406,9 +397,8 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
foreach (string key in streamHandlers.Keys)
{
Rest.Log.DebugFormat("{0} Match testing {1} against stream prefix <{2}>", MsgId, path, key);
// Note that Match will not necessarily find the handler that will
// actually be used - it does no test for the "closest" fit. It
// simply reflects that at least one possible handler exists.
@@ -418,7 +408,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
Rest.Log.DebugFormat("{0} Matched prefix <{1}>", MsgId, key);
// This apparently odd evaluation is needed to prevent a match
// on anything other than a URI token boundary. Otherwise we
// on anything other than a URI token boundary. Otherwise we
// may match on URL's that were not intended for this handler.
return ( path.Length == key.Length ||
@@ -426,7 +416,6 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
}
}
}
catch (Exception e)
{
@@ -460,7 +449,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
for (int i = 0; i < request.Headers.Count; i++)
{
Rest.Log.DebugFormat("{0} Header [{1}] : <{2}> = <{3}>",
Rest.Log.DebugFormat("{0} Header [{1}] : <{2}> = <{3}>",
MsgId, i, request.Headers.GetKey(i), request.Headers.Get(i));
}
Rest.Log.DebugFormat("{0} URI: {1}", MsgId, request.RawUrl);
@@ -486,7 +475,6 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
Rest.Log.DebugFormat("{0} EXIT", MsgId);
return handled;
}
#endregion interface methods
@@ -534,7 +522,6 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
}
return rdata.handled;
}
/// <summary>
@@ -547,13 +534,12 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
public void AddStreamHandler(string httpMethod, string path, RestMethod method)
{
if (!IsEnabled)
{
return;
}
if (!path.StartsWith(Rest.Prefix))
if (!path.StartsWith(Rest.Prefix))
{
path = String.Format("{0}{1}", Rest.Prefix, path);
}
@@ -571,7 +557,6 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
{
Rest.Log.WarnFormat("{0} Ignoring duplicate handler for {1}", MsgId, path);
}
}
/// <summary>
@@ -586,10 +571,9 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
internal bool FindPathHandler(OSHttpRequest request, OSHttpResponse response)
{
RequestData rdata = null;
string bestMatch = null;
if (!IsEnabled)
{
return false;
@@ -612,7 +596,6 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
if (!String.IsNullOrEmpty(bestMatch))
{
rdata = pathAllocators[bestMatch](request, response, bestMatch);
Rest.Log.DebugFormat("{0} Path based REST handler matched with <{1}>", MsgId, bestMatch);
@@ -621,7 +604,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
{
pathHandlers[bestMatch](rdata);
}
// A plugin generated error indicates a request-related error
// that has been handled by the plugin.
@@ -629,11 +612,9 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
{
Rest.Log.WarnFormat("{0} Request failed: {1}", MsgId, r.Message);
}
}
return (rdata == null) ? false : rdata.handled;
}
/// <summary>
@@ -643,7 +624,6 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
public void AddPathHandler(RestMethodHandler mh, string path, RestMethodAllocator ra)
{
if (!IsEnabled)
{
return;
@@ -665,8 +645,6 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
pathHandlers.Add(path, mh);
pathAllocators.Add(path, ra);
}
}
}

View File

@@ -23,7 +23,6 @@
* 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;
@@ -41,10 +40,8 @@ using OpenSim.Framework.Communications.Cache;
namespace OpenSim.ApplicationPlugins.Rest.Inventory.Tests
{
public class Remote : ITest
{
private static readonly int PARM_TESTID = 0;
private static readonly int PARM_COMMAND = 1;
@@ -72,7 +69,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory.Tests
}
// Called by the plug-in to halt REST processing. Local processing is
// disabled, and control blocks until all current processing has
// disabled, and control blocks until all current processing has
// completed. No new processing will be started
public void Close()
@@ -91,11 +88,10 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory.Tests
// Remote Handler
// Key information of interest here is the Parameters array, each
// entry represents an element of the URI, with element zero being
// the
// the
public void Execute(RequestData rdata)
{
if (!enabled) return;
// If we can't relate to what's there, leave it for others.
@@ -125,7 +121,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory.Tests
{
DoHelp(rdata);
}
}
}
private void DoHelp(RequestData rdata)
{
@@ -138,7 +134,6 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory.Tests
{
if (rdata.Parameters.Length >= 6)
{
string[] names = rdata.Parameters[PARM_MOVE_AVATAR].Split(Rest.CA_SPACE);
ScenePresence avatar = null;
Scene scene = null;
@@ -149,7 +144,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory.Tests
String.Format("invalid avatar name: <{0}>",rdata.Parameters[PARM_MOVE_AVATAR]));
}
Rest.Log.WarnFormat("{0} '{1}' command received for {2} {3}",
Rest.Log.WarnFormat("{0} '{1}' command received for {2} {3}",
MsgId, rdata.Parameters[0], names[0], names[1]);
// The first parameter should be an avatar name, look for the
@@ -171,8 +166,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory.Tests
if (avatar != null)
{
Rest.Log.DebugFormat("{0} Move : Avatar {1} located in region {2}",
Rest.Log.DebugFormat("{0} Move : Avatar {1} located in region {2}",
MsgId, rdata.Parameters[PARM_MOVE_AVATAR], scene.RegionInfo.RegionName);
try
@@ -185,16 +179,16 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory.Tests
}
catch (Exception e)
{
rdata.Fail(Rest.HttpStatusCodeBadRequest,
String.Format("invalid parameters: {0}", e.Message));
rdata.Fail(Rest.HttpStatusCodeBadRequest,
String.Format("invalid parameters: {0}", e.Message));
}
}
else
{
rdata.Fail(Rest.HttpStatusCodeBadRequest,
rdata.Fail(Rest.HttpStatusCodeBadRequest,
String.Format("avatar {0} not present", rdata.Parameters[PARM_MOVE_AVATAR]));
}
}
rdata.Complete();
rdata.Respond("OK");
@@ -205,7 +199,6 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory.Tests
Rest.Log.WarnFormat("{0} Move: No movement information provided", MsgId);
rdata.Fail(Rest.HttpStatusCodeBadRequest, "no movement information provided");
}
}
private static readonly string Help =
@@ -220,6 +213,5 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory.Tests
+ "</body>"
+ "</html>"
;
}
}