aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/ApplicationPlugins/Rest/Inventory
diff options
context:
space:
mode:
authorJeff Ames2008-08-18 00:39:10 +0000
committerJeff Ames2008-08-18 00:39:10 +0000
commit6ef9d4da901a346c232458317cca6268da888e2e (patch)
treedd1d935b10f34f261839da9f9879c02322e8ede7 /OpenSim/ApplicationPlugins/Rest/Inventory
parentUpdate svn properties, minor formatting cleanup. (diff)
downloadopensim-SC-6ef9d4da901a346c232458317cca6268da888e2e.zip
opensim-SC-6ef9d4da901a346c232458317cca6268da888e2e.tar.gz
opensim-SC-6ef9d4da901a346c232458317cca6268da888e2e.tar.bz2
opensim-SC-6ef9d4da901a346c232458317cca6268da888e2e.tar.xz
Formatting cleanup.
Diffstat (limited to 'OpenSim/ApplicationPlugins/Rest/Inventory')
-rw-r--r--OpenSim/ApplicationPlugins/Rest/Inventory/RequestData.cs119
-rw-r--r--OpenSim/ApplicationPlugins/Rest/Inventory/Rest.cs24
-rw-r--r--OpenSim/ApplicationPlugins/Rest/Inventory/RestAssetServices.cs36
-rw-r--r--OpenSim/ApplicationPlugins/Rest/Inventory/RestHandler.cs65
-rw-r--r--OpenSim/ApplicationPlugins/Rest/Inventory/RestInventoryServices.cs300
5 files changed, 221 insertions, 323 deletions
diff --git a/OpenSim/ApplicationPlugins/Rest/Inventory/RequestData.cs b/OpenSim/ApplicationPlugins/Rest/Inventory/RequestData.cs
index 94aecbd..6fc3ea3 100644
--- a/OpenSim/ApplicationPlugins/Rest/Inventory/RequestData.cs
+++ b/OpenSim/ApplicationPlugins/Rest/Inventory/RequestData.cs
@@ -23,7 +23,6 @@
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 *
27 */ 26 */
28 27
29using System; 28using System;
@@ -44,14 +43,14 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
44 43
45 /// <summary> 44 /// <summary>
46 /// This class represents the current REST request. It 45 /// This class represents the current REST request. It
47 /// encapsulates the request/response state and takes care 46 /// encapsulates the request/response state and takes care
48 /// of response generation without exposing the REST handler 47 /// of response generation without exposing the REST handler
49 /// to the actual mechanisms involved. 48 /// to the actual mechanisms involved.
50 /// 49 ///
51 /// This structure is created on entry to the Handler 50 /// This structure is created on entry to the Handler
52 /// method and is disposed of upon return. It is part of 51 /// method and is disposed of upon return. It is part of
53 /// the plug-in infrastructure, rather than the functionally 52 /// the plug-in infrastructure, rather than the functionally
54 /// specific REST handler, and fundamental changes to 53 /// specific REST handler, and fundamental changes to
55 /// this should be reflected in the Rest HandlerVersion. The 54 /// this should be reflected in the Rest HandlerVersion. The
56 /// object is instantiated, and may be extended by, any 55 /// object is instantiated, and may be extended by, any
57 /// given handler. See the inventory handler for an example 56 /// given handler. See the inventory handler for an example
@@ -100,7 +99,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
100 internal bool chunked = false; 99 internal bool chunked = false;
101 100
102 // Authentication related state 101 // Authentication related state
103 102
104 internal bool authenticated = false; 103 internal bool authenticated = false;
105 // internal string scheme = Rest.AS_DIGEST; 104 // internal string scheme = Rest.AS_DIGEST;
106 // internal string scheme = Rest.AS_BASIC; 105 // internal string scheme = Rest.AS_BASIC;
@@ -132,7 +131,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
132 private static readonly string[] EmptyPath = { String.Empty }; 131 private static readonly string[] EmptyPath = { String.Empty };
133 132
134 // Session related tables. These are only needed if QOP is set to "auth-sess" 133 // Session related tables. These are only needed if QOP is set to "auth-sess"
135 // and for now at least, it is not. Session related authentication is of 134 // and for now at least, it is not. Session related authentication is of
136 // questionable merit in the context of REST anyway, but it is, arguably, more 135 // questionable merit in the context of REST anyway, but it is, arguably, more
137 // secure. 136 // secure.
138 137
@@ -148,27 +147,27 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
148 147
149 private static Regex schema = new Regex("^\\s*(?<scheme>\\w+)\\s*.*", 148 private static Regex schema = new Regex("^\\s*(?<scheme>\\w+)\\s*.*",
150 RegexOptions.Compiled | RegexOptions.IgnoreCase); 149 RegexOptions.Compiled | RegexOptions.IgnoreCase);
151 150
152 private static Regex basicParms = new Regex("^\\s*(?:\\w+)\\s+(?<pval>\\S+)\\s*", 151 private static Regex basicParms = new Regex("^\\s*(?:\\w+)\\s+(?<pval>\\S+)\\s*",
153 RegexOptions.Compiled | RegexOptions.IgnoreCase); 152 RegexOptions.Compiled | RegexOptions.IgnoreCase);
154 153
155 private static Regex digestParm1 = new Regex("\\s*(?<parm>\\w+)\\s*=\\s*\"(?<pval>[^\"]+)\"", 154 private static Regex digestParm1 = new Regex("\\s*(?<parm>\\w+)\\s*=\\s*\"(?<pval>[^\"]+)\"",
156 RegexOptions.Compiled | RegexOptions.IgnoreCase); 155 RegexOptions.Compiled | RegexOptions.IgnoreCase);
157 156
158 private static Regex digestParm2 = new Regex("\\s*(?<parm>\\w+)\\s*=\\s*(?<pval>[^\\p{P}\\s]+)", 157 private static Regex digestParm2 = new Regex("\\s*(?<parm>\\w+)\\s*=\\s*(?<pval>[^\\p{P}\\s]+)",
159 RegexOptions.Compiled | RegexOptions.IgnoreCase); 158 RegexOptions.Compiled | RegexOptions.IgnoreCase);
160 159
161 private static Regex reuserPass = new Regex("(?<user>[^:]+):(?<pass>[\\S\\s]*)", 160 private static Regex reuserPass = new Regex("(?<user>[^:]+):(?<pass>[\\S\\s]*)",
162 RegexOptions.Compiled | RegexOptions.IgnoreCase); 161 RegexOptions.Compiled | RegexOptions.IgnoreCase);
163 162
164 // For efficiency, we create static instances of these objects 163 // For efficiency, we create static instances of these objects
165 164
166 private static MD5 md5hash = MD5.Create(); 165 private static MD5 md5hash = MD5.Create();
167 166
168 private static StringComparer sc = StringComparer.OrdinalIgnoreCase; 167 private static StringComparer sc = StringComparer.OrdinalIgnoreCase;
169 168
170 // Constructor 169 // Constructor
171 170
172 internal RequestData(OSHttpRequest p_request, OSHttpResponse p_response, string p_qprefix) 171 internal RequestData(OSHttpRequest p_request, OSHttpResponse p_response, string p_qprefix)
173 { 172 {
174 173
@@ -203,7 +202,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
203 internal bool IsAuthenticated 202 internal bool IsAuthenticated
204 { 203 {
205 get 204 get
206 { 205 {
207 if (Rest.Authenticate) 206 if (Rest.Authenticate)
208 { 207 {
209 if (!authenticated) 208 if (!authenticated)
@@ -223,7 +222,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
223 /// Realm, domain, etc. 222 /// Realm, domain, etc.
224 /// 223 ///
225 /// This method checks to see if the current request is already 224 /// This method checks to see if the current request is already
226 /// authenticated for this domain. If it is, then it returns 225 /// authenticated for this domain. If it is, then it returns
227 /// true. If it is not, then it issues a challenge to the client 226 /// true. If it is not, then it issues a challenge to the client
228 /// and responds negatively to the request. 227 /// and responds negatively to the request.
229 /// </summary> 228 /// </summary>
@@ -243,7 +242,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
243 Rest.Log.DebugFormat("{0} Challenge reason: No authorization data", MsgId); 242 Rest.Log.DebugFormat("{0} Challenge reason: No authorization data", MsgId);
244 DoChallenge(); 243 DoChallenge();
245 } 244 }
246 245
247 // So, we have authentication data, now we have to check to 246 // So, we have authentication data, now we have to check to
248 // see what we got and whether or not it is valid for the 247 // see what we got and whether or not it is valid for the
249 // current domain. To do this we need to interpret the data 248 // current domain. To do this we need to interpret the data
@@ -327,7 +326,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
327 foreach (Match m in matches) 326 foreach (Match m in matches)
328 { 327 {
329 authparms.Add("response",m.Groups["pval"].Value); 328 authparms.Add("response",m.Groups["pval"].Value);
330 Rest.Log.DebugFormat("{0} Parameter matched : {1} = {2}", 329 Rest.Log.DebugFormat("{0} Parameter matched : {1} = {2}",
331 MsgId, "response", m.Groups["pval"].Value); 330 MsgId, "response", m.Groups["pval"].Value);
332 } 331 }
333 332
@@ -369,7 +368,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
369 foreach (Match m in matches) 368 foreach (Match m in matches)
370 { 369 {
371 authparms.Add(m.Groups["parm"].Value,m.Groups["pval"].Value); 370 authparms.Add(m.Groups["parm"].Value,m.Groups["pval"].Value);
372 Rest.Log.DebugFormat("{0} String Parameter matched : {1} = {2}", 371 Rest.Log.DebugFormat("{0} String Parameter matched : {1} = {2}",
373 MsgId, m.Groups["parm"].Value,m.Groups["pval"].Value); 372 MsgId, m.Groups["parm"].Value,m.Groups["pval"].Value);
374 } 373 }
375 374
@@ -380,7 +379,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
380 foreach (Match m in matches) 379 foreach (Match m in matches)
381 { 380 {
382 authparms.Add(m.Groups["parm"].Value,m.Groups["pval"].Value); 381 authparms.Add(m.Groups["parm"].Value,m.Groups["pval"].Value);
383 Rest.Log.DebugFormat("{0} Tokenized Parameter matched : {1} = {2}", 382 Rest.Log.DebugFormat("{0} Tokenized Parameter matched : {1} = {2}",
384 MsgId, m.Groups["parm"].Value,m.Groups["pval"].Value); 383 MsgId, m.Groups["parm"].Value,m.Groups["pval"].Value);
385 } 384 }
386 385
@@ -417,7 +416,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
417 416
418 if (!authparms.TryGetValue("nonce", out nonce) || nonce == null) 417 if (!authparms.TryGetValue("nonce", out nonce) || nonce == null)
419 { 418 {
420 Rest.Log.WarnFormat("{0} Authentication failed: nonce missing", MsgId); 419 Rest.Log.WarnFormat("{0} Authentication failed: nonce missing", MsgId);
421 break; 420 break;
422 } 421 }
423 422
@@ -428,7 +427,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
428 { 427 {
429 if (temp != opaque) 428 if (temp != opaque)
430 { 429 {
431 Rest.Log.WarnFormat("{0} Authentication failed: bad opaque value", MsgId); 430 Rest.Log.WarnFormat("{0} Authentication failed: bad opaque value", MsgId);
432 break; 431 break;
433 } 432 }
434 } 433 }
@@ -440,7 +439,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
440 { 439 {
441 if (temp != algorithm) 440 if (temp != algorithm)
442 { 441 {
443 Rest.Log.WarnFormat("{0} Authentication failed: bad algorithm value", MsgId); 442 Rest.Log.WarnFormat("{0} Authentication failed: bad algorithm value", MsgId);
444 break; 443 break;
445 } 444 }
446 } 445 }
@@ -457,7 +456,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
457 456
458 if (!authparms.ContainsKey("cnonce")) 457 if (!authparms.ContainsKey("cnonce"))
459 { 458 {
460 Rest.Log.WarnFormat("{0} Authentication failed: cnonce missing", MsgId); 459 Rest.Log.WarnFormat("{0} Authentication failed: cnonce missing", MsgId);
461 break; 460 break;
462 } 461 }
463 462
@@ -465,7 +464,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
465 464
466 if (!authparms.TryGetValue("nc", out nck) || nck == null) 465 if (!authparms.TryGetValue("nc", out nck) || nck == null)
467 { 466 {
468 Rest.Log.WarnFormat("{0} Authentication failed: cnonce counter missing", MsgId); 467 Rest.Log.WarnFormat("{0} Authentication failed: cnonce counter missing", MsgId);
469 break; 468 break;
470 } 469 }
471 470
@@ -477,7 +476,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
477 476
478 if (Rest.Hex2Int(ncl) >= Rest.Hex2Int(nck)) 477 if (Rest.Hex2Int(ncl) >= Rest.Hex2Int(nck))
479 { 478 {
480 Rest.Log.WarnFormat("{0} Authentication failed: bad cnonce counter", MsgId); 479 Rest.Log.WarnFormat("{0} Authentication failed: bad cnonce counter", MsgId);
481 break; 480 break;
482 } 481 }
483 cntable[nonce] = nck; 482 cntable[nonce] = nck;
@@ -497,12 +496,12 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
497 // these MUST NOT be present. 496 // these MUST NOT be present.
498 if (authparms.ContainsKey("cnonce")) 497 if (authparms.ContainsKey("cnonce"))
499 { 498 {
500 Rest.Log.WarnFormat("{0} Authentication failed: invalid cnonce", MsgId); 499 Rest.Log.WarnFormat("{0} Authentication failed: invalid cnonce", MsgId);
501 break; 500 break;
502 } 501 }
503 if (authparms.ContainsKey("nc")) 502 if (authparms.ContainsKey("nc"))
504 { 503 {
505 Rest.Log.WarnFormat("{0} Authentication failed: invalid cnonce counter[2]", MsgId); 504 Rest.Log.WarnFormat("{0} Authentication failed: invalid cnonce counter[2]", MsgId);
506 break; 505 break;
507 } 506 }
508 } 507 }
@@ -511,7 +510,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
511 510
512 authenticated = ValidateDigest(userName, nonce, cnonce, nck, authPrefix, response); 511 authenticated = ValidateDigest(userName, nonce, cnonce, nck, authPrefix, response);
513 512
514 } 513 }
515 while (false); 514 while (false);
516 515
517 } 516 }
@@ -608,7 +607,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
608 } 607 }
609 608
610 // We don;t know the userid that will be used 609 // We don;t know the userid that will be used
611 // so we cannot make any authentication domain 610 // so we cannot make any authentication domain
612 // assumptions. So the prefix will determine 611 // assumptions. So the prefix will determine
613 // this. 612 // this.
614 613
@@ -624,7 +623,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
624 } 623 }
625 624
626 /// <summary> 625 /// <summary>
627 /// This method provides validation in support of the BASIC 626 /// This method provides validation in support of the BASIC
628 /// authentication method. This is not normaly expected to be 627 /// authentication method. This is not normaly expected to be
629 /// used, but is included for completeness (and because I tried 628 /// used, but is included for completeness (and because I tried
630 /// it first). 629 /// it first).
@@ -650,11 +649,11 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
650 /// <summary> 649 /// <summary>
651 /// This mechanism is used by the digest authetnication mechanism 650 /// This mechanism is used by the digest authetnication mechanism
652 /// to return the user's password. In fact, because the OpenSim 651 /// to return the user's password. In fact, because the OpenSim
653 /// user's passwords are already hashed, and the HTTP mechanism 652 /// user's passwords are already hashed, and the HTTP mechanism
654 /// does not supply an open password, the hashed passwords cannot 653 /// does not supply an open password, the hashed passwords cannot
655 /// be used unless the cliemt has used the same salting mechanism 654 /// be used unless the cliemt has used the same salting mechanism
656 /// to has the password before using it in the authentication 655 /// to has the password before using it in the authentication
657 /// algorithn. This is not inconceivable... 656 /// algorithm. This is not inconceivable...
658 /// </summary> 657 /// </summary>
659 658
660 private string getPassword(string user) 659 private string getPassword(string user)
@@ -665,12 +664,12 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
665 string last; 664 string last;
666 665
667 // Distinguish the parts, if necessary 666 // Distinguish the parts, if necessary
668 667
669 if ((x=user.IndexOf(Rest.C_SPACE)) != -1) 668 if ((x=user.IndexOf(Rest.C_SPACE)) != -1)
670 { 669 {
671 first = user.Substring(0,x); 670 first = user.Substring(0,x);
672 last = user.Substring(x+1); 671 last = user.Substring(x+1);
673 } 672 }
674 else 673 else
675 { 674 {
676 first = user; 675 first = user;
@@ -712,12 +711,12 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
712 string last; 711 string last;
713 712
714 // Distinguish the parts, if necessary 713 // Distinguish the parts, if necessary
715 714
716 if ((x=user.IndexOf(Rest.C_SPACE)) != -1) 715 if ((x=user.IndexOf(Rest.C_SPACE)) != -1)
717 { 716 {
718 first = user.Substring(0,x); 717 first = user.Substring(0,x);
719 last = user.Substring(x+1); 718 last = user.Substring(x+1);
720 } 719 }
721 else 720 else
722 { 721 {
723 first = user; 722 first = user;
@@ -733,9 +732,9 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
733 732
734 HA1 = HashToString(pass); 733 HA1 = HashToString(pass);
735 HA1 = HashToString(String.Format("{0}:{1}",HA1,udata.PasswordSalt)); 734 HA1 = HashToString(String.Format("{0}:{1}",HA1,udata.PasswordSalt));
736 735
737 return (0 == sc.Compare(HA1, udata.PasswordHash)); 736 return (0 == sc.Compare(HA1, udata.PasswordHash));
738 737
739 } 738 }
740 739
741 // Validate the request-digest 740 // Validate the request-digest
@@ -784,7 +783,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
784 HA2 = HashToString(patt); 783 HA2 = HashToString(patt);
785 784
786 // Generate Digest 785 // Generate Digest
787 786
788 if (qop != String.Empty) 787 if (qop != String.Empty)
789 { 788 {
790 patt = String.Format("{0}:{1}:{2}:{3}:{4}:{5}", HA1, nonce, nck, cnonce, qop, HA2); 789 patt = String.Format("{0}:{1}:{2}:{3}:{4}:{5}", HA1, nonce, nck, cnonce, qop, HA2);
@@ -856,7 +855,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
856 Fail(code, message, true); 855 Fail(code, message, true);
857 } 856 }
858 857
859 // More adventurous. This failure also includes a 858 // More adventurous. This failure also includes a
860 // specified entity. 859 // specified entity.
861 860
862 internal void Fail(int code, string message, string data) 861 internal void Fail(int code, string message, string data)
@@ -899,7 +898,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
899 fail = true; 898 fail = true;
900 899
901 Respond("Failure response"); 900 Respond("Failure response");
902 901
903 RestException re = new RestException(message+" <"+code+">"); 902 RestException re = new RestException(message+" <"+code+">");
904 903
905 re.statusCode = code; 904 re.statusCode = code;
@@ -918,7 +917,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
918 Fail(Rest.HttpStatusCodeNotImplemented, Rest.HttpStatusDescNotImplemented); 917 Fail(Rest.HttpStatusCodeNotImplemented, Rest.HttpStatusDescNotImplemented);
919 } 918 }
920 919
921 // This MUST be called by an agent handler before it returns 920 // This MUST be called by an agent handler before it returns
922 // control to Handle, otherwise the request will be ignored. 921 // control to Handle, otherwise the request will be ignored.
923 // This is called implciitly for the REST stream handlers and 922 // This is called implciitly for the REST stream handlers and
924 // is harmless if it is called twice. 923 // is harmless if it is called twice.
@@ -962,7 +961,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
962 Rest.Log.DebugFormat("{0} XML Response handler extension EXIT", MsgId); 961 Rest.Log.DebugFormat("{0} XML Response handler extension EXIT", MsgId);
963 } 962 }
964 963
965 // If buffer != null, then we assume that 964 // If buffer != null, then we assume that
966 // this has already been done some other 965 // this has already been done some other
967 // way. For example, transfer encoding might 966 // way. For example, transfer encoding might
968 // have been done. 967 // have been done.
@@ -997,7 +996,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
997 996
998 } 997 }
999 998
1000 // Set the status code & description. If nothing has been stored, 999 // Set the status code & description. If nothing has been stored,
1001 // we consider that a success. 1000 // we consider that a success.
1002 1001
1003 if (statusCode == 0) 1002 if (statusCode == 0)
@@ -1011,7 +1010,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
1011 1010
1012 // For a redirect we need to set the relocation header accordingly 1011 // For a redirect we need to set the relocation header accordingly
1013 1012
1014 if (response.StatusCode == (int) Rest.HttpStatusCodeTemporaryRedirect || 1013 if (response.StatusCode == (int) Rest.HttpStatusCodeTemporaryRedirect ||
1015 response.StatusCode == (int) Rest.HttpStatusCodePermanentRedirect) 1014 response.StatusCode == (int) Rest.HttpStatusCodePermanentRedirect)
1016 { 1015 {
1017 Rest.Log.DebugFormat("{0} Re-direct location is {1}", MsgId, redirectLocation); 1016 Rest.Log.DebugFormat("{0} Re-direct location is {1}", MsgId, redirectLocation);
@@ -1031,7 +1030,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
1031 // We've left the setting of handled' until the 1030 // We've left the setting of handled' until the
1032 // last minute because the header settings included 1031 // last minute because the header settings included
1033 // above are pretty harmless. But everything from 1032 // above are pretty harmless. But everything from
1034 // here on down probably leaves the response 1033 // here on down probably leaves the response
1035 // element unusable by anyone else. 1034 // element unusable by anyone else.
1036 1035
1037 handled = true; 1036 handled = true;
@@ -1046,7 +1045,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
1046 1045
1047 if (buffer != null && buffer.Length != 0) 1046 if (buffer != null && buffer.Length != 0)
1048 { 1047 {
1049 Rest.Log.DebugFormat("{0} Entity buffer, length = {1} : <{2}>", 1048 Rest.Log.DebugFormat("{0} Entity buffer, length = {1} : <{2}>",
1050 MsgId, buffer.Length, encoding.GetString(buffer)); 1049 MsgId, buffer.Length, encoding.GetString(buffer));
1051 response.OutputStream.Write(buffer, 0, buffer.Length); 1050 response.OutputStream.Write(buffer, 0, buffer.Length);
1052 } 1051 }
@@ -1066,17 +1065,17 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
1066 1065
1067 // Add a header to the table. We need to allow 1066 // Add a header to the table. We need to allow
1068 // multiple instances of many of the headers. 1067 // multiple instances of many of the headers.
1069 // If the 1068 // If the
1070 1069
1071 internal void AddHeader(string hdr, string data) 1070 internal void AddHeader(string hdr, string data)
1072 { 1071 {
1073 if (Rest.DEBUG) 1072 if (Rest.DEBUG)
1074 { 1073 {
1075 Rest.Log.DebugFormat("{0} Adding header: <{1}: {2}>", 1074 Rest.Log.DebugFormat("{0} Adding header: <{1}: {2}>",
1076 MsgId, hdr, data); 1075 MsgId, hdr, data);
1077 if (response.Headers.Get(hdr) != null) 1076 if (response.Headers.Get(hdr) != null)
1078 { 1077 {
1079 Rest.Log.DebugFormat("{0} Multipe {1} headers will be generated>", 1078 Rest.Log.DebugFormat("{0} Multipe {1} headers will be generated>",
1080 MsgId, hdr); 1079 MsgId, hdr);
1081 } 1080 }
1082 } 1081 }
@@ -1093,7 +1092,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
1093 Rest.Log.DebugFormat("{0} Removing header: <{1}>", MsgId, hdr); 1092 Rest.Log.DebugFormat("{0} Removing header: <{1}>", MsgId, hdr);
1094 if (response.Headers.Get(hdr) == null) 1093 if (response.Headers.Get(hdr) == null)
1095 { 1094 {
1096 Rest.Log.DebugFormat("{0} No such header existed", 1095 Rest.Log.DebugFormat("{0} No such header existed",
1097 MsgId, hdr); 1096 MsgId, hdr);
1098 } 1097 }
1099 } 1098 }
@@ -1110,7 +1109,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
1110 { 1109 {
1111 for (int i=0;i<response.Headers.Count;i++) 1110 for (int i=0;i<response.Headers.Count;i++)
1112 { 1111 {
1113 Rest.Log.DebugFormat("{0} Header[{1}] : {2}", MsgId, i, 1112 Rest.Log.DebugFormat("{0} Header[{1}] : {2}", MsgId, i,
1114 response.Headers.Get(i)); 1113 response.Headers.Get(i));
1115 } 1114 }
1116 } 1115 }
@@ -1144,7 +1143,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
1144 // If we succeeded in getting a path, perform any 1143 // If we succeeded in getting a path, perform any
1145 // additional pre-processing required. 1144 // additional pre-processing required.
1146 1145
1147 if (path != null) 1146 if (path != null)
1148 { 1147 {
1149 if (Rest.ExtendedEscape) 1148 if (Rest.ExtendedEscape)
1150 { 1149 {
@@ -1182,14 +1181,14 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
1182 { 1181 {
1183 parameters = new string[0]; 1182 parameters = new string[0];
1184 } 1183 }
1185 1184
1186 // Generate a debug list of the decoded parameters 1185 // Generate a debug list of the decoded parameters
1187 1186
1188 if (Rest.DEBUG && prfxlen < path.Length-1) 1187 if (Rest.DEBUG && prfxlen < path.Length-1)
1189 { 1188 {
1190 Rest.Log.DebugFormat("{0} URI: Parameters: {1}", MsgId, path.Substring(prfxlen)); 1189 Rest.Log.DebugFormat("{0} URI: Parameters: {1}", MsgId, path.Substring(prfxlen));
1191 for (int i = 0; i < parameters.Length; i++) 1190 for (int i = 0; i < parameters.Length; i++)
1192 { 1191 {
1193 Rest.Log.DebugFormat("{0} Parameter[{1}]: {2}", MsgId, i, parameters[i]); 1192 Rest.Log.DebugFormat("{0} Parameter[{1}]: {2}", MsgId, i, parameters[i]);
1194 } 1193 }
1195 } 1194 }
@@ -1197,11 +1196,11 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
1197 return parameters.Length; 1196 return parameters.Length;
1198 1197
1199 } 1198 }
1200 1199
1201 internal string[] PathNodes 1200 internal string[] PathNodes
1202 { 1201 {
1203 get 1202 get
1204 { 1203 {
1205 if (pathNodes == null) 1204 if (pathNodes == null)
1206 { 1205 {
1207 initUrl(); 1206 initUrl();
@@ -1209,10 +1208,10 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
1209 return pathNodes; 1208 return pathNodes;
1210 } 1209 }
1211 } 1210 }
1212 1211
1213 internal string BuildUrl(int first, int last) 1212 internal string BuildUrl(int first, int last)
1214 { 1213 {
1215 1214
1216 if (pathNodes == null) 1215 if (pathNodes == null)
1217 { 1216 {
1218 initUrl(); 1217 initUrl();
diff --git a/OpenSim/ApplicationPlugins/Rest/Inventory/Rest.cs b/OpenSim/ApplicationPlugins/Rest/Inventory/Rest.cs
index 439bbb4..2bb91a4 100644
--- a/OpenSim/ApplicationPlugins/Rest/Inventory/Rest.cs
+++ b/OpenSim/ApplicationPlugins/Rest/Inventory/Rest.cs
@@ -23,7 +23,7 @@
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 * 26 *
27 */ 27 */
28 28
29using System; 29using System;
@@ -42,7 +42,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
42 public class Rest 42 public class Rest
43 { 43 {
44 44
45 internal static readonly log4net.ILog Log = 45 internal static readonly log4net.ILog Log =
46 log4net.LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 46 log4net.LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
47 47
48 internal static bool DEBUG = Log.IsDebugEnabled; 48 internal static bool DEBUG = Log.IsDebugEnabled;
@@ -106,7 +106,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
106 /// supported by all servers. See Respond 106 /// supported by all servers. See Respond
107 /// to see how these are handled. 107 /// to see how these are handled.
108 /// </summary> 108 /// </summary>
109 109
110 // REST AGENT 1.0 interpretations 110 // REST AGENT 1.0 interpretations
111 public const string GET = "get"; // information retrieval - server state unchanged 111 public const string GET = "get"; // information retrieval - server state unchanged
112 public const string HEAD = "head"; // same as get except only the headers are returned. 112 public const string HEAD = "head"; // same as get except only the headers are returned.
@@ -138,7 +138,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
138 public static readonly char C_PERIOD = '.'; 138 public static readonly char C_PERIOD = '.';
139 public static readonly char C_COMMA = ','; 139 public static readonly char C_COMMA = ',';
140 public static readonly char C_DQUOTE = '"'; 140 public static readonly char C_DQUOTE = '"';
141 141
142 public static readonly string CS_SPACE = " "; 142 public static readonly string CS_SPACE = " ";
143 public static readonly string CS_SLASH = "/"; 143 public static readonly string CS_SLASH = "/";
144 public static readonly string CS_PATHSEP = "/"; 144 public static readonly string CS_PATHSEP = "/";
@@ -147,7 +147,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
147 public static readonly string CS_PERIOD = "."; 147 public static readonly string CS_PERIOD = ".";
148 public static readonly string CS_COMMA = ","; 148 public static readonly string CS_COMMA = ",";
149 public static readonly string CS_DQUOTE = "\""; 149 public static readonly string CS_DQUOTE = "\"";
150 150
151 public static readonly char[] CA_SPACE = { C_SPACE }; 151 public static readonly char[] CA_SPACE = { C_SPACE };
152 public static readonly char[] CA_SLASH = { C_SLASH }; 152 public static readonly char[] CA_SLASH = { C_SLASH };
153 public static readonly char[] CA_PATHSEP = { C_PATHSEP }; 153 public static readonly char[] CA_PATHSEP = { C_PATHSEP };
@@ -311,7 +311,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
311 public const string AS_DIGEST = "Digest"; 311 public const string AS_DIGEST = "Digest";
312 312
313 /// Supported Digest algorithms 313 /// Supported Digest algorithms
314 314
315 public const string Digest_MD5 = "MD5"; // assumedd efault if omitted 315 public const string Digest_MD5 = "MD5"; // assumedd efault if omitted
316 public const string Digest_MD5Sess = "MD5-sess"; 316 public const string Digest_MD5Sess = "MD5-sess";
317 317
@@ -359,7 +359,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
359 int val = 0; 359 int val = 0;
360 int sum = 0; 360 int sum = 0;
361 string tmp = null; 361 string tmp = null;
362 362
363 if (hex != null) 363 if (hex != null)
364 { 364 {
365 tmp = hex.ToLower(); 365 tmp = hex.ToLower();
@@ -446,20 +446,20 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
446 { 446 {
447 if (i % 4 == 0) Console.Write(" "); 447 if (i % 4 == 0) Console.Write(" ");
448 // if (i%16 == 0) Console.Write(" "); 448 // if (i%16 == 0) Console.Write(" ");
449 Console.Write(" "); 449 Console.Write(" ");
450 buffer[i % Rest.DumpLineSize] = ' '; 450 buffer[i % Rest.DumpLineSize] = ' ';
451 } 451 }
452 Console.WriteLine(" |"+(new String(buffer))+"|"); 452 Console.WriteLine(" |"+(new String(buffer))+"|");
453 } 453 }
454 else 454 else
455 { 455 {
456 Console.Write("\n"); 456 Console.Write("\n");
457 } 457 }
458 458
459 } 459 }
460 460
461 } 461 }
462 462
463 // Local exception type 463 // Local exception type
464 464
465 public class RestException : Exception 465 public class RestException : Exception
@@ -470,8 +470,8 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
470 internal string httpmethod; 470 internal string httpmethod;
471 internal string httppath; 471 internal string httppath;
472 472
473 public RestException(string msg) : base(msg) 473 public RestException(string msg) : base(msg)
474 { 474 {
475 } 475 }
476 } 476 }
477 477
diff --git a/OpenSim/ApplicationPlugins/Rest/Inventory/RestAssetServices.cs b/OpenSim/ApplicationPlugins/Rest/Inventory/RestAssetServices.cs
index b4eb7db..95b0ee3 100644
--- a/OpenSim/ApplicationPlugins/Rest/Inventory/RestAssetServices.cs
+++ b/OpenSim/ApplicationPlugins/Rest/Inventory/RestAssetServices.cs
@@ -23,7 +23,6 @@
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 *
27 */ 26 */
28 27
29using libsecondlife; 28using libsecondlife;
@@ -40,10 +39,8 @@ using OpenSim.Framework.Communications.Cache;
40 39
41namespace OpenSim.ApplicationPlugins.Rest.Inventory 40namespace OpenSim.ApplicationPlugins.Rest.Inventory
42{ 41{
43
44 public class RestAssetServices : IRest 42 public class RestAssetServices : IRest
45 { 43 {
46
47 private bool enabled = false; 44 private bool enabled = false;
48 private string qPrefix = "assets"; 45 private string qPrefix = "assets";
49 46
@@ -52,7 +49,6 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
52 49
53 public RestAssetServices() 50 public RestAssetServices()
54 { 51 {
55
56 Rest.Log.InfoFormat("{0} Asset services initializing", MsgId); 52 Rest.Log.InfoFormat("{0} Asset services initializing", MsgId);
57 Rest.Log.InfoFormat("{0} Using REST Implementation Version {1}", MsgId, Rest.Version); 53 Rest.Log.InfoFormat("{0} Using REST Implementation Version {1}", MsgId, Rest.Version);
58 54
@@ -73,7 +69,6 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
73 enabled = true; 69 enabled = true;
74 70
75 Rest.Log.InfoFormat("{0} Asset services initialization complete", MsgId); 71 Rest.Log.InfoFormat("{0} Asset services initialization complete", MsgId);
76
77 } 72 }
78 73
79 // Post-construction, pre-enabled initialization opportunity 74 // Post-construction, pre-enabled initialization opportunity
@@ -84,7 +79,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
84 } 79 }
85 80
86 // Called by the plug-in to halt REST processing. Local processing is 81 // Called by the plug-in to halt REST processing. Local processing is
87 // disabled, and control blocks until all current processing has 82 // disabled, and control blocks until all current processing has
88 // completed. No new processing will be started 83 // completed. No new processing will be started
89 84
90 public void Close() 85 public void Close()
@@ -111,14 +106,14 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
111 106
112 private void DoAsset(RequestData rparm) 107 private void DoAsset(RequestData rparm)
113 { 108 {
114 109 if (!enabled)
115 if (!enabled) return; 110 return;
116 111
117 AssetRequestData rdata = (AssetRequestData) rparm; 112 AssetRequestData rdata = (AssetRequestData) rparm;
118 113
119 Rest.Log.DebugFormat("{0} REST Asset handler ENTRY", MsgId); 114 Rest.Log.DebugFormat("{0} REST Asset handler ENTRY", MsgId);
120 115
121 // Now that we know this is a serious attempt to 116 // Now that we know this is a serious attempt to
122 // access inventory data, we should find out who 117 // access inventory data, we should find out who
123 // is asking, and make sure they are authorized 118 // is asking, and make sure they are authorized
124 // to do so. We need to validate the caller's 119 // to do so. We need to validate the caller's
@@ -129,9 +124,9 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
129 // With the present HTTP server we can't use the 124 // With the present HTTP server we can't use the
130 // builtin authentication mechanisms because they 125 // builtin authentication mechanisms because they
131 // would be enforced for all in-bound requests. 126 // would be enforced for all in-bound requests.
132 // Instead we look at the headers ourselves and 127 // Instead we look at the headers ourselves and
133 // handle authentication directly. 128 // handle authentication directly.
134 129
135 try 130 try
136 { 131 {
137 if (!rdata.IsAuthenticated) 132 if (!rdata.IsAuthenticated)
@@ -144,13 +139,13 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
144 if (e.statusCode == Rest.HttpStatusCodeNotAuthorized) 139 if (e.statusCode == Rest.HttpStatusCodeNotAuthorized)
145 { 140 {
146 Rest.Log.WarnFormat("{0} User not authenticated", MsgId); 141 Rest.Log.WarnFormat("{0} User not authenticated", MsgId);
147 Rest.Log.DebugFormat("{0} Authorization header: {1}", MsgId, 142 Rest.Log.DebugFormat("{0} Authorization header: {1}", MsgId,
148 rdata.request.Headers.Get("Authorization")); 143 rdata.request.Headers.Get("Authorization"));
149 } 144 }
150 else 145 else
151 { 146 {
152 Rest.Log.ErrorFormat("{0} User authentication failed", MsgId); 147 Rest.Log.ErrorFormat("{0} User authentication failed", MsgId);
153 Rest.Log.DebugFormat("{0} Authorization header: {1}", MsgId, 148 Rest.Log.DebugFormat("{0} Authorization header: {1}", MsgId,
154 rdata.request.Headers.Get("Authorization")); 149 rdata.request.Headers.Get("Authorization"));
155 } 150 }
156 throw (e); 151 throw (e);
@@ -173,7 +168,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
173 case "post" : 168 case "post" :
174 case "delete" : 169 case "delete" :
175 default : 170 default :
176 Rest.Log.WarnFormat("{0} Asset: Method not supported: {1}", 171 Rest.Log.WarnFormat("{0} Asset: Method not supported: {1}",
177 MsgId, rdata.method); 172 MsgId, rdata.method);
178 rdata.Fail(Rest.HttpStatusCodeBadRequest, 173 rdata.Fail(Rest.HttpStatusCodeBadRequest,
179 Rest.HttpStatusDescBadRequest); 174 Rest.HttpStatusDescBadRequest);
@@ -194,7 +189,6 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
194 189
195 private void DoGet(AssetRequestData rdata) 190 private void DoGet(AssetRequestData rdata)
196 { 191 {
197
198 bool istexture = false; 192 bool istexture = false;
199 193
200 Rest.Log.DebugFormat("{0} REST Asset handler, Method = <{1}> ENTRY", MsgId, rdata.method); 194 Rest.Log.DebugFormat("{0} REST Asset handler, Method = <{1}> ENTRY", MsgId, rdata.method);
@@ -204,13 +198,11 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
204 198
205 if (rdata.parameters.Length == 1) 199 if (rdata.parameters.Length == 1)
206 { 200 {
207
208 LLUUID uuid = new LLUUID(rdata.parameters[0]); 201 LLUUID uuid = new LLUUID(rdata.parameters[0]);
209 AssetBase asset = Rest.AssetServices.GetAsset(uuid, istexture); 202 AssetBase asset = Rest.AssetServices.GetAsset(uuid, istexture);
210 203
211 if (asset != null) 204 if (asset != null)
212 { 205 {
213
214 Rest.Log.DebugFormat("{0} Asset located <{1}>", MsgId, rdata.parameters[0]); 206 Rest.Log.DebugFormat("{0} Asset located <{1}>", MsgId, rdata.parameters[0]);
215 207
216 rdata.initXmlWriter(); 208 rdata.initXmlWriter();
@@ -227,19 +219,17 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
227 rdata.writer.WriteBase64(asset.Data,0,asset.Data.Length); 219 rdata.writer.WriteBase64(asset.Data,0,asset.Data.Length);
228 220
229 rdata.writer.WriteFullEndElement(); 221 rdata.writer.WriteFullEndElement();
230
231 } 222 }
232 else 223 else
233 { 224 {
234 Rest.Log.DebugFormat("{0} Invalid parameters: <{1}>", MsgId, rdata.path); 225 Rest.Log.DebugFormat("{0} Invalid parameters: <{1}>", MsgId, rdata.path);
235 rdata.Fail(Rest.HttpStatusCodeNotFound, 226 rdata.Fail(Rest.HttpStatusCodeNotFound,
236 Rest.HttpStatusDescNotFound); 227 Rest.HttpStatusDescNotFound);
237 } 228 }
238 } 229 }
239 230
240 rdata.Complete(); 231 rdata.Complete();
241 rdata.Respond("Asset " + rdata.method + ": Normal completion"); 232 rdata.Respond("Asset " + rdata.method + ": Normal completion");
242
243 } 233 }
244 234
245 private void DoPut(AssetRequestData rdata) 235 private void DoPut(AssetRequestData rdata)
@@ -257,7 +247,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
257 if (!xml.ReadToFollowing("Asset")) 247 if (!xml.ReadToFollowing("Asset"))
258 { 248 {
259 Rest.Log.DebugFormat("{0} Invalid request data: <{1}>", MsgId, rdata.path); 249 Rest.Log.DebugFormat("{0} Invalid request data: <{1}>", MsgId, rdata.path);
260 rdata.Fail(Rest.HttpStatusCodeBadRequest, 250 rdata.Fail(Rest.HttpStatusCodeBadRequest,
261 Rest.HttpStatusDescBadRequest); 251 Rest.HttpStatusDescBadRequest);
262 } 252 }
263 253
@@ -275,13 +265,12 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
275 else 265 else
276 { 266 {
277 Rest.Log.DebugFormat("{0} Invalid parameters: <{1}>", MsgId, rdata.path); 267 Rest.Log.DebugFormat("{0} Invalid parameters: <{1}>", MsgId, rdata.path);
278 rdata.Fail(Rest.HttpStatusCodeNotFound, 268 rdata.Fail(Rest.HttpStatusCodeNotFound,
279 Rest.HttpStatusDescNotFound); 269 Rest.HttpStatusDescNotFound);
280 } 270 }
281 271
282 rdata.Complete(); 272 rdata.Complete();
283 rdata.Respond("Asset " + rdata.method + ": Normal completion"); 273 rdata.Respond("Asset " + rdata.method + ": Normal completion");
284
285 } 274 }
286 275
287 internal class AssetRequestData : RequestData 276 internal class AssetRequestData : RequestData
@@ -291,6 +280,5 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
291 { 280 {
292 } 281 }
293 } 282 }
294
295 } 283 }
296} 284}
diff --git a/OpenSim/ApplicationPlugins/Rest/Inventory/RestHandler.cs b/OpenSim/ApplicationPlugins/Rest/Inventory/RestHandler.cs
index 7bd83c1..7f4157c 100644
--- a/OpenSim/ApplicationPlugins/Rest/Inventory/RestHandler.cs
+++ b/OpenSim/ApplicationPlugins/Rest/Inventory/RestHandler.cs
@@ -23,7 +23,6 @@
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 *
27 */ 26 */
28 27
29using System; 28using System;
@@ -37,7 +36,6 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
37{ 36{
38 public class RestHandler : RestPlugin, IHttpAgentHandler 37 public class RestHandler : RestPlugin, IHttpAgentHandler
39 { 38 {
40
41 /// <remarks> 39 /// <remarks>
42 /// The handler delegates are not noteworthy. The allocator allows 40 /// The handler delegates are not noteworthy. The allocator allows
43 /// a given handler to optionally subclass the base RequestData 41 /// a given handler to optionally subclass the base RequestData
@@ -66,10 +64,10 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
66 /// <summary> 64 /// <summary>
67 /// This static initializer scans the ASSEMBLY for classes that 65 /// This static initializer scans the ASSEMBLY for classes that
68 /// export the IRest interface and builds a list of them. These 66 /// export the IRest interface and builds a list of them. These
69 /// are later activated by the handler. To add a new handler it 67 /// are later activated by the handler. To add a new handler it
70 /// is only necessary to create a new services class that implements 68 /// is only necessary to create a new services class that implements
71 /// the IRest interface, and recompile the handler. This gives 69 /// the IRest interface, and recompile the handler. This gives
72 /// all of the build-time flexibility of a modular approach 70 /// all of the build-time flexibility of a modular approach
73 /// while not introducing yet-another module loader. Note that 71 /// while not introducing yet-another module loader. Note that
74 /// multiple assembles can still be built, each with its own set 72 /// multiple assembles can still be built, each with its own set
75 /// of handlers. Examples of services classes are RestInventoryServices 73 /// of handlers. Examples of services classes are RestInventoryServices
@@ -78,13 +76,12 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
78 76
79 static RestHandler() 77 static RestHandler()
80 { 78 {
81
82 Module[] mods = Assembly.GetExecutingAssembly().GetModules(); 79 Module[] mods = Assembly.GetExecutingAssembly().GetModules();
83 80
84 foreach (Module m in mods) 81 foreach (Module m in mods)
85 { 82 {
86 Type[] types = m.GetTypes(); 83 Type[] types = m.GetTypes();
87 foreach (Type t in types) 84 foreach (Type t in types)
88 { 85 {
89 try 86 try
90 { 87 {
@@ -100,7 +97,6 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
100 } 97 }
101 } 98 }
102 } 99 }
103
104 } 100 }
105 101
106 #endregion local static state 102 #endregion local static state
@@ -109,13 +105,13 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
109 105
110 /// <summary> 106 /// <summary>
111 /// This routine loads all of the handlers discovered during 107 /// This routine loads all of the handlers discovered during
112 /// instance initialization. 108 /// instance initialization.
113 /// A table of all loaded and successfully constructed handlers 109 /// A table of all loaded and successfully constructed handlers
114 /// is built, and this table is then used by the constructor to 110 /// is built, and this table is then used by the constructor to
115 /// initialize each of the handlers in turn. 111 /// initialize each of the handlers in turn.
116 /// NOTE: The loading process does not automatically imply that 112 /// NOTE: The loading process does not automatically imply that
117 /// the handler has registered any kind of an interface, that 113 /// the handler has registered any kind of an interface, that
118 /// may be (optionally) done by the handler either during 114 /// may be (optionally) done by the handler either during
119 /// construction, or during initialization. 115 /// construction, or during initialization.
120 /// 116 ///
121 /// I was not able to make this code work within a constructor 117 /// I was not able to make this code work within a constructor
@@ -128,7 +124,6 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
128 { 124 {
129 if (!handlersLoaded) 125 if (!handlersLoaded)
130 { 126 {
131
132 ConstructorInfo ci; 127 ConstructorInfo ci;
133 Object ht; 128 Object ht;
134 129
@@ -159,8 +154,8 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
159 154
160 // Name is used to differentiate the message header. 155 // Name is used to differentiate the message header.
161 156
162 public override string Name 157 public override string Name
163 { 158 {
164 get { return "HANDLER"; } 159 get { return "HANDLER"; }
165 } 160 }
166 161
@@ -173,7 +168,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
173 168
174 // We have to rename these because we want 169 // We have to rename these because we want
175 // to be able to share the values with other 170 // to be able to share the values with other
176 // classes in our assembly and the base 171 // classes in our assembly and the base
177 // names are protected. 172 // names are protected.
178 173
179 internal string MsgId 174 internal string MsgId
@@ -203,7 +198,6 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
203 { 198 {
204 try 199 try
205 { 200 {
206
207 // This plugin will only be enabled if the broader 201 // This plugin will only be enabled if the broader
208 // REST plugin mechanism is enabled. 202 // REST plugin mechanism is enabled.
209 203
@@ -214,7 +208,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
214 // IsEnabled is implemented by the base class and 208 // IsEnabled is implemented by the base class and
215 // reflects an overall RestPlugin status 209 // reflects an overall RestPlugin status
216 210
217 if (!IsEnabled) 211 if (!IsEnabled)
218 { 212 {
219 Rest.Log.WarnFormat("{0} Plugins are disabled", MsgId); 213 Rest.Log.WarnFormat("{0} Plugins are disabled", MsgId);
220 return; 214 return;
@@ -263,15 +257,15 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
263 Rest.DumpLineSize); 257 Rest.DumpLineSize);
264 } 258 }
265 259
266 // Load all of the handlers present in the 260 // Load all of the handlers present in the
267 // assembly 261 // assembly
268 262
269 // In principle, as we're an application plug-in, 263 // In principle, as we're an application plug-in,
270 // most of what needs to be done could be done using 264 // most of what needs to be done could be done using
271 // static resources, however the Open Sim plug-in 265 // static resources, however the Open Sim plug-in
272 // model makes this an instance, so that's what we 266 // model makes this an instance, so that's what we
273 // need to be. 267 // need to be.
274 // There is only one Communications manager per 268 // There is only one Communications manager per
275 // server, and by inference, only one each of the 269 // server, and by inference, only one each of the
276 // user, asset, and inventory servers. So we can cache 270 // user, asset, and inventory servers. So we can cache
277 // those using a static initializer. 271 // those using a static initializer.
@@ -314,13 +308,12 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
314 { 308 {
315 Rest.Log.ErrorFormat("{0} Plugin initialization has failed: {1}", MsgId, e.Message); 309 Rest.Log.ErrorFormat("{0} Plugin initialization has failed: {1}", MsgId, e.Message);
316 } 310 }
317
318 } 311 }
319 312
320 /// <summary> 313 /// <summary>
321 /// In the interests of efficiency, and because we cannot determine whether 314 /// In the interests of efficiency, and because we cannot determine whether
322 /// or not this instance will actually be harvested, we clobber the only 315 /// or not this instance will actually be harvested, we clobber the only
323 /// anchoring reference to the working state for this plug-in. What the 316 /// anchoring reference to the working state for this plug-in. What the
324 /// call to close does is irrelevant to this class beyond knowing that it 317 /// call to close does is irrelevant to this class beyond knowing that it
325 /// can nullify the reference when it returns. 318 /// can nullify the reference when it returns.
326 /// To make sure everything is copacetic we make sure the primary interface 319 /// To make sure everything is copacetic we make sure the primary interface
@@ -329,7 +322,6 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
329 322
330 public override void Close() 323 public override void Close()
331 { 324 {
332
333 Rest.Log.InfoFormat("{0} Plugin is terminating", MsgId); 325 Rest.Log.InfoFormat("{0} Plugin is terminating", MsgId);
334 326
335 try 327 try
@@ -337,12 +329,11 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
337 RemoveAgentHandler(Rest.Name, this); 329 RemoveAgentHandler(Rest.Name, this);
338 } 330 }
339 catch (KeyNotFoundException){} 331 catch (KeyNotFoundException){}
340 332
341 foreach (IRest handler in handlers) 333 foreach (IRest handler in handlers)
342 { 334 {
343 handler.Close(); 335 handler.Close();
344 } 336 }
345
346 } 337 }
347 338
348 #endregion overriding methods 339 #endregion overriding methods
@@ -380,7 +371,6 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
380 return true; 371 return true;
381 } 372 }
382 } 373 }
383
384 } 374 }
385 catch (Exception e) 375 catch (Exception e)
386 { 376 {
@@ -414,7 +404,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
414 404
415 for (int i = 0; i < request.Headers.Count; i++) 405 for (int i = 0; i < request.Headers.Count; i++)
416 { 406 {
417 Rest.Log.DebugFormat("{0} Header [{1}] : <{2}> = <{3}>", 407 Rest.Log.DebugFormat("{0} Header [{1}] : <{2}> = <{3}>",
418 MsgId, i, request.Headers.GetKey(i), request.Headers.Get(i)); 408 MsgId, i, request.Headers.GetKey(i), request.Headers.Get(i));
419 } 409 }
420 Rest.Log.DebugFormat("{0} URI: {1}", MsgId, request.RawUrl); 410 Rest.Log.DebugFormat("{0} URI: {1}", MsgId, request.RawUrl);
@@ -425,8 +415,8 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
425 415
426 try 416 try
427 { 417 {
428 handled = ( FindPathHandler(request, response) || 418 handled = FindPathHandler(request, response) ||
429 FindStreamHandler(request, response) ); 419 FindStreamHandler(request, response);
430 } 420 }
431 catch (Exception e) 421 catch (Exception e)
432 { 422 {
@@ -440,7 +430,6 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
440 Rest.Log.DebugFormat("{0} EXIT", MsgId); 430 Rest.Log.DebugFormat("{0} EXIT", MsgId);
441 431
442 return handled; 432 return handled;
443
444 } 433 }
445 434
446 #endregion interface methods 435 #endregion interface methods
@@ -488,7 +477,6 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
488 } 477 }
489 478
490 return rdata.handled; 479 return rdata.handled;
491
492 } 480 }
493 481
494 /// <summary> 482 /// <summary>
@@ -501,13 +489,12 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
501 489
502 public void AddStreamHandler(string httpMethod, string path, RestMethod method) 490 public void AddStreamHandler(string httpMethod, string path, RestMethod method)
503 { 491 {
504
505 if (!IsEnabled) 492 if (!IsEnabled)
506 { 493 {
507 return; 494 return;
508 } 495 }
509 496
510 if (!path.StartsWith(Rest.Prefix)) 497 if (!path.StartsWith(Rest.Prefix))
511 { 498 {
512 path = String.Format("{0}{1}", Rest.Prefix, path); 499 path = String.Format("{0}{1}", Rest.Prefix, path);
513 } 500 }
@@ -525,7 +512,6 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
525 { 512 {
526 Rest.Log.WarnFormat("{0} Ignoring duplicate handler for {1}", MsgId, path); 513 Rest.Log.WarnFormat("{0} Ignoring duplicate handler for {1}", MsgId, path);
527 } 514 }
528
529 } 515 }
530 516
531 /// <summary> 517 /// <summary>
@@ -540,10 +526,9 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
540 526
541 internal bool FindPathHandler(OSHttpRequest request, OSHttpResponse response) 527 internal bool FindPathHandler(OSHttpRequest request, OSHttpResponse response)
542 { 528 {
543
544 RequestData rdata = null; 529 RequestData rdata = null;
545 string bestMatch = null; 530 string bestMatch = null;
546 531
547 if (!IsEnabled) 532 if (!IsEnabled)
548 { 533 {
549 return false; 534 return false;
@@ -566,7 +551,6 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
566 551
567 if (!String.IsNullOrEmpty(bestMatch)) 552 if (!String.IsNullOrEmpty(bestMatch))
568 { 553 {
569
570 rdata = pathAllocators[bestMatch](request, response); 554 rdata = pathAllocators[bestMatch](request, response);
571 555
572 Rest.Log.DebugFormat("{0} Path based REST handler matched with <{1}>", MsgId, bestMatch); 556 Rest.Log.DebugFormat("{0} Path based REST handler matched with <{1}>", MsgId, bestMatch);
@@ -575,7 +559,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
575 { 559 {
576 pathHandlers[bestMatch](rdata); 560 pathHandlers[bestMatch](rdata);
577 } 561 }
578 562
579 // A plugin generated error indicates a request-related error 563 // A plugin generated error indicates a request-related error
580 // that has been handled by the plugin. 564 // that has been handled by the plugin.
581 565
@@ -583,11 +567,9 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
583 { 567 {
584 Rest.Log.WarnFormat("{0} Request failed: {1}", MsgId, r.Message); 568 Rest.Log.WarnFormat("{0} Request failed: {1}", MsgId, r.Message);
585 } 569 }
586
587 } 570 }
588 571
589 return (rdata == null) ? false : rdata.handled; 572 return (rdata == null) ? false : rdata.handled;
590
591 } 573 }
592 574
593 /// <summary> 575 /// <summary>
@@ -597,7 +579,6 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
597 579
598 internal void AddPathHandler(RestMethodHandler mh, string path, RestMethodAllocator ra) 580 internal void AddPathHandler(RestMethodHandler mh, string path, RestMethodAllocator ra)
599 { 581 {
600
601 if (!IsEnabled) 582 if (!IsEnabled)
602 { 583 {
603 return; 584 return;
@@ -619,8 +600,6 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
619 600
620 pathHandlers.Add(path, mh); 601 pathHandlers.Add(path, mh);
621 pathAllocators.Add(path, ra); 602 pathAllocators.Add(path, ra);
622
623 } 603 }
624 } 604 }
625
626} 605}
diff --git a/OpenSim/ApplicationPlugins/Rest/Inventory/RestInventoryServices.cs b/OpenSim/ApplicationPlugins/Rest/Inventory/RestInventoryServices.cs
index 61c3ac4..0c107d5 100644
--- a/OpenSim/ApplicationPlugins/Rest/Inventory/RestInventoryServices.cs
+++ b/OpenSim/ApplicationPlugins/Rest/Inventory/RestInventoryServices.cs
@@ -23,7 +23,6 @@
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 *
27 */ 26 */
28 27
29using System; 28using System;
@@ -42,10 +41,8 @@ using Nini.Config;
42 41
43namespace OpenSim.ApplicationPlugins.Rest.Inventory 42namespace OpenSim.ApplicationPlugins.Rest.Inventory
44{ 43{
45
46 public class RestInventoryServices : IRest 44 public class RestInventoryServices : IRest
47 { 45 {
48
49 private bool enabled = false; 46 private bool enabled = false;
50 private string qPrefix = "inventory"; 47 private string qPrefix = "inventory";
51 48
@@ -56,11 +53,10 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
56 53
57 public RestInventoryServices() 54 public RestInventoryServices()
58 { 55 {
59
60 Rest.Log.InfoFormat("{0} Inventory services initializing", MsgId); 56 Rest.Log.InfoFormat("{0} Inventory services initializing", MsgId);
61 Rest.Log.InfoFormat("{0} Using REST Implementation Version {1}", MsgId, Rest.Version); 57 Rest.Log.InfoFormat("{0} Using REST Implementation Version {1}", MsgId, Rest.Version);
62 58
63 // If a relative path was specified for the handler's domain, 59 // If a relative path was specified for the handler's domain,
64 // add the standard prefix to make it absolute, e.g. /admin 60 // add the standard prefix to make it absolute, e.g. /admin
65 61
66 if (!qPrefix.StartsWith(Rest.UrlPathSeparator)) 62 if (!qPrefix.StartsWith(Rest.UrlPathSeparator))
@@ -77,7 +73,6 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
77 enabled = true; 73 enabled = true;
78 74
79 Rest.Log.InfoFormat("{0} Inventory services initialization complete", MsgId); 75 Rest.Log.InfoFormat("{0} Inventory services initialization complete", MsgId);
80
81 } 76 }
82 77
83 /// <summary> 78 /// <summary>
@@ -91,7 +86,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
91 86
92 /// <summary> 87 /// <summary>
93 /// Called by the plug-in to halt REST processing. Local processing is 88 /// Called by the plug-in to halt REST processing. Local processing is
94 /// disabled, and control blocks until all current processing has 89 /// disabled, and control blocks until all current processing has
95 /// completed. No new processing will be started 90 /// completed. No new processing will be started
96 /// </summary> 91 /// </summary>
97 92
@@ -134,7 +129,6 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
134 129
135 private void DoInventory(RequestData hdata) 130 private void DoInventory(RequestData hdata)
136 { 131 {
137
138 InventoryRequestData rdata = (InventoryRequestData) hdata; 132 InventoryRequestData rdata = (InventoryRequestData) hdata;
139 133
140 Rest.Log.DebugFormat("{0} DoInventory ENTRY", MsgId); 134 Rest.Log.DebugFormat("{0} DoInventory ENTRY", MsgId);
@@ -146,7 +140,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
146 return; 140 return;
147 } 141 }
148 142
149 // Now that we know this is a serious attempt to 143 // Now that we know this is a serious attempt to
150 // access inventory data, we should find out who 144 // access inventory data, we should find out who
151 // is asking, and make sure they are authorized 145 // is asking, and make sure they are authorized
152 // to do so. We need to validate the caller's 146 // to do so. We need to validate the caller's
@@ -157,9 +151,9 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
157 // With the present HTTP server we can't use the 151 // With the present HTTP server we can't use the
158 // builtin authentication mechanisms because they 152 // builtin authentication mechanisms because they
159 // would be enforced for all in-bound requests. 153 // would be enforced for all in-bound requests.
160 // Instead we look at the headers ourselves and 154 // Instead we look at the headers ourselves and
161 // handle authentication directly. 155 // handle authentication directly.
162 156
163 try 157 try
164 { 158 {
165 if (!rdata.IsAuthenticated) 159 if (!rdata.IsAuthenticated)
@@ -197,7 +191,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
197 /// 191 ///
198 /// Indicating that this is an inventory request for 192 /// Indicating that this is an inventory request for
199 /// an avatar named Arthur Dent. This is ALl that is 193 /// an avatar named Arthur Dent. This is ALl that is
200 /// required to designate a GET for an entire 194 /// required to designate a GET for an entire
201 /// inventory. 195 /// inventory.
202 /// </remarks> 196 /// </remarks>
203 197
@@ -238,7 +232,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
238 232
239 if (rdata.userProfile != null) 233 if (rdata.userProfile != null)
240 { 234 {
241 Rest.Log.DebugFormat("{0} Profile obtained for agent {1} {2}", 235 Rest.Log.DebugFormat("{0} Profile obtained for agent {1} {2}",
242 MsgId, rdata.userProfile.FirstName, rdata.userProfile.SurName); 236 MsgId, rdata.userProfile.FirstName, rdata.userProfile.SurName);
243 } 237 }
244 else 238 else
@@ -260,18 +254,18 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
260 // response is not recieved in a timely fashion. 254 // response is not recieved in a timely fashion.
261 255
262 rdata.uuid = rdata.userProfile.ID; 256 rdata.uuid = rdata.userProfile.ID;
263 257
264 if (Rest.InventoryServices.HasInventoryForUser(rdata.uuid)) 258 if (Rest.InventoryServices.HasInventoryForUser(rdata.uuid))
265 { 259 {
266 260
267 rdata.root = Rest.InventoryServices.RequestRootFolder(rdata.uuid); 261 rdata.root = Rest.InventoryServices.RequestRootFolder(rdata.uuid);
268 262
269 Rest.Log.DebugFormat("{0} Inventory Root retrieved for {1} {2}", 263 Rest.Log.DebugFormat("{0} Inventory Root retrieved for {1} {2}",
270 MsgId, rdata.userProfile.FirstName, rdata.userProfile.SurName); 264 MsgId, rdata.userProfile.FirstName, rdata.userProfile.SurName);
271 265
272 Rest.InventoryServices.RequestInventoryForUser(rdata.uuid, rdata.GetUserInventory); 266 Rest.InventoryServices.RequestInventoryForUser(rdata.uuid, rdata.GetUserInventory);
273 267
274 Rest.Log.DebugFormat("{0} Inventory catalog requested for {1} {2}", 268 Rest.Log.DebugFormat("{0} Inventory catalog requested for {1} {2}",
275 MsgId, rdata.userProfile.FirstName, rdata.userProfile.SurName); 269 MsgId, rdata.userProfile.FirstName, rdata.userProfile.SurName);
276 270
277 lock (rdata) 271 lock (rdata)
@@ -284,15 +278,14 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
284 278
285 if (rdata.root == null) 279 if (rdata.root == null)
286 { 280 {
287 Rest.Log.DebugFormat("{0} Inventory is not available [1] for agent {1} {2}", 281 Rest.Log.DebugFormat("{0} Inventory is not available [1] for agent {1} {2}",
288 MsgId, rdata.userProfile.FirstName, rdata.userProfile.SurName); 282 MsgId, rdata.userProfile.FirstName, rdata.userProfile.SurName);
289 rdata.Fail(Rest.HttpStatusCodeServerError,Rest.HttpStatusDescServerError+": inventory retrieval failed"); 283 rdata.Fail(Rest.HttpStatusCodeServerError,Rest.HttpStatusDescServerError+": inventory retrieval failed");
290 } 284 }
291
292 } 285 }
293 else 286 else
294 { 287 {
295 Rest.Log.DebugFormat("{0} Inventory is not available for agent [3] {1} {2}", 288 Rest.Log.DebugFormat("{0} Inventory is not available for agent [3] {1} {2}",
296 MsgId, rdata.userProfile.FirstName, rdata.userProfile.SurName); 289 MsgId, rdata.userProfile.FirstName, rdata.userProfile.SurName);
297 rdata.Fail(Rest.HttpStatusCodeNotFound,Rest.HttpStatusDescNotFound+": no inventory for user"); 290 rdata.Fail(Rest.HttpStatusCodeNotFound,Rest.HttpStatusDescNotFound+": no inventory for user");
298 } 291 }
@@ -302,7 +295,6 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
302 295
303 switch (rdata.method) 296 switch (rdata.method)
304 { 297 {
305
306 case Rest.HEAD : // Do the processing, set the status code, suppress entity 298 case Rest.HEAD : // Do the processing, set the status code, suppress entity
307 DoGet(rdata); 299 DoGet(rdata);
308 rdata.buffer = null; 300 rdata.buffer = null;
@@ -325,13 +317,12 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
325 break; 317 break;
326 318
327 default : 319 default :
328 Rest.Log.DebugFormat("{0} Method {1} not supported for {2}", 320 Rest.Log.DebugFormat("{0} Method {1} not supported for {2}",
329 MsgId, rdata.method, rdata.path); 321 MsgId, rdata.method, rdata.path);
330 rdata.Fail(Rest.HttpStatusCodeMethodNotAllowed, 322 rdata.Fail(Rest.HttpStatusCodeMethodNotAllowed,
331 Rest.HttpStatusDescMethodNotAllowed+": "+rdata.method+" not supported"); 323 Rest.HttpStatusDescMethodNotAllowed+": "+rdata.method+" not supported");
332 break; 324 break;
333 } 325 }
334
335 } 326 }
336 327
337 #endregion Interface 328 #endregion Interface
@@ -346,12 +337,11 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
346 337
347 private void DoGet(InventoryRequestData rdata) 338 private void DoGet(InventoryRequestData rdata)
348 { 339 {
349
350 rdata.initXmlWriter(); 340 rdata.initXmlWriter();
351 341
352 rdata.writer.WriteStartElement(String.Empty,"Inventory",String.Empty); 342 rdata.writer.WriteStartElement(String.Empty,"Inventory",String.Empty);
353 343
354 // If there was only one parameter, then the entire 344 // If there was only one parameter, then the entire
355 // inventory is being requested. 345 // inventory is being requested.
356 346
357 if (rdata.parameters.Length == 1) 347 if (rdata.parameters.Length == 1)
@@ -361,7 +351,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
361 351
362 // If there are additional parameters, then these represent 352 // If there are additional parameters, then these represent
363 // a path relative to the root of the inventory. This path 353 // a path relative to the root of the inventory. This path
364 // must be traversed before we format the sub-tree thus 354 // must be traversed before we format the sub-tree thus
365 // identified. 355 // identified.
366 356
367 else 357 else
@@ -373,9 +363,8 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
373 363
374 rdata.Complete(); 364 rdata.Complete();
375 rdata.Respond("Inventory " + rdata.method + ": Normal completion"); 365 rdata.Respond("Inventory " + rdata.method + ": Normal completion");
376
377 } 366 }
378 367
379 /// <summary> 368 /// <summary>
380 /// In the case of the inventory, and probably in general, 369 /// In the case of the inventory, and probably in general,
381 /// the distinction between PUT and POST is not always 370 /// the distinction between PUT and POST is not always
@@ -389,29 +378,28 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
389 /// The best way to exaplain the distinction is to 378 /// The best way to exaplain the distinction is to
390 /// consider the relationship between the URI and the 379 /// consider the relationship between the URI and the
391 /// entity in question. For POST, the URI identifies the 380 /// entity in question. For POST, the URI identifies the
392 /// entity to be modified or replaced. 381 /// entity to be modified or replaced.
393 /// If the operation is PUT,then the URI describes the 382 /// If the operation is PUT,then the URI describes the
394 /// context into which the new entity will be added. 383 /// context into which the new entity will be added.
395 /// 384 ///
396 /// As an example, suppose the URI contains: 385 /// As an example, suppose the URI contains:
397 /// /admin/inventory/Clothing 386 /// /admin/inventory/Clothing
398 /// 387 ///
399 /// A POST request will result in some modification of 388 /// A POST request will result in some modification of
400 /// the folder or item named "Clothing". Whereas a PUT 389 /// the folder or item named "Clothing". Whereas a PUT
401 /// request will add some new information into the 390 /// request will add some new information into the
402 /// content identified by Clothing. It follows from this 391 /// content identified by Clothing. It follows from this
403 /// that for PUT, the element identified by the URI must 392 /// that for PUT, the element identified by the URI must
404 /// be a folder. 393 /// be a folder.
405 /// </summary> 394 /// </summary>
406 395
407 /// <summary> 396 /// <summary>
408 /// PUT adds new information to the inventory in the 397 /// PUT adds new information to the inventory in the
409 /// context identified by the URI. 398 /// context identified by the URI.
410 /// </summary> 399 /// </summary>
411 400
412 private void DoPut(InventoryRequestData rdata) 401 private void DoPut(InventoryRequestData rdata)
413 { 402 {
414
415 // Resolve the context node specified in the URI. Entity 403 // Resolve the context node specified in the URI. Entity
416 // data will be ADDED beneath this node. 404 // data will be ADDED beneath this node.
417 405
@@ -419,11 +407,11 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
419 407
420 // Processing depends upon the type of inventory node 408 // Processing depends upon the type of inventory node
421 // identified in the URI. This is the CONTEXT for the 409 // identified in the URI. This is the CONTEXT for the
422 // change. We either got a context or we threw an 410 // change. We either got a context or we threw an
423 // exception. 411 // exception.
424 412
425 // It follows that we can only add information if the URI 413 // It follows that we can only add information if the URI
426 // has identified a folder. So only a type of folder is supported 414 // has identified a folder. So only a type of folder is supported
427 // in this case. 415 // in this case.
428 416
429 if (typeof(InventoryFolderBase) == InventoryNode.GetType() || 417 if (typeof(InventoryFolderBase) == InventoryNode.GetType() ||
@@ -448,12 +436,11 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
448 XmlInventoryCollection entity = ReconstituteEntity(rdata); 436 XmlInventoryCollection entity = ReconstituteEntity(rdata);
449 437
450 // Inlined assets can be included in entity. These must be incorporated into 438 // Inlined assets can be included in entity. These must be incorporated into
451 // the asset database before we attempt to update the inventory. If anything 439 // the asset database before we attempt to update the inventory. If anything
452 // fails, return a failure to requestor. 440 // fails, return a failure to requestor.
453 441
454 if (entity.Assets.Count > 0) 442 if (entity.Assets.Count > 0)
455 { 443 {
456
457 Rest.Log.DebugFormat("{0} Adding {1} assets to server", 444 Rest.Log.DebugFormat("{0} Adding {1} assets to server",
458 MsgId, entity.Assets.Count); 445 MsgId, entity.Assets.Count);
459 446
@@ -467,9 +454,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
467 { 454 {
468 Rest.Dump(asset.Data); 455 Rest.Dump(asset.Data);
469 } 456 }
470
471 } 457 }
472
473 } 458 }
474 459
475 // Modify the context using the collection of folders and items 460 // Modify the context using the collection of folders and items
@@ -477,7 +462,6 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
477 462
478 foreach (InventoryFolderBase folder in entity.Folders) 463 foreach (InventoryFolderBase folder in entity.Folders)
479 { 464 {
480
481 InventoryFolderBase found; 465 InventoryFolderBase found;
482 466
483 // If the parentID is zero, then this folder is going 467 // If the parentID is zero, then this folder is going
@@ -519,7 +503,6 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
519 Rest.Log.DebugFormat("{0} Adding new folder", MsgId); 503 Rest.Log.DebugFormat("{0} Adding new folder", MsgId);
520 Rest.InventoryServices.AddFolder(folder); 504 Rest.InventoryServices.AddFolder(folder);
521 } 505 }
522
523 } 506 }
524 507
525 // Now we repeat a similar process for the items included 508 // Now we repeat a similar process for the items included
@@ -527,7 +510,6 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
527 510
528 foreach (InventoryItemBase item in entity.Items) 511 foreach (InventoryItemBase item in entity.Items)
529 { 512 {
530
531 InventoryItemBase found = null; 513 InventoryItemBase found = null;
532 514
533 // If the parentID is zero, then this is going 515 // If the parentID is zero, then this is going
@@ -538,7 +520,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
538 item.Folder = context.ID; 520 item.Folder = context.ID;
539 } 521 }
540 522
541 // Determine whether this is a new item or a 523 // Determine whether this is a new item or a
542 // replacement definition. 524 // replacement definition.
543 525
544 foreach (InventoryItemBase xi in rdata.items) 526 foreach (InventoryItemBase xi in rdata.items)
@@ -563,9 +545,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
563 MsgId, item.ID, item.AssetID, item.InvType, item.AssetType, item.Name); 545 MsgId, item.ID, item.AssetID, item.InvType, item.AssetType, item.Name);
564 Rest.InventoryServices.AddItem(item); 546 Rest.InventoryServices.AddItem(item);
565 } 547 }
566
567 } 548 }
568
569 } 549 }
570 else 550 else
571 { 551 {
@@ -577,34 +557,32 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
577 557
578 rdata.Complete(); 558 rdata.Complete();
579 rdata.Respond("Inventory " + rdata.method + ": Normal completion"); 559 rdata.Respond("Inventory " + rdata.method + ": Normal completion");
580
581 } 560 }
582 561
583 /// <summary> 562 /// <summary>
584 /// POST updates the URI-identified element in the inventory. This 563 /// POST updates the URI-identified element in the inventory. This
585 /// is actually far more flexible than it might at first sound. For 564 /// is actually far more flexible than it might at first sound. For
586 /// POST the URI serves two purposes: 565 /// POST the URI serves two purposes:
587 /// [1] It identifies the user whose inventory is to be 566 /// [1] It identifies the user whose inventory is to be
588 /// processed. 567 /// processed.
589 /// [2] It optionally specifies a subtree of the inventory 568 /// [2] It optionally specifies a subtree of the inventory
590 /// that is to be used to resolve any relative subtree 569 /// that is to be used to resolve any relative subtree
591 /// specifications in the entity. If nothing is specified 570 /// specifications in the entity. If nothing is specified
592 /// then the whole inventory is implied. 571 /// then the whole inventory is implied.
593 /// Please note that the subtree specified by the URI is only relevant 572 /// Please note that the subtree specified by the URI is only relevant
594 /// to an entity containing a URI relative specification, i.e. one or 573 /// to an entity containing a URI relative specification, i.e. one or
595 /// more elements do not specify parent folder information. These 574 /// more elements do not specify parent folder information. These
596 /// elements will be implicitly referenced within the context identified 575 /// elements will be implicitly referenced within the context identified
597 /// by the URI. 576 /// by the URI.
598 /// If an element in the entity specifies an explicit parent folder, then 577 /// If an element in the entity specifies an explicit parent folder, then
599 /// that parent is effective, regardless of any value specified in the 578 /// that parent is effective, regardless of any value specified in the
600 /// URI. If the parent does not exist, then the element, and any dependent 579 /// URI. If the parent does not exist, then the element, and any dependent
601 /// elements, are ignored. This case is actually detected and handled 580 /// elements, are ignored. This case is actually detected and handled
602 /// during the reconstitution process. 581 /// during the reconstitution process.
603 /// </summary> 582 /// </summary>
604 583
605 private void DoPost(InventoryRequestData rdata) 584 private void DoPost(InventoryRequestData rdata)
606 { 585 {
607
608 int count = 0; 586 int count = 0;
609 587
610 // Resolve the inventory node that is to be modified. 588 // Resolve the inventory node that is to be modified.
@@ -612,8 +590,8 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
612 Object InventoryNode = getInventoryNode(rdata, rdata.root, 1); 590 Object InventoryNode = getInventoryNode(rdata, rdata.root, 1);
613 591
614 // As long as we have a node, then we have something 592 // As long as we have a node, then we have something
615 // meaningful to do, unlike PUT. So we reconstitute the 593 // meaningful to do, unlike PUT. So we reconstitute the
616 // subtree before doing anything else. Note that we 594 // subtree before doing anything else. Note that we
617 // etiher got a valid node or we threw an exception. 595 // etiher got a valid node or we threw an exception.
618 596
619 XmlInventoryCollection entity = ReconstituteEntity(rdata); 597 XmlInventoryCollection entity = ReconstituteEntity(rdata);
@@ -639,7 +617,6 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
639 { 617 {
640 Rest.Dump(asset.Data); 618 Rest.Dump(asset.Data);
641 } 619 }
642
643 } 620 }
644 } 621 }
645 622
@@ -648,15 +625,15 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
648 /// </summary> 625 /// </summary>
649 /// <remarks> 626 /// <remarks>
650 /// The root node in the entity will replace the node identified 627 /// The root node in the entity will replace the node identified
651 /// by the URI. This means the parent will remain the same, but 628 /// by the URI. This means the parent will remain the same, but
652 /// any or all attributes associated with the named element 629 /// any or all attributes associated with the named element
653 /// will change. 630 /// will change.
654 /// 631 ///
655 /// If the inventory collection contains an element with a zero 632 /// If the inventory collection contains an element with a zero
656 /// parent ID, then this is taken to be the replacement for the 633 /// parent ID, then this is taken to be the replacement for the
657 /// named node. The collection MAY also specify an explicit 634 /// named node. The collection MAY also specify an explicit
658 /// parent ID, in this case it MAY identify the same parent as 635 /// parent ID, in this case it MAY identify the same parent as
659 /// the current node, or it MAY specify a different parent, 636 /// the current node, or it MAY specify a different parent,
660 /// indicating that the folder is being moved in addition to any 637 /// indicating that the folder is being moved in addition to any
661 /// other modifications being made. 638 /// other modifications being made.
662 /// </remarks> 639 /// </remarks>
@@ -664,10 +641,9 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
664 if (typeof(InventoryFolderBase) == InventoryNode.GetType() || 641 if (typeof(InventoryFolderBase) == InventoryNode.GetType() ||
665 typeof(InventoryFolderImpl) == InventoryNode.GetType()) 642 typeof(InventoryFolderImpl) == InventoryNode.GetType())
666 { 643 {
667
668 InventoryFolderBase uri = (InventoryFolderBase) InventoryNode; 644 InventoryFolderBase uri = (InventoryFolderBase) InventoryNode;
669 InventoryFolderBase xml = null; 645 InventoryFolderBase xml = null;
670 646
671 // Scan the set of folders in the entity collection for an 647 // Scan the set of folders in the entity collection for an
672 // entry that matches the context folder. It is assumed that 648 // entry that matches the context folder. It is assumed that
673 // the only reliable indicator of this is a zero UUID ( using 649 // the only reliable indicator of this is a zero UUID ( using
@@ -676,7 +652,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
676 // ambiguity in this case because this is POST and we are 652 // ambiguity in this case because this is POST and we are
677 // supposed to be modifying a specific node. 653 // supposed to be modifying a specific node.
678 // We assign any element IDs required as an economy; we don't 654 // We assign any element IDs required as an economy; we don't
679 // want to iterate over the fodler set again if it can be 655 // want to iterate over the fodler set again if it can be
680 // helped. 656 // helped.
681 657
682 foreach (InventoryFolderBase folder in entity.Folders) 658 foreach (InventoryFolderBase folder in entity.Folders)
@@ -701,29 +677,27 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
701 { 677 {
702 Rest.Log.DebugFormat("{0} {1}: Request for <{2}> is ambiguous", 678 Rest.Log.DebugFormat("{0} {1}: Request for <{2}> is ambiguous",
703 MsgId, rdata.method, rdata.path); 679 MsgId, rdata.method, rdata.path);
704 rdata.Fail(Rest.HttpStatusCodeBadRequest, 680 rdata.Fail(Rest.HttpStatusCodeBadRequest,
705 Rest.HttpStatusDescBadRequest+": context is ambiguous"); 681 Rest.HttpStatusDescBadRequest+": context is ambiguous");
706 } 682 }
707 683
708 // Exactly one entry means we ARE replacing the node 684 // Exactly one entry means we ARE replacing the node
709 // identified by the URI. So we delete the old folder 685 // identified by the URI. So we delete the old folder
710 // by moving it to the trash and then purging it. 686 // by moving it to the trash and then purging it.
711 // We then add all of the folders and items we 687 // We then add all of the folders and items we
712 // included in the entity. The subtree has been 688 // included in the entity. The subtree has been
713 // modified. 689 // modified.
714 690
715 if (count == 1) 691 if (count == 1)
716 { 692 {
717
718 InventoryFolderBase TrashCan = GetTrashCan(rdata); 693 InventoryFolderBase TrashCan = GetTrashCan(rdata);
719 694
720 uri.ParentID = TrashCan.ID; 695 uri.ParentID = TrashCan.ID;
721 Rest.InventoryServices.MoveFolder(uri); 696 Rest.InventoryServices.MoveFolder(uri);
722 Rest.InventoryServices.PurgeFolder(TrashCan); 697 Rest.InventoryServices.PurgeFolder(TrashCan);
723
724 } 698 }
725 699
726 // Now, regardelss of what they represent, we 700 // Now, regardelss of what they represent, we
727 // integrate all of the elements in the entity. 701 // integrate all of the elements in the entity.
728 702
729 foreach (InventoryFolderBase f in entity.Folders) 703 foreach (InventoryFolderBase f in entity.Folders)
@@ -735,7 +709,6 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
735 { 709 {
736 Rest.InventoryServices.AddItem(it); 710 Rest.InventoryServices.AddItem(it);
737 } 711 }
738
739 } 712 }
740 713
741 /// <summary> 714 /// <summary>
@@ -748,7 +721,6 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
748 721
749 else 722 else
750 { 723 {
751
752 InventoryItemBase uri = (InventoryItemBase) InventoryNode; 724 InventoryItemBase uri = (InventoryItemBase) InventoryNode;
753 InventoryItemBase xml = null; 725 InventoryItemBase xml = null;
754 726
@@ -756,7 +728,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
756 { 728 {
757 Rest.Log.DebugFormat("{0} {1}: Request should not contain any folders <{2}>", 729 Rest.Log.DebugFormat("{0} {1}: Request should not contain any folders <{2}>",
758 MsgId, rdata.method, rdata.path); 730 MsgId, rdata.method, rdata.path);
759 rdata.Fail(Rest.HttpStatusCodeBadRequest, 731 rdata.Fail(Rest.HttpStatusCodeBadRequest,
760 Rest.HttpStatusDescBadRequest+": folder is not allowed"); 732 Rest.HttpStatusDescBadRequest+": folder is not allowed");
761 } 733 }
762 734
@@ -764,12 +736,12 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
764 { 736 {
765 Rest.Log.DebugFormat("{0} {1}: Entity contains too many items <{2}>", 737 Rest.Log.DebugFormat("{0} {1}: Entity contains too many items <{2}>",
766 MsgId, rdata.method, rdata.path); 738 MsgId, rdata.method, rdata.path);
767 rdata.Fail(Rest.HttpStatusCodeBadRequest, 739 rdata.Fail(Rest.HttpStatusCodeBadRequest,
768 Rest.HttpStatusDescBadRequest+": too may items"); 740 Rest.HttpStatusDescBadRequest+": too may items");
769 } 741 }
770 742
771 xml = entity.Items[0]; 743 xml = entity.Items[0];
772 744
773 if (xml.ID == LLUUID.Zero) 745 if (xml.ID == LLUUID.Zero)
774 { 746 {
775 xml.ID = LLUUID.Random(); 747 xml.ID = LLUUID.Random();
@@ -786,12 +758,10 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
786 // Add the new item to the inventory 758 // Add the new item to the inventory
787 759
788 Rest.InventoryServices.AddItem(xml); 760 Rest.InventoryServices.AddItem(xml);
789
790 } 761 }
791 762
792 rdata.Complete(); 763 rdata.Complete();
793 rdata.Respond("Inventory " + rdata.method + ": Normal completion"); 764 rdata.Respond("Inventory " + rdata.method + ": Normal completion");
794
795 } 765 }
796 766
797 /// <summary> 767 /// <summary>
@@ -804,7 +774,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
804 /// 774 ///
805 /// Folders are deleted by moving them to another folder and then 775 /// Folders are deleted by moving them to another folder and then
806 /// purging that folder. We'll do that by creating a temporary 776 /// purging that folder. We'll do that by creating a temporary
807 /// sub-folder in the TrashCan and purging that folder's 777 /// sub-folder in the TrashCan and purging that folder's
808 /// contents. If we can't can it, we don't delete it... 778 /// contents. If we can't can it, we don't delete it...
809 /// So, if no trashcan is available, the request does nothing. 779 /// So, if no trashcan is available, the request does nothing.
810 /// Items are summarily deleted. 780 /// Items are summarily deleted.
@@ -816,13 +786,11 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
816 786
817 private void DoDelete(InventoryRequestData rdata) 787 private void DoDelete(InventoryRequestData rdata)
818 { 788 {
819
820 Object InventoryNode = getInventoryNode(rdata, rdata.root, 1); 789 Object InventoryNode = getInventoryNode(rdata, rdata.root, 1);
821 790
822 if (typeof(InventoryFolderBase) == InventoryNode.GetType() || 791 if (typeof(InventoryFolderBase) == InventoryNode.GetType() ||
823 typeof(InventoryFolderImpl) == InventoryNode.GetType()) 792 typeof(InventoryFolderImpl) == InventoryNode.GetType())
824 { 793 {
825
826 InventoryFolderBase TrashCan = GetTrashCan(rdata); 794 InventoryFolderBase TrashCan = GetTrashCan(rdata);
827 795
828 InventoryFolderBase folder = (InventoryFolderBase) InventoryNode; 796 InventoryFolderBase folder = (InventoryFolderBase) InventoryNode;
@@ -831,7 +799,6 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
831 folder.ParentID = TrashCan.ID; 799 folder.ParentID = TrashCan.ID;
832 Rest.InventoryServices.MoveFolder(folder); 800 Rest.InventoryServices.MoveFolder(folder);
833 Rest.InventoryServices.PurgeFolder(TrashCan); 801 Rest.InventoryServices.PurgeFolder(TrashCan);
834
835 } 802 }
836 803
837 // Deleting items is much more straight forward. 804 // Deleting items is much more straight forward.
@@ -846,18 +813,17 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
846 813
847 rdata.Complete(); 814 rdata.Complete();
848 rdata.Respond("Inventory " + rdata.method + ": Normal completion"); 815 rdata.Respond("Inventory " + rdata.method + ": Normal completion");
849
850 } 816 }
851 817
852#endregion method-specific processing 818 #endregion method-specific processing
853 819
854 /// <summary> 820 /// <summary>
855 /// This method is called to obtain the OpenSim inventory object identified 821 /// This method is called to obtain the OpenSim inventory object identified
856 /// by the supplied URI. This may be either an Item or a Folder, so a suitably 822 /// by the supplied URI. This may be either an Item or a Folder, so a suitably
857 /// ambiguous return type is employed (Object). This method recurses as 823 /// ambiguous return type is employed (Object). This method recurses as
858 /// necessary to process the designated hierarchy. 824 /// necessary to process the designated hierarchy.
859 /// 825 ///
860 /// If we reach the end of the URI then we return the contextural folder to 826 /// If we reach the end of the URI then we return the contextural folder to
861 /// our caller. 827 /// our caller.
862 /// 828 ///
863 /// If we are not yet at the end of the URI we attempt to find a child folder 829 /// If we are not yet at the end of the URI we attempt to find a child folder
@@ -869,8 +835,8 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
869 /// Otherwise we fail the request on the ground of an invalid URI. 835 /// Otherwise we fail the request on the ground of an invalid URI.
870 /// 836 ///
871 /// <note> 837 /// <note>
872 /// This mechanism cannot detect the case where duplicate subtrees satisfy a 838 /// This mechanism cannot detect the case where duplicate subtrees satisfy a
873 /// request. In such a case the 1st element gets processed. If this is a 839 /// request. In such a case the 1st element gets processed. If this is a
874 /// problem, then UUID should be used to identify the end-node. This is basic 840 /// problem, then UUID should be used to identify the end-node. This is basic
875 /// premise of normal inventory processing. The name is an informational, and 841 /// premise of normal inventory processing. The name is an informational, and
876 /// not a defining, attribute. 842 /// not a defining, attribute.
@@ -880,7 +846,6 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
880 846
881 private Object getInventoryNode(InventoryRequestData rdata, InventoryFolderBase folder, int pi) 847 private Object getInventoryNode(InventoryRequestData rdata, InventoryFolderBase folder, int pi)
882 { 848 {
883
884 Rest.Log.DebugFormat("{0} Searching folder {1} {2} [{3}]", MsgId, folder.ID, folder.Name, pi); 849 Rest.Log.DebugFormat("{0} Searching folder {1} {2} [{3}]", MsgId, folder.ID, folder.Name, pi);
885 850
886 // We have just run off the end of the parameter sequence 851 // We have just run off the end of the parameter sequence
@@ -894,17 +859,19 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
894 // get us there. 859 // get us there.
895 860
896 if (rdata.folders != null) 861 if (rdata.folders != null)
862 {
897 foreach (InventoryFolderBase f in rdata.folders) 863 foreach (InventoryFolderBase f in rdata.folders)
898 { 864 {
899 // Look for the present node in the directory list 865 // Look for the present node in the directory list
900 if (f.ParentID == folder.ID && 866 if (f.ParentID == folder.ID &&
901 (f.Name == rdata.parameters[pi] || 867 (f.Name == rdata.parameters[pi] ||
902 f.ID.ToString() == rdata.parameters[pi])) 868 f.ID.ToString() == rdata.parameters[pi]))
903 { 869 {
904 return getInventoryNode(rdata, f, pi+1); 870 return getInventoryNode(rdata, f, pi+1);
905 } 871 }
906 } 872 }
907 873 }
874
908 // No folders that match. Perhaps this parameter identifies an item? If 875 // No folders that match. Perhaps this parameter identifies an item? If
909 // it does, then it MUST also be the last name in the sequence. 876 // it does, then it MUST also be the last name in the sequence.
910 877
@@ -916,7 +883,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
916 InventoryItemBase li = null; 883 InventoryItemBase li = null;
917 foreach (InventoryItemBase i in rdata.items) 884 foreach (InventoryItemBase i in rdata.items)
918 { 885 {
919 if (i.Folder == folder.ID && 886 if (i.Folder == folder.ID &&
920 (i.Name == rdata.parameters[pi] || 887 (i.Name == rdata.parameters[pi] ||
921 i.ID.ToString() == rdata.parameters[pi])) 888 i.ID.ToString() == rdata.parameters[pi]))
922 { 889 {
@@ -944,11 +911,10 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
944 rdata.Fail(Rest.HttpStatusCodeNotFound, Rest.HttpStatusDescNotFound+": resource "+rdata.path+" not found"); 911 rdata.Fail(Rest.HttpStatusCodeNotFound, Rest.HttpStatusDescNotFound+": resource "+rdata.path+" not found");
945 912
946 return null; /* Never reached */ 913 return null; /* Never reached */
947
948 } 914 }
949 915
950 /// <summary> 916 /// <summary>
951 /// This routine traverse the inventory's structure until the end-point identified 917 /// This routine traverse the inventory's structure until the end-point identified
952 /// in the URI is reached, the remainder of the inventory (if any) is then formatted 918 /// in the URI is reached, the remainder of the inventory (if any) is then formatted
953 /// and returned to the requestor. 919 /// and returned to the requestor.
954 /// 920 ///
@@ -961,14 +927,13 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
961 927
962 private void traverseInventory(InventoryRequestData rdata, InventoryFolderBase folder, int pi) 928 private void traverseInventory(InventoryRequestData rdata, InventoryFolderBase folder, int pi)
963 { 929 {
964
965 Rest.Log.DebugFormat("{0} Folder : {1} {2} [{3}]", MsgId, folder.ID, folder.Name, pi); 930 Rest.Log.DebugFormat("{0} Folder : {1} {2} [{3}]", MsgId, folder.ID, folder.Name, pi);
966 931
967 if (rdata.folders != null) 932 if (rdata.folders != null)
968 { 933 {
969 foreach (InventoryFolderBase f in rdata.folders) 934 foreach (InventoryFolderBase f in rdata.folders)
970 { 935 {
971 if (f.ParentID == folder.ID && 936 if (f.ParentID == folder.ID &&
972 (f.Name == rdata.parameters[pi] || 937 (f.Name == rdata.parameters[pi] ||
973 f.ID.ToString() == rdata.parameters[pi])) 938 f.ID.ToString() == rdata.parameters[pi]))
974 { 939 {
@@ -991,13 +956,13 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
991 { 956 {
992 foreach (InventoryItemBase i in rdata.items) 957 foreach (InventoryItemBase i in rdata.items)
993 { 958 {
994 if (i.Folder == folder.ID && 959 if (i.Folder == folder.ID &&
995 (i.Name == rdata.parameters[pi] || 960 (i.Name == rdata.parameters[pi] ||
996 i.ID.ToString() == rdata.parameters[pi])) 961 i.ID.ToString() == rdata.parameters[pi]))
997 { 962 {
998 // Fetching an Item has a special significance. In this 963 // Fetching an Item has a special significance. In this
999 // case we also want to fetch the associated asset. 964 // case we also want to fetch the associated asset.
1000 // To make it interesting, we'll d this via redirection. 965 // To make it interesting, we'll d this via redirection.
1001 string asseturl = "http://" + rdata.hostname + ":" + rdata.port + 966 string asseturl = "http://" + rdata.hostname + ":" + rdata.port +
1002 "/admin/assets" + Rest.UrlPathSeparator + i.AssetID.ToString(); 967 "/admin/assets" + Rest.UrlPathSeparator + i.AssetID.ToString();
1003 rdata.Redirect(asseturl,Rest.PERMANENT); 968 rdata.Redirect(asseturl,Rest.PERMANENT);
@@ -1007,10 +972,9 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
1007 } 972 }
1008 } 973 }
1009 974
1010 Rest.Log.DebugFormat("{0} Inventory does not contain item/folder: <{1}>", 975 Rest.Log.DebugFormat("{0} Inventory does not contain item/folder: <{1}>",
1011 MsgId, rdata.path); 976 MsgId, rdata.path);
1012 rdata.Fail(Rest.HttpStatusCodeNotFound,Rest.HttpStatusDescNotFound+": no such item/folder"); 977 rdata.Fail(Rest.HttpStatusCodeNotFound,Rest.HttpStatusDescNotFound+": no such item/folder");
1013
1014 } 978 }
1015 979
1016 /// <summary> 980 /// <summary>
@@ -1023,7 +987,6 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
1023 987
1024 private void formatInventory(InventoryRequestData rdata, InventoryFolderBase folder, string indent) 988 private void formatInventory(InventoryRequestData rdata, InventoryFolderBase folder, string indent)
1025 { 989 {
1026
1027 if (Rest.DEBUG) 990 if (Rest.DEBUG)
1028 { 991 {
1029 Rest.Log.DebugFormat("{0} Folder : {1} {2} {3}", MsgId, folder.ID, indent, folder.Name); 992 Rest.Log.DebugFormat("{0} Folder : {1} {2} {3}", MsgId, folder.ID, indent, folder.Name);
@@ -1064,7 +1027,6 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
1064 // End folder item 1027 // End folder item
1065 1028
1066 rdata.writer.WriteEndElement(); 1029 rdata.writer.WriteEndElement();
1067
1068 } 1030 }
1069 1031
1070 /// <summary> 1032 /// <summary>
@@ -1073,7 +1035,6 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
1073 1035
1074 private void formatItem(InventoryRequestData rdata, InventoryItemBase i, string indent) 1036 private void formatItem(InventoryRequestData rdata, InventoryItemBase i, string indent)
1075 { 1037 {
1076
1077 Rest.Log.DebugFormat("{0} Item : {1} {2} {3}", MsgId, i.ID, indent, i.Name); 1038 Rest.Log.DebugFormat("{0} Item : {1} {2} {3}", MsgId, i.ID, indent, i.Name);
1078 1039
1079 rdata.writer.WriteStartElement(String.Empty,"Item",String.Empty); 1040 rdata.writer.WriteStartElement(String.Empty,"Item",String.Empty);
@@ -1102,11 +1063,10 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
1102 rdata.writer.WriteElementString("Asset",i.AssetID.ToString()); 1063 rdata.writer.WriteElementString("Asset",i.AssetID.ToString());
1103 1064
1104 rdata.writer.WriteEndElement(); 1065 rdata.writer.WriteEndElement();
1105
1106 } 1066 }
1107 1067
1108 /// <summary> 1068 /// <summary>
1109 /// This method creates a "trashcan" folder to support folder and item 1069 /// This method creates a "trashcan" folder to support folder and item
1110 /// deletions by this interface. The xisting trash folder is found and 1070 /// deletions by this interface. The xisting trash folder is found and
1111 /// this folder is created within it. It is called "tmp" to indicate to 1071 /// this folder is created within it. It is called "tmp" to indicate to
1112 /// the client that it is OK to delete this folder. The REST interface 1072 /// the client that it is OK to delete this folder. The REST interface
@@ -1117,7 +1077,6 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
1117 1077
1118 private InventoryFolderBase GetTrashCan(InventoryRequestData rdata) 1078 private InventoryFolderBase GetTrashCan(InventoryRequestData rdata)
1119 { 1079 {
1120
1121 InventoryFolderBase TrashCan = null; 1080 InventoryFolderBase TrashCan = null;
1122 1081
1123 foreach (InventoryFolderBase f in rdata.folders) 1082 foreach (InventoryFolderBase f in rdata.folders)
@@ -1144,16 +1103,15 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
1144 } 1103 }
1145 } 1104 }
1146 } 1105 }
1147 1106
1148 if (TrashCan == null) 1107 if (TrashCan == null)
1149 { 1108 {
1150 Rest.Log.DebugFormat("{0} No Trash Can available", MsgId); 1109 Rest.Log.DebugFormat("{0} No Trash Can available", MsgId);
1151 rdata.Fail(Rest.HttpStatusCodeServerError, 1110 rdata.Fail(Rest.HttpStatusCodeServerError,
1152 Rest.HttpStatusDescServerError+": unable to create trash can"); 1111 Rest.HttpStatusDescServerError+": unable to create trash can");
1153 } 1112 }
1154 1113
1155 return TrashCan; 1114 return TrashCan;
1156
1157 } 1115 }
1158 1116
1159 /// <summary> 1117 /// <summary>
@@ -1163,11 +1121,11 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
1163 1121
1164 private bool FolderHasChanged(InventoryFolderBase newf, InventoryFolderBase oldf) 1122 private bool FolderHasChanged(InventoryFolderBase newf, InventoryFolderBase oldf)
1165 { 1123 {
1166 return ( newf.Name != oldf.Name 1124 return (newf.Name != oldf.Name
1167 || newf.ParentID != oldf.ParentID 1125 || newf.ParentID != oldf.ParentID
1168 || newf.Owner != oldf.Owner 1126 || newf.Owner != oldf.Owner
1169 || newf.Type != oldf.Type 1127 || newf.Type != oldf.Type
1170 || newf.Version != oldf.Version 1128 || newf.Version != oldf.Version
1171 ); 1129 );
1172 } 1130 }
1173 1131
@@ -1178,24 +1136,24 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
1178 1136
1179 private bool ItemHasChanged(InventoryItemBase newf, InventoryItemBase oldf) 1137 private bool ItemHasChanged(InventoryItemBase newf, InventoryItemBase oldf)
1180 { 1138 {
1181 return ( newf.Name != oldf.Name 1139 return (newf.Name != oldf.Name
1182 || newf.Folder != oldf.Description 1140 || newf.Folder != oldf.Description
1183 || newf.Description != oldf.Description 1141 || newf.Description != oldf.Description
1184 || newf.Owner != oldf.Owner 1142 || newf.Owner != oldf.Owner
1185 || newf.Creator != oldf.Creator 1143 || newf.Creator != oldf.Creator
1186 || newf.AssetID != oldf.AssetID 1144 || newf.AssetID != oldf.AssetID
1187 || newf.GroupID != oldf.GroupID 1145 || newf.GroupID != oldf.GroupID
1188 || newf.GroupOwned != oldf.GroupOwned 1146 || newf.GroupOwned != oldf.GroupOwned
1189 || newf.InvType != oldf.InvType 1147 || newf.InvType != oldf.InvType
1190 || newf.AssetType != oldf.AssetType 1148 || newf.AssetType != oldf.AssetType
1191 ); 1149 );
1192 } 1150 }
1193 1151
1194 /// <summary> 1152 /// <summary>
1195 /// This method is called by PUT and POST to create an XmlInventoryCollection 1153 /// This method is called by PUT and POST to create an XmlInventoryCollection
1196 /// instance that reflects the content of the entity supplied on the request. 1154 /// instance that reflects the content of the entity supplied on the request.
1197 /// Any elements in the completed collection whose UUID is zero, are 1155 /// Any elements in the completed collection whose UUID is zero, are
1198 /// considered to be located relative to the end-point identified int he 1156 /// considered to be located relative to the end-point identified int he
1199 /// URI. In this way, an entire sub-tree can be conveyed in a single REST 1157 /// URI. In this way, an entire sub-tree can be conveyed in a single REST
1200 /// PUT or POST request. 1158 /// PUT or POST request.
1201 /// 1159 ///
@@ -1203,26 +1161,24 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
1203 /// has an entity, it is more completely initialized. thus, if no entity was 1161 /// has an entity, it is more completely initialized. thus, if no entity was
1204 /// provided the collection is valid, but empty. 1162 /// provided the collection is valid, but empty.
1205 /// 1163 ///
1206 /// The entity is then scanned and each tag is processed to produce the 1164 /// The entity is then scanned and each tag is processed to produce the
1207 /// appropriate inventory elements. At the end f the scan, teh XmlInventoryCollection 1165 /// appropriate inventory elements. At the end f the scan, teh XmlInventoryCollection
1208 /// will reflect the subtree described by the entity. 1166 /// will reflect the subtree described by the entity.
1209 /// 1167 ///
1210 /// This is a very flexible mechanism, the entity may contain arbitrary, 1168 /// This is a very flexible mechanism, the entity may contain arbitrary,
1211 /// discontiguous tree fragments, or may contain single element. The caller is 1169 /// discontiguous tree fragments, or may contain single element. The caller is
1212 /// responsible for integrating this collection (and ensuring that any 1170 /// responsible for integrating this collection (and ensuring that any
1213 /// missing parent IDs are resolved). 1171 /// missing parent IDs are resolved).
1214 /// </summary> 1172 /// </summary>
1215 1173
1216 internal XmlInventoryCollection ReconstituteEntity(InventoryRequestData rdata) 1174 internal XmlInventoryCollection ReconstituteEntity(InventoryRequestData rdata)
1217 { 1175 {
1218
1219 Rest.Log.DebugFormat("{0} Reconstituting entity", MsgId); 1176 Rest.Log.DebugFormat("{0} Reconstituting entity", MsgId);
1220 1177
1221 XmlInventoryCollection ic = new XmlInventoryCollection(); 1178 XmlInventoryCollection ic = new XmlInventoryCollection();
1222 1179
1223 if (rdata.request.HasEntityBody) 1180 if (rdata.request.HasEntityBody)
1224 { 1181 {
1225
1226 Rest.Log.DebugFormat("{0} Entity present", MsgId); 1182 Rest.Log.DebugFormat("{0} Entity present", MsgId);
1227 1183
1228 ic.init(rdata); 1184 ic.init(rdata);
@@ -1318,7 +1274,6 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
1318 Rest.Log.WarnFormat("{0} Unexpected XML parsing error: {1}", MsgId, e.Message); 1274 Rest.Log.WarnFormat("{0} Unexpected XML parsing error: {1}", MsgId, e.Message);
1319 throw e; 1275 throw e;
1320 } 1276 }
1321
1322 } 1277 }
1323 else 1278 else
1324 { 1279 {
@@ -1334,14 +1289,13 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
1334 } 1289 }
1335 1290
1336 return ic; 1291 return ic;
1337
1338 } 1292 }
1339 1293
1340 /// <summary> 1294 /// <summary>
1341 /// This method creates an inventory Folder from the 1295 /// This method creates an inventory Folder from the
1342 /// information supplied in the request's entity. 1296 /// information supplied in the request's entity.
1343 /// A folder instance is created and initialized to reflect 1297 /// A folder instance is created and initialized to reflect
1344 /// default values. These values are then overridden 1298 /// default values. These values are then overridden
1345 /// by information supplied in the entity. 1299 /// by information supplied in the entity.
1346 /// If context was not explicitly provided, then the 1300 /// If context was not explicitly provided, then the
1347 /// appropriate ID values are determined. 1301 /// appropriate ID values are determined.
@@ -1349,7 +1303,6 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
1349 1303
1350 private void CollectFolder(XmlInventoryCollection ic) 1304 private void CollectFolder(XmlInventoryCollection ic)
1351 { 1305 {
1352
1353 Rest.Log.DebugFormat("{0} Interpret folder element", MsgId); 1306 Rest.Log.DebugFormat("{0} Interpret folder element", MsgId);
1354 1307
1355 InventoryFolderBase result = new InventoryFolderBase(); 1308 InventoryFolderBase result = new InventoryFolderBase();
@@ -1389,7 +1342,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
1389 result.Version = UInt16.Parse(ic.xml.Value); 1342 result.Version = UInt16.Parse(ic.xml.Value);
1390 break; 1343 break;
1391 default : 1344 default :
1392 Rest.Log.DebugFormat("{0} Folder: unrecognized attribute: {1}:{2}", 1345 Rest.Log.DebugFormat("{0} Folder: unrecognized attribute: {1}:{2}",
1393 MsgId, ic.xml.Name, ic.xml.Value); 1346 MsgId, ic.xml.Name, ic.xml.Value);
1394 ic.Fail(Rest.HttpStatusCodeBadRequest, 1347 ic.Fail(Rest.HttpStatusCodeBadRequest,
1395 Rest.HttpStatusDescBadRequest+": unrecognized attribute"); 1348 Rest.HttpStatusDescBadRequest+": unrecognized attribute");
@@ -1411,7 +1364,6 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
1411 } 1364 }
1412 else 1365 else
1413 { 1366 {
1414
1415 bool found = false; 1367 bool found = false;
1416 1368
1417 foreach (InventoryFolderBase parent in ic.rdata.folders) 1369 foreach (InventoryFolderBase parent in ic.rdata.folders)
@@ -1425,7 +1377,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
1425 1377
1426 if (!found) 1378 if (!found)
1427 { 1379 {
1428 Rest.Log.ErrorFormat("{0} Invalid parent ID ({1}) in folder {2}", 1380 Rest.Log.ErrorFormat("{0} Invalid parent ID ({1}) in folder {2}",
1429 MsgId, ic.Item.Folder, result.ID); 1381 MsgId, ic.Item.Folder, result.ID);
1430 ic.Fail(Rest.HttpStatusCodeBadRequest, 1382 ic.Fail(Rest.HttpStatusCodeBadRequest,
1431 Rest.HttpStatusDescBadRequest+": invalid parent"); 1383 Rest.HttpStatusDescBadRequest+": invalid parent");
@@ -1445,15 +1397,14 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
1445 // obsolete as a consequence. 1397 // obsolete as a consequence.
1446 1398
1447 ic.Push(result); 1399 ic.Push(result);
1448
1449 } 1400 }
1450 1401
1451 /// <summary> 1402 /// <summary>
1452 /// This method is called to handle the construction of an Item 1403 /// This method is called to handle the construction of an Item
1453 /// instance from the supplied request entity. It is called 1404 /// instance from the supplied request entity. It is called
1454 /// whenever an Item start tag is detected. 1405 /// whenever an Item start tag is detected.
1455 /// An instance of an Item is created and initialized to default 1406 /// An instance of an Item is created and initialized to default
1456 /// values. These values are then overridden from values supplied 1407 /// values. These values are then overridden from values supplied
1457 /// as attributes to the Item element. 1408 /// as attributes to the Item element.
1458 /// This item is then stored in the XmlInventoryCollection and 1409 /// This item is then stored in the XmlInventoryCollection and
1459 /// will be verified by Validate. 1410 /// will be verified by Validate.
@@ -1463,7 +1414,6 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
1463 1414
1464 private void CollectItem(XmlInventoryCollection ic) 1415 private void CollectItem(XmlInventoryCollection ic)
1465 { 1416 {
1466
1467 Rest.Log.DebugFormat("{0} Interpret item element", MsgId); 1417 Rest.Log.DebugFormat("{0} Interpret item element", MsgId);
1468 1418
1469 InventoryItemBase result = new InventoryItemBase(); 1419 InventoryItemBase result = new InventoryItemBase();
@@ -1484,7 +1434,6 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
1484 { 1434 {
1485 for (int i = 0; i < ic.xml.AttributeCount; i++) 1435 for (int i = 0; i < ic.xml.AttributeCount; i++)
1486 { 1436 {
1487
1488 ic.xml.MoveToAttribute(i); 1437 ic.xml.MoveToAttribute(i);
1489 1438
1490 switch (ic.xml.Name) 1439 switch (ic.xml.Name)
@@ -1533,37 +1482,36 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
1533 break; 1482 break;
1534 1483
1535 default : 1484 default :
1536 Rest.Log.DebugFormat("{0} Item: Unrecognized attribute: {1}:{2}", 1485 Rest.Log.DebugFormat("{0} Item: Unrecognized attribute: {1}:{2}",
1537 MsgId, ic.xml.Name, ic.xml.Value); 1486 MsgId, ic.xml.Name, ic.xml.Value);
1538 ic.Fail(Rest.HttpStatusCodeBadRequest, 1487 ic.Fail(Rest.HttpStatusCodeBadRequest,
1539 Rest.HttpStatusDescBadRequest+": unrecognized attribute"); 1488 Rest.HttpStatusDescBadRequest+": unrecognized attribute");
1540 break; 1489 break;
1541 } 1490 }
1542 } 1491 }
1543 } 1492 }
1544 1493
1545 ic.xml.MoveToElement(); 1494 ic.xml.MoveToElement();
1546 1495
1547 ic.Push(result); 1496 ic.Push(result);
1548
1549 } 1497 }
1550 1498
1551 /// <summary> 1499 /// <summary>
1552 /// This method assembles an asset instance from the 1500 /// This method assembles an asset instance from the
1553 /// information supplied in the request's entity. It is 1501 /// information supplied in the request's entity. It is
1554 /// called as a result of detecting a start tag for a 1502 /// called as a result of detecting a start tag for a
1555 /// type of Asset. 1503 /// type of Asset.
1556 /// The information is collected locally, and an asset 1504 /// The information is collected locally, and an asset
1557 /// instance is created only if the basic XML parsing 1505 /// instance is created only if the basic XML parsing
1558 /// completes successfully. 1506 /// completes successfully.
1559 /// Default values for all parts of the asset are 1507 /// Default values for all parts of the asset are
1560 /// established before overriding them from the supplied 1508 /// established before overriding them from the supplied
1561 /// XML. 1509 /// XML.
1562 /// If an asset has inline=true as an attribute, then 1510 /// If an asset has inline=true as an attribute, then
1563 /// the element contains the data representing the 1511 /// the element contains the data representing the
1564 /// asset. This is saved as the data component. 1512 /// asset. This is saved as the data component.
1565 /// inline=false means that the element's payload is 1513 /// inline=false means that the element's payload is
1566 /// simply the UUID of the asset referenced by the 1514 /// simply the UUID of the asset referenced by the
1567 /// item being constructed. 1515 /// item being constructed.
1568 /// An asset, if created is stored in the 1516 /// An asset, if created is stored in the
1569 /// XmlInventoryCollection 1517 /// XmlInventoryCollection
@@ -1624,7 +1572,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
1624 break; 1572 break;
1625 1573
1626 default : 1574 default :
1627 Rest.Log.DebugFormat("{0} Asset: Unrecognized attribute: {1}:{2}", 1575 Rest.Log.DebugFormat("{0} Asset: Unrecognized attribute: {1}:{2}",
1628 MsgId, ic.xml.Name, ic.xml.Value); 1576 MsgId, ic.xml.Name, ic.xml.Value);
1629 ic.Fail(Rest.HttpStatusCodeBadRequest, 1577 ic.Fail(Rest.HttpStatusCodeBadRequest,
1630 Rest.HttpStatusDescBadRequest); 1578 Rest.HttpStatusDescBadRequest);
@@ -1637,7 +1585,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
1637 1585
1638 // If this is a reference to an existing asset, just store the 1586 // If this is a reference to an existing asset, just store the
1639 // asset ID into the item. 1587 // asset ID into the item.
1640 1588
1641 if (!inline) 1589 if (!inline)
1642 { 1590 {
1643 if (ic.Item != null) 1591 if (ic.Item != null)
@@ -1653,13 +1601,12 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
1653 } 1601 }
1654 } 1602 }
1655 1603
1656 // Otherwise, generate an asset ID, store that into the item, and 1604 // Otherwise, generate an asset ID, store that into the item, and
1657 // create an entry in the asset list for the inlined asset. But 1605 // create an entry in the asset list for the inlined asset. But
1658 // only if the size is non-zero. 1606 // only if the size is non-zero.
1659 1607
1660 else 1608 else
1661 { 1609 {
1662
1663 string b64string = null; 1610 string b64string = null;
1664 1611
1665 // Generate a UUID of none were given, and generally none should 1612 // Generate a UUID of none were given, and generally none should
@@ -1672,17 +1619,17 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
1672 1619
1673 // Create AssetBase entity to hold the inlined asset 1620 // Create AssetBase entity to hold the inlined asset
1674 1621
1675 asset = new AssetBase(uuid, name); 1622 asset = new AssetBase(uuid, name);
1676 1623
1677 asset.Description = desc; 1624 asset.Description = desc;
1678 asset.Type = type; // type == 0 == texture 1625 asset.Type = type; // type == 0 == texture
1679 asset.Local = local; 1626 asset.Local = local;
1680 asset.Temporary = temp; 1627 asset.Temporary = temp;
1681 1628
1682 b64string = ic.xml.ReadElementContentAsString(); 1629 b64string = ic.xml.ReadElementContentAsString();
1683 1630
1684 Rest.Log.DebugFormat("{0} Data length is {1}", MsgId, b64string.Length); 1631 Rest.Log.DebugFormat("{0} Data length is {1}", MsgId, b64string.Length);
1685 Rest.Log.DebugFormat("{0} Data content starts with: \n\t<{1}>", MsgId, 1632 Rest.Log.DebugFormat("{0} Data content starts with: \n\t<{1}>", MsgId,
1686 b64string.Substring(0, b64string.Length > 132 ? 132 : b64string.Length)); 1633 b64string.Substring(0, b64string.Length > 132 ? 132 : b64string.Length));
1687 1634
1688 asset.Data = Convert.FromBase64String(b64string); 1635 asset.Data = Convert.FromBase64String(b64string);
@@ -1701,22 +1648,19 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
1701 { 1648 {
1702 ic.Item.AssetID = uuid; 1649 ic.Item.AssetID = uuid;
1703 } 1650 }
1704
1705 } 1651 }
1706 1652
1707 ic.Push(asset); 1653 ic.Push(asset);
1708
1709 } 1654 }
1710 1655
1711 /// <summary> 1656 /// <summary>
1712 /// Store any permissions information provided by the request. 1657 /// Store any permissions information provided by the request.
1713 /// This overrides the default permissions set when the 1658 /// This overrides the default permissions set when the
1714 /// XmlInventoryCollection object was created. 1659 /// XmlInventoryCollection object was created.
1715 /// </summary> 1660 /// </summary>
1716 1661
1717 private void CollectPermissions(XmlInventoryCollection ic) 1662 private void CollectPermissions(XmlInventoryCollection ic)
1718 { 1663 {
1719
1720 if (ic.xml.HasAttributes) 1664 if (ic.xml.HasAttributes)
1721 { 1665 {
1722 for (int i = 0; i < ic.xml.AttributeCount; i++) 1666 for (int i = 0; i < ic.xml.AttributeCount; i++)
@@ -1747,7 +1691,6 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
1747 } 1691 }
1748 1692
1749 ic.xml.MoveToElement(); 1693 ic.xml.MoveToElement();
1750
1751 } 1694 }
1752 1695
1753 /// <summary> 1696 /// <summary>
@@ -1762,7 +1705,6 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
1762 1705
1763 private void Validate(XmlInventoryCollection ic) 1706 private void Validate(XmlInventoryCollection ic)
1764 { 1707 {
1765
1766 // There really should be an item present if we've 1708 // There really should be an item present if we've
1767 // called validate. So fail if there is not. 1709 // called validate. So fail if there is not.
1768 1710
@@ -1772,7 +1714,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
1772 ic.Fail(Rest.HttpStatusCodeBadRequest, 1714 ic.Fail(Rest.HttpStatusCodeBadRequest,
1773 Rest.HttpStatusDescBadRequest+": request parse error"); 1715 Rest.HttpStatusDescBadRequest+": request parse error");
1774 } 1716 }
1775 1717
1776 // Every item is required to have a name (via REST anyway) 1718 // Every item is required to have a name (via REST anyway)
1777 1719
1778 if (ic.Item.Name == String.Empty) 1720 if (ic.Item.Name == String.Empty)
@@ -1781,19 +1723,17 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
1781 ic.Fail(Rest.HttpStatusCodeBadRequest, 1723 ic.Fail(Rest.HttpStatusCodeBadRequest,
1782 Rest.HttpStatusDescBadRequest+": item name required"); 1724 Rest.HttpStatusDescBadRequest+": item name required");
1783 } 1725 }
1784 1726
1785 // An item MUST have an asset ID. AssetID should never be zero 1727 // An item MUST have an asset ID. AssetID should never be zero
1786 // here. It should always get set from the information stored 1728 // here. It should always get set from the information stored
1787 // when the Asset element was processed. 1729 // when the Asset element was processed.
1788 1730
1789 if (ic.Item.AssetID == LLUUID.Zero) 1731 if (ic.Item.AssetID == LLUUID.Zero)
1790 { 1732 {
1791
1792 Rest.Log.ErrorFormat("{0} Unable to complete request", MsgId); 1733 Rest.Log.ErrorFormat("{0} Unable to complete request", MsgId);
1793 Rest.Log.InfoFormat("{0} Asset information is missing", MsgId); 1734 Rest.Log.InfoFormat("{0} Asset information is missing", MsgId);
1794 ic.Fail(Rest.HttpStatusCodeBadRequest, 1735 ic.Fail(Rest.HttpStatusCodeBadRequest,
1795 Rest.HttpStatusDescBadRequest+": asset information required"); 1736 Rest.HttpStatusDescBadRequest+": asset information required");
1796
1797 } 1737 }
1798 1738
1799 // If the item is new, then assign it an ID 1739 // If the item is new, then assign it an ID
@@ -1806,19 +1746,18 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
1806 // If the context is being implied, obtain the current 1746 // If the context is being implied, obtain the current
1807 // folder item's ID. If it was specified explicitly, make 1747 // folder item's ID. If it was specified explicitly, make
1808 // sure that theparent folder exists. 1748 // sure that theparent folder exists.
1809 1749
1810 if (ic.Item.Folder == LLUUID.Zero) 1750 if (ic.Item.Folder == LLUUID.Zero)
1811 { 1751 {
1812 ic.Item.Folder = ic.Parent(); 1752 ic.Item.Folder = ic.Parent();
1813 } 1753 }
1814 else 1754 else
1815 { 1755 {
1816
1817 bool found = false; 1756 bool found = false;
1818 1757
1819 foreach (InventoryFolderBase parent in ic.rdata.folders) 1758 foreach (InventoryFolderBase parent in ic.rdata.folders)
1820 { 1759 {
1821 if ( parent.ID == ic.Item.Folder ) 1760 if (parent.ID == ic.Item.Folder)
1822 { 1761 {
1823 found = true; 1762 found = true;
1824 break; 1763 break;
@@ -1827,12 +1766,11 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
1827 1766
1828 if (!found) 1767 if (!found)
1829 { 1768 {
1830 Rest.Log.ErrorFormat("{0} Invalid parent ID ({1}) in item {2}", 1769 Rest.Log.ErrorFormat("{0} Invalid parent ID ({1}) in item {2}",
1831 MsgId, ic.Item.Folder, ic.Item.ID); 1770 MsgId, ic.Item.Folder, ic.Item.ID);
1832 ic.Fail(Rest.HttpStatusCodeBadRequest, 1771 ic.Fail(Rest.HttpStatusCodeBadRequest,
1833 Rest.HttpStatusDescBadRequest+": parent information required"); 1772 Rest.HttpStatusDescBadRequest+": parent information required");
1834 } 1773 }
1835
1836 } 1774 }
1837 1775
1838 // If this is an inline asset being constructed in the context 1776 // If this is an inline asset being constructed in the context
@@ -1854,13 +1792,12 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
1854 ic.Item.NextPermissions = ic.NextPermissions; 1792 ic.Item.NextPermissions = ic.NextPermissions;
1855 1793
1856 // If no type was specified for this item, we can attempt to 1794 // If no type was specified for this item, we can attempt to
1857 // infer something from the file type maybe. This is NOT as 1795 // infer something from the file type maybe. This is NOT as
1858 // good as having type be specified in the XML. 1796 // good as having type be specified in the XML.
1859 1797
1860 if (ic.Item.AssetType == (int) AssetType.Unknown || 1798 if (ic.Item.AssetType == (int) AssetType.Unknown ||
1861 ic.Item.InvType == (int) AssetType.Unknown) 1799 ic.Item.InvType == (int) AssetType.Unknown)
1862 { 1800 {
1863
1864 Rest.Log.DebugFormat("{0} Attempting to infer item type", MsgId); 1801 Rest.Log.DebugFormat("{0} Attempting to infer item type", MsgId);
1865 1802
1866 string[] parts = ic.Item.Name.Split(Rest.CA_PERIOD); 1803 string[] parts = ic.Item.Name.Split(Rest.CA_PERIOD);
@@ -1880,7 +1817,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
1880 1817
1881 if (parts.Length > 1) 1818 if (parts.Length > 1)
1882 { 1819 {
1883 Rest.Log.DebugFormat("{0} File type is {1}", 1820 Rest.Log.DebugFormat("{0} File type is {1}",
1884 MsgId, parts[parts.Length - 1]); 1821 MsgId, parts[parts.Length - 1]);
1885 switch (parts[parts.Length - 1]) 1822 switch (parts[parts.Length - 1])
1886 { 1823 {
@@ -1888,7 +1825,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
1888 case "jpeg-2000" : 1825 case "jpeg-2000" :
1889 case "jpg2000" : 1826 case "jpg2000" :
1890 case "jpg-2000" : 1827 case "jpg-2000" :
1891 Rest.Log.DebugFormat("{0} Type {1} inferred", 1828 Rest.Log.DebugFormat("{0} Type {1} inferred",
1892 MsgId, parts[parts.Length-1]); 1829 MsgId, parts[parts.Length-1]);
1893 if (ic.Item.AssetType == (int) AssetType.Unknown) 1830 if (ic.Item.AssetType == (int) AssetType.Unknown)
1894 ic.Item.AssetType = (int) AssetType.ImageJPEG; 1831 ic.Item.AssetType = (int) AssetType.ImageJPEG;
@@ -1897,7 +1834,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
1897 break; 1834 break;
1898 case "jpg" : 1835 case "jpg" :
1899 case "jpeg" : 1836 case "jpeg" :
1900 Rest.Log.DebugFormat("{0} Type {1} inferred", 1837 Rest.Log.DebugFormat("{0} Type {1} inferred",
1901 MsgId, parts[parts.Length - 1]); 1838 MsgId, parts[parts.Length - 1]);
1902 if (ic.Item.AssetType == (int) AssetType.Unknown) 1839 if (ic.Item.AssetType == (int) AssetType.Unknown)
1903 ic.Item.AssetType = (int) AssetType.ImageJPEG; 1840 ic.Item.AssetType = (int) AssetType.ImageJPEG;
@@ -1938,16 +1875,14 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
1938 temp = OpenJPEGNet.LoadTGAClass.LoadTGA(tgadata); 1875 temp = OpenJPEGNet.LoadTGAClass.LoadTGA(tgadata);
1939 ic.Asset.Data = OpenJPEGNet.OpenJPEG.EncodeFromImage(temp, true); 1876 ic.Asset.Data = OpenJPEGNet.OpenJPEG.EncodeFromImage(temp, true);
1940 } 1877 }
1941
1942 ic.reset();
1943 1878
1879 ic.reset();
1944 } 1880 }
1945 1881
1946 #region Inventory RequestData extension 1882 #region Inventory RequestData extension
1947 1883
1948 internal class InventoryRequestData : RequestData 1884 internal class InventoryRequestData : RequestData
1949 { 1885 {
1950
1951 /// <summary> 1886 /// <summary>
1952 /// These are the inventory specific request/response state 1887 /// These are the inventory specific request/response state
1953 /// extensions. 1888 /// extensions.
@@ -1965,7 +1900,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
1965 } 1900 }
1966 1901
1967 /// <summary> 1902 /// <summary>
1968 /// This is the callback method required by inventory services. The 1903 /// This is the callback method required by inventory services. The
1969 /// requestor issues an inventory request and then blocks until this 1904 /// requestor issues an inventory request and then blocks until this
1970 /// method signals the monitor. 1905 /// method signals the monitor.
1971 /// </summary> 1906 /// </summary>
@@ -1981,7 +1916,6 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
1981 Monitor.Pulse(this); 1916 Monitor.Pulse(this);
1982 } 1917 }
1983 } 1918 }
1984
1985 } 1919 }
1986 1920
1987 #endregion Inventory RequestData extension 1921 #endregion Inventory RequestData extension
@@ -1994,7 +1928,6 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
1994 1928
1995 internal class XmlInventoryCollection : InventoryCollection 1929 internal class XmlInventoryCollection : InventoryCollection
1996 { 1930 {
1997
1998 internal InventoryRequestData rdata; 1931 internal InventoryRequestData rdata;
1999 private Stack<InventoryFolderBase> stk; 1932 private Stack<InventoryFolderBase> stk;
2000 1933
@@ -2087,7 +2020,6 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
2087 { 2020 {
2088 rdata.Fail(code, desc); 2021 rdata.Fail(code, desc);
2089 } 2022 }
2090
2091 } 2023 }
2092 } 2024 }
2093} 2025}