Adds REST interface for setting avatar appearance. cleans up a couple

of places in the REST inventory code.
0.6.0-stable
Dr Scofield 2008-09-18 15:49:52 +00:00
parent 03f246d6fe
commit 978b8af777
5 changed files with 62 additions and 32 deletions

View File

@ -58,6 +58,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
internal static CommunicationsManager Comms = null; internal static CommunicationsManager Comms = null;
internal static IInventoryServices InventoryServices = null; internal static IInventoryServices InventoryServices = null;
internal static IUserService UserServices = null; internal static IUserService UserServices = null;
internal static IAvatarService AvatarServices = null;
internal static AssetCache AssetServices = null; internal static AssetCache AssetServices = null;
internal static string Prefix = null; internal static string Prefix = null;
internal static IConfig Config = null; internal static IConfig Config = null;

View File

@ -57,7 +57,9 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
if (!qPrefix.StartsWith(Rest.UrlPathSeparator)) if (!qPrefix.StartsWith(Rest.UrlPathSeparator))
{ {
qPrefix = Rest.Prefix + Rest.UrlPathSeparator + qPrefix; Rest.Log.InfoFormat("{0} Prefixing domain name ({1})", MsgId, qPrefix);
qPrefix = String.Format("{0}{1}{2}", Rest.Prefix, Rest.UrlPathSeparator, qPrefix);
Rest.Log.InfoFormat("{0} Fully qualified domain name is <{1}>", MsgId, qPrefix);
} }
// Register interface using the fully-qualified prefix // Register interface using the fully-qualified prefix
@ -85,7 +87,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
public void Close() public void Close()
{ {
enabled = false; enabled = false;
Rest.Log.InfoFormat("{0} Asset services closing down", MsgId); Rest.Log.InfoFormat("{0} Asset services ({1}) closing down", MsgId, qPrefix);
} }
// Properties // Properties
@ -110,7 +112,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
AssetRequestData rdata = (AssetRequestData) rparm; AssetRequestData rdata = (AssetRequestData) rparm;
Rest.Log.DebugFormat("{0} REST Asset handler ENTRY", MsgId); Rest.Log.DebugFormat("{0} REST Asset handler ({1}) ENTRY", MsgId, qPrefix);
// 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 // access inventory data, we should find out who
@ -184,15 +186,17 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
#endregion Interface #endregion Interface
/// <summary>
/// The only parameter we recognize is a UUID.If an asset with this identification is
/// found, it's content, base-64 encoded, is returned to the client.
/// </summary>
private void DoGet(AssetRequestData rdata) private void DoGet(AssetRequestData rdata)
{ {
bool istexture = false; bool istexture = false;
Rest.Log.DebugFormat("{0} REST Asset handler, Method = <{1}> ENTRY", MsgId, rdata.method); Rest.Log.DebugFormat("{0} REST Asset handler, Method = <{1}> ENTRY", MsgId, rdata.method);
// The only parameter we accept is an UUID for
// the asset
if (rdata.Parameters.Length == 1) if (rdata.Parameters.Length == 1)
{ {
UUID uuid = new UUID(rdata.Parameters[0]); UUID uuid = new UUID(rdata.Parameters[0]);
@ -226,15 +230,19 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
} }
rdata.Complete(); rdata.Complete();
rdata.Respond("Asset " + rdata.method + ": Normal completion"); rdata.Respond(String.Format("Asset <{0}> : Normal completion", rdata.method));
} }
/// <summary>
/// The only parameter we recognize is a UUID. The enclosed asset data (base-64 encoded)
/// is decoded and stored in the database, identified by the supplied UUID.
/// </summary>
private void DoPut(AssetRequestData rdata) private void DoPut(AssetRequestData rdata)
{ {
Rest.Log.DebugFormat("{0} REST Asset handler, Method = <{1}> ENTRY", MsgId, rdata.method);
// The only parameter we accept is an UUID for Rest.Log.DebugFormat("{0} REST Asset handler, Method = <{1}> ENTRY", MsgId, rdata.method);
// the asset
if (rdata.Parameters.Length == 1) if (rdata.Parameters.Length == 1)
{ {
@ -265,9 +273,14 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
} }
rdata.Complete(); rdata.Complete();
rdata.Respond("Asset " + rdata.method + ": Normal completion"); rdata.Respond(String.Format("Asset <{0}>: Normal completion", rdata.method));
} }
/// <summary>
/// Asset processing has no special data area requirements.
/// </summary>
internal class AssetRequestData : RequestData internal class AssetRequestData : RequestData
{ {
internal AssetRequestData(OSHttpRequest request, OSHttpResponse response, string prefix) internal AssetRequestData(OSHttpRequest request, OSHttpResponse response, string prefix)

View File

@ -123,7 +123,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
/// construction, or during initialization. /// construction, or during initialization.
/// ///
/// I was not able to make this code work within a constructor /// I was not able to make this code work within a constructor
/// so it is islated within this method. /// so it is isolated within this method.
/// </summary> /// </summary>
private void LoadHandlers() private void LoadHandlers()
@ -222,7 +222,8 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
return; return;
} }
Rest.Log.InfoFormat("{0} Plugin will be enabled", MsgId); Rest.Log.InfoFormat("{0} Rest <{1}> plugin will be enabled", MsgId, Name);
Rest.Log.InfoFormat("{0} Configuration parameters read from <{1}>", MsgId, ConfigName);
// These are stored in static variables to make // These are stored in static variables to make
// them easy to reach from anywhere in the assembly. // them easy to reach from anywhere in the assembly.
@ -233,6 +234,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
Rest.UserServices = Rest.Comms.UserService; Rest.UserServices = Rest.Comms.UserService;
Rest.InventoryServices = Rest.Comms.InventoryService; Rest.InventoryServices = Rest.Comms.InventoryService;
Rest.AssetServices = Rest.Comms.AssetCache; Rest.AssetServices = Rest.Comms.AssetCache;
Rest.AvatarServices = Rest.Comms.AvatarService;
Rest.Config = Config; Rest.Config = Config;
Rest.Prefix = Prefix; Rest.Prefix = Prefix;
Rest.GodKey = GodKey; Rest.GodKey = GodKey;
@ -261,15 +263,18 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
// The supplied prefix MUST be absolute // The supplied prefix MUST be absolute
if (Rest.Prefix.Substring(0,1) != Rest.UrlPathSeparator) if (Rest.Prefix.Substring(0,1) != Rest.UrlPathSeparator)
Rest.Prefix = Rest.UrlPathSeparator+Rest.Prefix; {
Rest.Log.WarnFormat("{0} Prefix <{1}> is not absolute and must be", MsgId, Rest.Prefix);
Rest.Log.InfoFormat("{0} Prefix changed to </{1}>", MsgId, Rest.Prefix);
Rest.Prefix = String.Format("{0}{1}", Rest.UrlPathSeparator, Rest.Prefix);
}
// If data dumping is requested, report on the chosen line // If data dumping is requested, report on the chosen line
// length. // length.
if (Rest.DumpAsset) if (Rest.DumpAsset)
{ {
Rest.Log.InfoFormat("{0} Dump {1} bytes per line", MsgId, Rest.Log.InfoFormat("{0} Dump {1} bytes per line", MsgId, Rest.DumpLineSize);
Rest.DumpLineSize);
} }
// Load all of the handlers present in the // Load all of the handlers present in the
@ -361,11 +366,13 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
/// underlying handlers and looks for the best match. It returns /// underlying handlers and looks for the best match. It returns
/// true if a match is found. /// true if a match is found.
/// The matching process could be made arbitrarily complex. /// The matching process could be made arbitrarily complex.
/// Note: The match is case-insensitive.
/// </summary> /// </summary>
public bool Match(OSHttpRequest request, OSHttpResponse response) public bool Match(OSHttpRequest request, OSHttpResponse response)
{ {
string path = request.RawUrl;
string path = request.RawUrl.ToLower();
Rest.Log.DebugFormat("{0} Match ENTRY", MsgId); Rest.Log.DebugFormat("{0} Match ENTRY", MsgId);
@ -483,6 +490,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
/// If there is a stream handler registered that can handle the /// If there is a stream handler registered that can handle the
/// request, then fine. If the request is not matched, do /// request, then fine. If the request is not matched, do
/// nothing. /// nothing.
/// Note: The selection is case-insensitive
/// </summary> /// </summary>
private bool FindStreamHandler(OSHttpRequest request, OSHttpResponse response) private bool FindStreamHandler(OSHttpRequest request, OSHttpResponse response)
@ -490,7 +498,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
RequestData rdata = new RequestData(request, response, String.Empty); RequestData rdata = new RequestData(request, response, String.Empty);
string bestMatch = null; string bestMatch = null;
string path = String.Format("{0}:{1}", rdata.method, rdata.path); string path = String.Format("{0}:{1}", rdata.method, rdata.path).ToLower();
Rest.Log.DebugFormat("{0} Checking for stream handler for <{1}>", MsgId, path); Rest.Log.DebugFormat("{0} Checking for stream handler for <{1}>", MsgId, path);
@ -567,6 +575,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
/// handler was located. The boolean indicates whether or not the request has been /// handler was located. The boolean indicates whether or not the request has been
/// handled, not whether or not the request was successful - that information is in /// handled, not whether or not the request was successful - that information is in
/// the response. /// the response.
/// Note: The selection process is case-insensitive
/// </summary> /// </summary>
internal bool FindPathHandler(OSHttpRequest request, OSHttpResponse response) internal bool FindPathHandler(OSHttpRequest request, OSHttpResponse response)
@ -585,7 +594,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
foreach (string pattern in pathHandlers.Keys) foreach (string pattern in pathHandlers.Keys)
{ {
if (request.RawUrl.StartsWith(pattern)) if (request.RawUrl.ToLower().StartsWith(pattern))
{ {
if (String.IsNullOrEmpty(bestMatch) || pattern.Length > bestMatch.Length) if (String.IsNullOrEmpty(bestMatch) || pattern.Length > bestMatch.Length)
{ {

View File

@ -66,7 +66,9 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
if (!qPrefix.StartsWith(Rest.UrlPathSeparator)) if (!qPrefix.StartsWith(Rest.UrlPathSeparator))
{ {
qPrefix = Rest.Prefix + Rest.UrlPathSeparator + qPrefix; Rest.Log.InfoFormat("{0} Domain is relative, adding absolute prefix", MsgId);
qPrefix = String.Format("{0}{1}{2}", Rest.Prefix, Rest.UrlPathSeparator, qPrefix);
Rest.Log.InfoFormat("{0} Domain is now <{1}>", MsgId, qPrefix);
} }
// Register interface using the absolute URI. // Register interface using the absolute URI.
@ -262,7 +264,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
// TODO // TODO
// If something went wrong in inventory processing the thread could stall here // If something went wrong in inventory processing the thread could stall here
// indefinitely. There should be a watchdog timer to fail the request if the // indefinitely. There should be a watchdog timer to fail the request if the
// response is not recieved in a timely fashion. // response is not received in a timely fashion.
rdata.uuid = rdata.userProfile.ID; rdata.uuid = rdata.userProfile.ID;
@ -330,7 +332,8 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
default : default :
Rest.Log.WarnFormat("{0} Method {1} not supported for {2}", Rest.Log.WarnFormat("{0} Method {1} not supported for {2}",
MsgId, rdata.method, rdata.path); MsgId, rdata.method, rdata.path);
rdata.Fail(Rest.HttpStatusCodeMethodNotAllowed, rdata.method+" not supported"); rdata.Fail(Rest.HttpStatusCodeMethodNotAllowed,
String.Format("{0} not supported", rdata.method));
break; break;
} }
} }
@ -591,8 +594,8 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
if (created) if (created)
{ {
// Must include a location header with a URI that identifies the new resource. // Must include a location header with a URI that identifies the new resource.
rdata.AddHeader(Rest.HttpHeaderLocation,String.Format("http://{0}{1}/{2}", rdata.AddHeader(Rest.HttpHeaderLocation,String.Format("http://{0}{1}:{2}/{3}",
rdata.hostname+":"+rdata.port,rdata.path,newnode)); rdata.hostname, rdata.port,rdata.path,newnode));
rdata.Complete(Rest.HttpStatusCodeCreated); rdata.Complete(Rest.HttpStatusCodeCreated);
} }
else else
@ -607,7 +610,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
} }
} }
rdata.Respond("Inventory " + rdata.method + ": Normal completion"); rdata.Respond(String.Format("Profile {0} : Normal completion", rdata.method));
} }
else else
{ {
@ -872,7 +875,8 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
} }
} }
rdata.Respond("Inventory " + rdata.method + ": Normal completion"); rdata.Respond(String.Format("Profile {0} : Normal completion", rdata.method));
} }
/// <summary> /// <summary>
@ -927,7 +931,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
} }
rdata.Complete(); rdata.Complete();
rdata.Respond("Inventory " + rdata.method + ": Normal completion"); rdata.Respond(String.Format("Profile {0} : Normal completion", rdata.method));
} }
#endregion method-specific processing #endregion method-specific processing
@ -1061,7 +1065,8 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
Rest.Log.DebugFormat("{0} {1}: Resource {2} not found", Rest.Log.DebugFormat("{0} {1}: Resource {2} not found",
MsgId, rdata.method, rdata.path); MsgId, rdata.method, rdata.path);
rdata.Fail(Rest.HttpStatusCodeNotFound, "resource "+rdata.path+" not found"); rdata.Fail(Rest.HttpStatusCodeNotFound,
String.Format("resource {0}:{1} not found", rdata.method, rdata.path));
return null; /* Never reached */ return null; /* Never reached */
} }
@ -1189,9 +1194,9 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
{ {
// Fetching an Item has a special significance. In this // Fetching an Item has a special significance. In this
// case we also want to fetch the associated asset. // case we also want to fetch the associated asset.
// To make it interesting, we'll d this via redirection. // To make it interesting, we'll do this via redirection.
string asseturl = "http://" + rdata.hostname + ":" + rdata.port + string asseturl = String.Format("http://{0}:{1}/{2}{3}{4}", rdata.hostname, rdata.port,
"/admin/assets" + Rest.UrlPathSeparator + ifound.AssetID.ToString(); "admin/assets",Rest.UrlPathSeparator,ifound.AssetID.ToString());
rdata.Redirect(asseturl,Rest.PERMANENT); rdata.Redirect(asseturl,Rest.PERMANENT);
Rest.Log.DebugFormat("{0} Never Reached", MsgId); Rest.Log.DebugFormat("{0} Never Reached", MsgId);
} }

View File

@ -58,7 +58,9 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
if (!qPrefix.StartsWith(Rest.UrlPathSeparator)) if (!qPrefix.StartsWith(Rest.UrlPathSeparator))
{ {
qPrefix = Rest.Prefix + Rest.UrlPathSeparator + qPrefix; Rest.Log.InfoFormat("{0} Domain is relative, adding absolute prefix", MsgId);
qPrefix = String.Format("{0}{1}{2}", Rest.Prefix, Rest.UrlPathSeparator, qPrefix);
Rest.Log.InfoFormat("{0} Domain is now <{1}>", MsgId, qPrefix);
} }
// Load test cases // Load test cases