aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Framework
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Framework')
-rw-r--r--OpenSim/Framework/Console/CommandConsole.cs10
-rw-r--r--OpenSim/Framework/Console/ConsoleDisplayList.cs112
-rw-r--r--OpenSim/Framework/Console/ConsoleDisplayTable.cs139
-rw-r--r--OpenSim/Framework/Console/LocalConsole.cs4
-rw-r--r--OpenSim/Framework/EstateSettings.cs6
-rw-r--r--OpenSim/Framework/OSChatMessage.cs20
-rw-r--r--OpenSim/Framework/PrimitiveBaseShape.cs12
-rw-r--r--OpenSim/Framework/RegionSettings.cs29
-rw-r--r--OpenSim/Framework/SLUtil.cs382
-rw-r--r--OpenSim/Framework/Serialization/External/RegionSettingsSerializer.cs37
-rw-r--r--OpenSim/Framework/Serialization/Tests/RegionSettingsSerializerTests.cs8
-rw-r--r--OpenSim/Framework/Servers/HttpServer/BaseHTTPHandler.cs10
-rw-r--r--OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs58
-rw-r--r--OpenSim/Framework/Servers/HttpServer/BaseRequestHandler.cs10
-rw-r--r--OpenSim/Framework/Servers/HttpServer/BaseStreamHandler.cs9
-rw-r--r--OpenSim/Framework/Servers/HttpServer/BinaryStreamHandler.cs17
-rw-r--r--OpenSim/Framework/Servers/HttpServer/Interfaces/IStreamHandler.cs21
-rw-r--r--OpenSim/Framework/Servers/HttpServer/OSHttpRequest.cs2
-rw-r--r--OpenSim/Framework/Servers/HttpServer/OSHttpStatusCodes.cs379
-rw-r--r--OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs2
-rw-r--r--OpenSim/Framework/Servers/HttpServer/RestDeserialiseHandler.cs6
-rw-r--r--OpenSim/Framework/Servers/HttpServer/RestHTTPHandler.cs20
-rw-r--r--OpenSim/Framework/Servers/HttpServer/RestStreamHandler.cs14
-rw-r--r--OpenSim/Framework/TaskInventoryDictionary.cs89
-rw-r--r--OpenSim/Framework/TaskInventoryItem.cs16
-rw-r--r--OpenSim/Framework/Tests/MundaneFrameworkTests.cs4
-rw-r--r--OpenSim/Framework/Tests/UtilTest.cs23
-rw-r--r--OpenSim/Framework/Watchdog.cs40
-rw-r--r--OpenSim/Framework/WebUtil.cs312
29 files changed, 1217 insertions, 574 deletions
diff --git a/OpenSim/Framework/Console/CommandConsole.cs b/OpenSim/Framework/Console/CommandConsole.cs
index c5d6b78..87bdacd 100644
--- a/OpenSim/Framework/Console/CommandConsole.cs
+++ b/OpenSim/Framework/Console/CommandConsole.cs
@@ -79,7 +79,11 @@ namespace OpenSim.Framework.Console
79 public List<CommandDelegate> fn; 79 public List<CommandDelegate> fn;
80 } 80 }
81 81
82 public const string GeneralHelpText = "For more information, type 'help <item>' where <item> is one of the following categories:"; 82 public const string GeneralHelpText
83 = "To enter an argument that contains spaces, surround the argument with double quotes.\nFor example, show object name \"My long object name\"\n";
84
85 public const string ItemHelpText
86 = "For more information, type 'help <item>' where <item> is one of the following:";
83 87
84 /// <value> 88 /// <value>
85 /// Commands organized by keyword in a tree 89 /// Commands organized by keyword in a tree
@@ -108,7 +112,9 @@ namespace OpenSim.Framework.Console
108 // General help 112 // General help
109 if (helpParts.Count == 0) 113 if (helpParts.Count == 0)
110 { 114 {
115 help.Add(""); // Will become a newline.
111 help.Add(GeneralHelpText); 116 help.Add(GeneralHelpText);
117 help.Add(ItemHelpText);
112 help.AddRange(CollectModulesHelp(tree)); 118 help.AddRange(CollectModulesHelp(tree));
113 } 119 }
114 else 120 else
@@ -132,7 +138,7 @@ namespace OpenSim.Framework.Console
132 // Check modules first to see if we just need to display a list of those commands 138 // Check modules first to see if we just need to display a list of those commands
133 if (TryCollectModuleHelp(originalHelpRequest, help)) 139 if (TryCollectModuleHelp(originalHelpRequest, help))
134 { 140 {
135 help.Insert(0, GeneralHelpText); 141 help.Insert(0, ItemHelpText);
136 return help; 142 return help;
137 } 143 }
138 144
diff --git a/OpenSim/Framework/Console/ConsoleDisplayList.cs b/OpenSim/Framework/Console/ConsoleDisplayList.cs
new file mode 100644
index 0000000..6885509
--- /dev/null
+++ b/OpenSim/Framework/Console/ConsoleDisplayList.cs
@@ -0,0 +1,112 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
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
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Linq;
31using System.Text;
32
33namespace OpenSim.Framework.Console
34{
35 /// <summary>
36 /// Used to generated a formatted table for the console.
37 /// </summary>
38 /// <remarks>
39 /// Currently subject to change. If you use this, be prepared to change your code when this class changes.
40 /// </remarks>
41 public class ConsoleDisplayList
42 {
43 /// <summary>
44 /// The default divider between key and value for a list item.
45 /// </summary>
46 public const string DefaultKeyValueDivider = " : ";
47
48 /// <summary>
49 /// The divider used between key and value for a list item.
50 /// </summary>
51 public string KeyValueDivider { get; set; }
52
53 /// <summary>
54 /// Table rows
55 /// </summary>
56 public List<KeyValuePair<string, string>> Rows { get; private set; }
57
58 /// <summary>
59 /// Number of spaces to indent the list.
60 /// </summary>
61 public int Indent { get; set; }
62
63 public ConsoleDisplayList()
64 {
65 Rows = new List<KeyValuePair<string, string>>();
66 KeyValueDivider = DefaultKeyValueDivider;
67 }
68
69 public override string ToString()
70 {
71 StringBuilder sb = new StringBuilder();
72 AddToStringBuilder(sb);
73 return sb.ToString();
74 }
75
76 public void AddToStringBuilder(StringBuilder sb)
77 {
78 string formatString = GetFormatString();
79// System.Console.WriteLine("FORMAT STRING [{0}]", formatString);
80
81 // rows
82 foreach (KeyValuePair<string, string> row in Rows)
83 sb.AppendFormat(formatString, row.Key, row.Value);
84 }
85
86 /// <summary>
87 /// Gets the format string for the table.
88 /// </summary>
89 private string GetFormatString()
90 {
91 StringBuilder formatSb = new StringBuilder();
92
93 int longestKey = -1;
94
95 foreach (KeyValuePair<string, string> row in Rows)
96 if (row.Key.Length > longestKey)
97 longestKey = row.Key.Length;
98
99 formatSb.Append(' ', Indent);
100
101 // Can only do left formatting for now
102 formatSb.AppendFormat("{{0,-{0}}}{1}{{1}}\n", longestKey, KeyValueDivider);
103
104 return formatSb.ToString();
105 }
106
107 public void AddRow(object key, object value)
108 {
109 Rows.Add(new KeyValuePair<string, string>(key.ToString(), value.ToString()));
110 }
111 }
112} \ No newline at end of file
diff --git a/OpenSim/Framework/Console/ConsoleDisplayTable.cs b/OpenSim/Framework/Console/ConsoleDisplayTable.cs
new file mode 100644
index 0000000..e9d1628
--- /dev/null
+++ b/OpenSim/Framework/Console/ConsoleDisplayTable.cs
@@ -0,0 +1,139 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
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
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Linq;
31using System.Text;
32
33namespace OpenSim.Framework.Console
34{
35 /// <summary>
36 /// Used to generated a formatted table for the console.
37 /// </summary>
38 /// <remarks>
39 /// Currently subject to change. If you use this, be prepared to change your code when this class changes.
40 /// </remarks>
41 public class ConsoleDisplayTable
42 {
43 /// <summary>
44 /// Default number of spaces between table columns.
45 /// </summary>
46 public const int DefaultTableSpacing = 2;
47
48 /// <summary>
49 /// Table columns.
50 /// </summary>
51 public List<ConsoleDisplayTableColumn> Columns { get; private set; }
52
53 /// <summary>
54 /// Table rows
55 /// </summary>
56 public List<ConsoleDisplayTableRow> Rows { get; private set; }
57
58 /// <summary>
59 /// Number of spaces to indent the table.
60 /// </summary>
61 public int Indent { get; set; }
62
63 /// <summary>
64 /// Spacing between table columns
65 /// </summary>
66 public int TableSpacing { get; set; }
67
68 public ConsoleDisplayTable()
69 {
70 TableSpacing = DefaultTableSpacing;
71 Columns = new List<ConsoleDisplayTableColumn>();
72 Rows = new List<ConsoleDisplayTableRow>();
73 }
74
75 public override string ToString()
76 {
77 StringBuilder sb = new StringBuilder();
78 AddToStringBuilder(sb);
79 return sb.ToString();
80 }
81
82 public void AddToStringBuilder(StringBuilder sb)
83 {
84 string formatString = GetFormatString();
85// System.Console.WriteLine("FORMAT STRING [{0}]", formatString);
86
87 // columns
88 sb.AppendFormat(formatString, Columns.ConvertAll(c => c.Header).ToArray());
89
90 // rows
91 foreach (ConsoleDisplayTableRow row in Rows)
92 sb.AppendFormat(formatString, row.Cells.ToArray());
93 }
94
95 /// <summary>
96 /// Gets the format string for the table.
97 /// </summary>
98 private string GetFormatString()
99 {
100 StringBuilder formatSb = new StringBuilder();
101
102 formatSb.Append(' ', Indent);
103
104 for (int i = 0; i < Columns.Count; i++)
105 {
106 formatSb.Append(' ', TableSpacing);
107
108 // Can only do left formatting for now
109 formatSb.AppendFormat("{{{0},-{1}}}", i, Columns[i].Width);
110 }
111
112 formatSb.Append('\n');
113
114 return formatSb.ToString();
115 }
116 }
117
118 public struct ConsoleDisplayTableColumn
119 {
120 public string Header { get; set; }
121 public int Width { get; set; }
122
123 public ConsoleDisplayTableColumn(string header, int width) : this()
124 {
125 Header = header;
126 Width = width;
127 }
128 }
129
130 public struct ConsoleDisplayTableRow
131 {
132 public List<string> Cells { get; private set; }
133
134 public ConsoleDisplayTableRow(List<string> cells) : this()
135 {
136 Cells = cells;
137 }
138 }
139} \ No newline at end of file
diff --git a/OpenSim/Framework/Console/LocalConsole.cs b/OpenSim/Framework/Console/LocalConsole.cs
index 7c8626d..f65813b 100644
--- a/OpenSim/Framework/Console/LocalConsole.cs
+++ b/OpenSim/Framework/Console/LocalConsole.cs
@@ -296,6 +296,10 @@ namespace OpenSim.Framework.Console
296 matches[0].Groups["Category"].Value); 296 matches[0].Groups["Category"].Value);
297 System.Console.Write("]:"); 297 System.Console.Write("]:");
298 } 298 }
299 else
300 {
301 outText = outText.Trim();
302 }
299 } 303 }
300 304
301 if (level == "error") 305 if (level == "error")
diff --git a/OpenSim/Framework/EstateSettings.cs b/OpenSim/Framework/EstateSettings.cs
index 142b783..9020761 100644
--- a/OpenSim/Framework/EstateSettings.cs
+++ b/OpenSim/Framework/EstateSettings.cs
@@ -346,7 +346,7 @@ namespace OpenSim.Framework
346 l_EstateManagers.Remove(avatarID); 346 l_EstateManagers.Remove(avatarID);
347 } 347 }
348 348
349 public bool IsEstateManager(UUID avatarID) 349 public bool IsEstateManagerOrOwner(UUID avatarID)
350 { 350 {
351 if (IsEstateOwner(avatarID)) 351 if (IsEstateOwner(avatarID))
352 return true; 352 return true;
@@ -368,7 +368,7 @@ namespace OpenSim.Framework
368 if (ban.BannedUserID == avatarID) 368 if (ban.BannedUserID == avatarID)
369 return true; 369 return true;
370 370
371 if (!IsEstateManager(avatarID) && !HasAccess(avatarID)) 371 if (!IsEstateManagerOrOwner(avatarID) && !HasAccess(avatarID))
372 { 372 {
373 if (DenyMinors) 373 if (DenyMinors)
374 { 374 {
@@ -411,7 +411,7 @@ namespace OpenSim.Framework
411 411
412 public bool HasAccess(UUID user) 412 public bool HasAccess(UUID user)
413 { 413 {
414 if (IsEstateManager(user)) 414 if (IsEstateManagerOrOwner(user))
415 return true; 415 return true;
416 416
417 return l_EstateAccess.Contains(user); 417 return l_EstateAccess.Contains(user);
diff --git a/OpenSim/Framework/OSChatMessage.cs b/OpenSim/Framework/OSChatMessage.cs
index 54fa275..455756d 100644
--- a/OpenSim/Framework/OSChatMessage.cs
+++ b/OpenSim/Framework/OSChatMessage.cs
@@ -51,10 +51,12 @@ namespace OpenSim.Framework
51 protected object m_senderObject; 51 protected object m_senderObject;
52 protected ChatTypeEnum m_type; 52 protected ChatTypeEnum m_type;
53 protected UUID m_fromID; 53 protected UUID m_fromID;
54 protected UUID m_toID;
54 55
55 public OSChatMessage() 56 public OSChatMessage()
56 { 57 {
57 m_position = new Vector3(); 58 m_position = new Vector3();
59 m_toID = UUID.Zero;
58 } 60 }
59 61
60 /// <summary> 62 /// <summary>
@@ -102,6 +104,15 @@ namespace OpenSim.Framework
102 set { m_from = value; } 104 set { m_from = value; }
103 } 105 }
104 106
107 /// <summary>
108 /// The name of the sender (needed for scripts)
109 /// </summary>
110 public string To
111 {
112 get { return m_from; }
113 set { m_from = value; }
114 }
115
105 #region IEventArgs Members 116 #region IEventArgs Members
106 117
107 /// TODO: Sender and SenderObject should just be Sender and of 118 /// TODO: Sender and SenderObject should just be Sender and of
@@ -132,6 +143,15 @@ namespace OpenSim.Framework
132 } 143 }
133 144
134 /// <summary> 145 /// <summary>
146 /// The single recipient or all if not set.
147 /// </summary>
148 public UUID TargetUUID
149 {
150 get { return m_toID; }
151 set { m_toID = value; }
152 }
153
154 /// <summary>
135 /// 155 ///
136 /// </summary> 156 /// </summary>
137 public IScene Scene 157 public IScene Scene
diff --git a/OpenSim/Framework/PrimitiveBaseShape.cs b/OpenSim/Framework/PrimitiveBaseShape.cs
index c6ccc9e..fcc9873 100644
--- a/OpenSim/Framework/PrimitiveBaseShape.cs
+++ b/OpenSim/Framework/PrimitiveBaseShape.cs
@@ -241,10 +241,14 @@ namespace OpenSim.Framework
241 241
242 m_textureEntry = prim.Textures.GetBytes(); 242 m_textureEntry = prim.Textures.GetBytes();
243 243
244 SculptEntry = (prim.Sculpt.Type != OpenMetaverse.SculptType.None); 244 if (prim.Sculpt != null)
245 SculptData = prim.Sculpt.GetBytes(); 245 {
246 SculptTexture = prim.Sculpt.SculptTexture; 246 SculptEntry = (prim.Sculpt.Type != OpenMetaverse.SculptType.None);
247 SculptType = (byte)prim.Sculpt.Type; 247 SculptData = prim.Sculpt.GetBytes();
248 SculptTexture = prim.Sculpt.SculptTexture;
249 SculptType = (byte)prim.Sculpt.Type;
250 }
251 else SculptType = (byte)OpenMetaverse.SculptType.None;
248 } 252 }
249 253
250 [XmlIgnore] 254 [XmlIgnore]
diff --git a/OpenSim/Framework/RegionSettings.cs b/OpenSim/Framework/RegionSettings.cs
index c142bd9..47a2780 100644
--- a/OpenSim/Framework/RegionSettings.cs
+++ b/OpenSim/Framework/RegionSettings.cs
@@ -29,6 +29,7 @@ using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.IO; 30using System.IO;
31using OpenMetaverse; 31using OpenMetaverse;
32using System.Runtime.Serialization;
32 33
33namespace OpenSim.Framework 34namespace OpenSim.Framework
34{ 35{
@@ -71,6 +72,32 @@ namespace OpenSim.Framework
71 72
72 return pos + offset; 73 return pos + offset;
73 } 74 }
75
76 /// <summary>
77 /// Returns a string representation of this SpawnPoint.
78 /// </summary>
79 /// <returns></returns>
80 public override string ToString()
81 {
82 return string.Format("{0},{1},{2}", Yaw, Pitch, Distance);
83 }
84
85 /// <summary>
86 /// Generate a SpawnPoint from a string
87 /// </summary>
88 /// <param name="str"></param>
89 public static SpawnPoint Parse(string str)
90 {
91 string[] parts = str.Split(',');
92 if (parts.Length != 3)
93 throw new ArgumentException("Invalid string: " + str);
94
95 SpawnPoint sp = new SpawnPoint();
96 sp.Yaw = float.Parse(parts[0]);
97 sp.Pitch = float.Parse(parts[1]);
98 sp.Distance = float.Parse(parts[2]);
99 return sp;
100 }
74 } 101 }
75 102
76 public class RegionSettings 103 public class RegionSettings
@@ -478,7 +505,7 @@ namespace OpenSim.Framework
478 } 505 }
479 506
480 // Connected Telehub object 507 // Connected Telehub object
481 private UUID m_TelehubObject; 508 private UUID m_TelehubObject = UUID.Zero;
482 public UUID TelehubObject 509 public UUID TelehubObject
483 { 510 {
484 get 511 get
diff --git a/OpenSim/Framework/SLUtil.cs b/OpenSim/Framework/SLUtil.cs
index db4541e..537de7a 100644
--- a/OpenSim/Framework/SLUtil.cs
+++ b/OpenSim/Framework/SLUtil.cs
@@ -38,239 +38,189 @@ namespace OpenSim.Framework
38 public static class SLUtil 38 public static class SLUtil
39 { 39 {
40// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 40// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
41 41
42 #region SL / file extension / content-type conversions 42 #region SL / file extension / content-type conversions
43 43
44 public static string SLAssetTypeToContentType(int assetType) 44 private class TypeMapping
45 { 45 {
46 switch ((AssetType)assetType) 46 private sbyte assetType;
47 private InventoryType inventoryType;
48 private string contentType;
49 private string contentType2;
50 private string extension;
51
52 public sbyte AssetTypeCode
53 {
54 get { return assetType; }
55 }
56
57 public object AssetType
58 {
59 get {
60 if (Enum.IsDefined(typeof(OpenMetaverse.AssetType), assetType))
61 return (OpenMetaverse.AssetType)assetType;
62 else
63 return OpenMetaverse.AssetType.Unknown;
64 }
65 }
66
67 public InventoryType InventoryType
68 {
69 get { return inventoryType; }
70 }
71
72 public string ContentType
73 {
74 get { return contentType; }
75 }
76
77 public string ContentType2
78 {
79 get { return contentType2; }
80 }
81
82 public string Extension
83 {
84 get { return extension; }
85 }
86
87 private TypeMapping(sbyte assetType, InventoryType inventoryType, string contentType, string contentType2, string extension)
88 {
89 this.assetType = assetType;
90 this.inventoryType = inventoryType;
91 this.contentType = contentType;
92 this.contentType2 = contentType2;
93 this.extension = extension;
94 }
95
96 public TypeMapping(AssetType assetType, InventoryType inventoryType, string contentType, string contentType2, string extension)
97 : this((sbyte)assetType, inventoryType, contentType, contentType2, extension)
98 {
99 }
100
101 public TypeMapping(AssetType assetType, InventoryType inventoryType, string contentType, string extension)
102 : this((sbyte)assetType, inventoryType, contentType, null, extension)
47 { 103 {
48 case AssetType.Texture:
49 return "image/x-j2c";
50 case AssetType.Sound:
51 return "audio/ogg";
52 case AssetType.CallingCard:
53 return "application/vnd.ll.callingcard";
54 case AssetType.Landmark:
55 return "application/vnd.ll.landmark";
56 case AssetType.Clothing:
57 return "application/vnd.ll.clothing";
58 case AssetType.Object:
59 return "application/vnd.ll.primitive";
60 case AssetType.Notecard:
61 return "application/vnd.ll.notecard";
62 case AssetType.Folder:
63 return "application/vnd.ll.folder";
64 case AssetType.RootFolder:
65 return "application/vnd.ll.rootfolder";
66 case AssetType.LSLText:
67 return "application/vnd.ll.lsltext";
68 case AssetType.LSLBytecode:
69 return "application/vnd.ll.lslbyte";
70 case AssetType.TextureTGA:
71 case AssetType.ImageTGA:
72 return "image/tga";
73 case AssetType.Bodypart:
74 return "application/vnd.ll.bodypart";
75 case AssetType.TrashFolder:
76 return "application/vnd.ll.trashfolder";
77 case AssetType.SnapshotFolder:
78 return "application/vnd.ll.snapshotfolder";
79 case AssetType.LostAndFoundFolder:
80 return "application/vnd.ll.lostandfoundfolder";
81 case AssetType.SoundWAV:
82 return "audio/x-wav";
83 case AssetType.ImageJPEG:
84 return "image/jpeg";
85 case AssetType.Animation:
86 return "application/vnd.ll.animation";
87 case AssetType.Gesture:
88 return "application/vnd.ll.gesture";
89 case AssetType.Simstate:
90 return "application/x-metaverse-simstate";
91 case AssetType.FavoriteFolder:
92 return "application/vnd.ll.favoritefolder";
93 case AssetType.Link:
94 return "application/vnd.ll.link";
95 case AssetType.LinkFolder:
96 return "application/vnd.ll.linkfolder";
97 case AssetType.CurrentOutfitFolder:
98 return "application/vnd.ll.currentoutfitfolder";
99 case AssetType.OutfitFolder:
100 return "application/vnd.ll.outfitfolder";
101 case AssetType.MyOutfitsFolder:
102 return "application/vnd.ll.myoutfitsfolder";
103 case AssetType.Unknown:
104 default:
105 return "application/octet-stream";
106 } 104 }
107 } 105 }
108 106
109 public static string SLInvTypeToContentType(int invType) 107 /// <summary>
108 /// Maps between AssetType, InventoryType and Content-Type.
109 /// Where more than one possibility exists, the first one takes precedence. E.g.:
110 /// AssetType "AssetType.Texture" -> Content-Type "image-xj2c"
111 /// Content-Type "image/x-j2c" -> InventoryType "InventoryType.Texture"
112 /// </summary>
113 private static TypeMapping[] MAPPINGS = new TypeMapping[] {
114 new TypeMapping(AssetType.Unknown, InventoryType.Unknown, "application/octet-stream", "bin"),
115 new TypeMapping(AssetType.Texture, InventoryType.Texture, "image/x-j2c", "image/jp2", "j2c"),
116 new TypeMapping(AssetType.Texture, InventoryType.Snapshot, "image/x-j2c", "image/jp2", "j2c"),
117 new TypeMapping(AssetType.TextureTGA, InventoryType.Texture, "image/tga", "tga"),
118 new TypeMapping(AssetType.ImageTGA, InventoryType.Texture, "image/tga", "tga"),
119 new TypeMapping(AssetType.ImageJPEG, InventoryType.Texture, "image/jpeg", "jpg"),
120 new TypeMapping(AssetType.Sound, InventoryType.Sound, "audio/ogg", "application/ogg", "ogg"),
121 new TypeMapping(AssetType.SoundWAV, InventoryType.Sound, "audio/x-wav", "wav"),
122 new TypeMapping(AssetType.CallingCard, InventoryType.CallingCard, "application/vnd.ll.callingcard", "application/x-metaverse-callingcard", "callingcard"),
123 new TypeMapping(AssetType.Landmark, InventoryType.Landmark, "application/vnd.ll.landmark", "application/x-metaverse-landmark", "landmark"),
124 new TypeMapping(AssetType.Clothing, InventoryType.Wearable, "application/vnd.ll.clothing", "application/x-metaverse-clothing", "clothing"),
125 new TypeMapping(AssetType.Object, InventoryType.Object, "application/vnd.ll.primitive", "application/x-metaverse-primitive", "primitive"),
126 new TypeMapping(AssetType.Object, InventoryType.Attachment, "application/vnd.ll.primitive", "application/x-metaverse-primitive", "primitive"),
127 new TypeMapping(AssetType.Notecard, InventoryType.Notecard, "application/vnd.ll.notecard", "application/x-metaverse-notecard", "notecard"),
128 new TypeMapping(AssetType.Folder, InventoryType.Folder, "application/vnd.ll.folder", "folder"),
129 new TypeMapping(AssetType.RootFolder, InventoryType.RootCategory, "application/vnd.ll.rootfolder", "rootfolder"),
130 new TypeMapping(AssetType.LSLText, InventoryType.LSL, "application/vnd.ll.lsltext", "application/x-metaverse-lsl", "lsl"),
131 new TypeMapping(AssetType.LSLBytecode, InventoryType.LSL, "application/vnd.ll.lslbyte", "application/x-metaverse-lso", "lso"),
132 new TypeMapping(AssetType.Bodypart, InventoryType.Wearable, "application/vnd.ll.bodypart", "application/x-metaverse-bodypart", "bodypart"),
133 new TypeMapping(AssetType.TrashFolder, InventoryType.Folder, "application/vnd.ll.trashfolder", "trashfolder"),
134 new TypeMapping(AssetType.SnapshotFolder, InventoryType.Folder, "application/vnd.ll.snapshotfolder", "snapshotfolder"),
135 new TypeMapping(AssetType.LostAndFoundFolder, InventoryType.Folder, "application/vnd.ll.lostandfoundfolder", "lostandfoundfolder"),
136 new TypeMapping(AssetType.Animation, InventoryType.Animation, "application/vnd.ll.animation", "application/x-metaverse-animation", "animation"),
137 new TypeMapping(AssetType.Gesture, InventoryType.Gesture, "application/vnd.ll.gesture", "application/x-metaverse-gesture", "gesture"),
138 new TypeMapping(AssetType.Simstate, InventoryType.Snapshot, "application/x-metaverse-simstate", "simstate"),
139 new TypeMapping(AssetType.FavoriteFolder, InventoryType.Unknown, "application/vnd.ll.favoritefolder", "favoritefolder"),
140 new TypeMapping(AssetType.Link, InventoryType.Unknown, "application/vnd.ll.link", "link"),
141 new TypeMapping(AssetType.LinkFolder, InventoryType.Unknown, "application/vnd.ll.linkfolder", "linkfolder"),
142 new TypeMapping(AssetType.CurrentOutfitFolder, InventoryType.Unknown, "application/vnd.ll.currentoutfitfolder", "currentoutfitfolder"),
143 new TypeMapping(AssetType.OutfitFolder, InventoryType.Unknown, "application/vnd.ll.outfitfolder", "outfitfolder"),
144 new TypeMapping(AssetType.MyOutfitsFolder, InventoryType.Unknown, "application/vnd.ll.myoutfitsfolder", "myoutfitsfolder"),
145 new TypeMapping(AssetType.Mesh, InventoryType.Mesh, "application/vnd.ll.mesh", "llm")
146 };
147
148 private static Dictionary<sbyte, string> asset2Content;
149 private static Dictionary<sbyte, string> asset2Extension;
150 private static Dictionary<InventoryType, string> inventory2Content;
151 private static Dictionary<string, sbyte> content2Asset;
152 private static Dictionary<string, InventoryType> content2Inventory;
153
154 static SLUtil()
110 { 155 {
111 switch ((InventoryType)invType) 156 asset2Content = new Dictionary<sbyte, string>();
157 asset2Extension = new Dictionary<sbyte, string>();
158 inventory2Content = new Dictionary<InventoryType, string>();
159 content2Asset = new Dictionary<string, sbyte>();
160 content2Inventory = new Dictionary<string, InventoryType>();
161
162 foreach (TypeMapping mapping in MAPPINGS)
112 { 163 {
113 case InventoryType.Animation: 164 sbyte assetType = mapping.AssetTypeCode;
114 return "application/vnd.ll.animation"; 165 if (!asset2Content.ContainsKey(assetType))
115 case InventoryType.CallingCard: 166 asset2Content.Add(assetType, mapping.ContentType);
116 return "application/vnd.ll.callingcard"; 167 if (!asset2Extension.ContainsKey(assetType))
117 case InventoryType.Folder: 168 asset2Extension.Add(assetType, mapping.Extension);
118 return "application/vnd.ll.folder"; 169 if (!inventory2Content.ContainsKey(mapping.InventoryType))
119 case InventoryType.Gesture: 170 inventory2Content.Add(mapping.InventoryType, mapping.ContentType);
120 return "application/vnd.ll.gesture"; 171 if (!content2Asset.ContainsKey(mapping.ContentType))
121 case InventoryType.Landmark: 172 content2Asset.Add(mapping.ContentType, assetType);
122 return "application/vnd.ll.landmark"; 173 if (!content2Inventory.ContainsKey(mapping.ContentType))
123 case InventoryType.LSL: 174 content2Inventory.Add(mapping.ContentType, mapping.InventoryType);
124 return "application/vnd.ll.lsltext"; 175
125 case InventoryType.Notecard: 176 if (mapping.ContentType2 != null)
126 return "application/vnd.ll.notecard"; 177 {
127 case InventoryType.Attachment: 178 if (!content2Asset.ContainsKey(mapping.ContentType2))
128 case InventoryType.Object: 179 content2Asset.Add(mapping.ContentType2, assetType);
129 return "application/vnd.ll.primitive"; 180 if (!content2Inventory.ContainsKey(mapping.ContentType2))
130 case InventoryType.Sound: 181 content2Inventory.Add(mapping.ContentType2, mapping.InventoryType);
131 return "audio/ogg"; 182 }
132 case InventoryType.Snapshot:
133 case InventoryType.Texture:
134 return "image/x-j2c";
135 case InventoryType.Wearable:
136 return "application/vnd.ll.clothing";
137 default:
138 return "application/octet-stream";
139 } 183 }
140 } 184 }
185
186 public static string SLAssetTypeToContentType(int assetType)
187 {
188 string contentType;
189 if (!asset2Content.TryGetValue((sbyte)assetType, out contentType))
190 contentType = asset2Content[(sbyte)AssetType.Unknown];
191 return contentType;
192 }
193
194 public static string SLInvTypeToContentType(int invType)
195 {
196 string contentType;
197 if (!inventory2Content.TryGetValue((InventoryType)invType, out contentType))
198 contentType = inventory2Content[InventoryType.Unknown];
199 return contentType;
200 }
141 201
142 public static sbyte ContentTypeToSLAssetType(string contentType) 202 public static sbyte ContentTypeToSLAssetType(string contentType)
143 { 203 {
144 switch (contentType) 204 sbyte assetType;
145 { 205 if (!content2Asset.TryGetValue(contentType, out assetType))
146 case "image/x-j2c": 206 assetType = (sbyte)AssetType.Unknown;
147 case "image/jp2": 207 return (sbyte)assetType;
148 return (sbyte)AssetType.Texture;
149 case "application/ogg":
150 case "audio/ogg":
151 return (sbyte)AssetType.Sound;
152 case "application/vnd.ll.callingcard":
153 case "application/x-metaverse-callingcard":
154 return (sbyte)AssetType.CallingCard;
155 case "application/vnd.ll.landmark":
156 case "application/x-metaverse-landmark":
157 return (sbyte)AssetType.Landmark;
158 case "application/vnd.ll.clothing":
159 case "application/x-metaverse-clothing":
160 return (sbyte)AssetType.Clothing;
161 case "application/vnd.ll.primitive":
162 case "application/x-metaverse-primitive":
163 return (sbyte)AssetType.Object;
164 case "application/vnd.ll.notecard":
165 case "application/x-metaverse-notecard":
166 return (sbyte)AssetType.Notecard;
167 case "application/vnd.ll.folder":
168 return (sbyte)AssetType.Folder;
169 case "application/vnd.ll.rootfolder":
170 return (sbyte)AssetType.RootFolder;
171 case "application/vnd.ll.lsltext":
172 case "application/x-metaverse-lsl":
173 return (sbyte)AssetType.LSLText;
174 case "application/vnd.ll.lslbyte":
175 case "application/x-metaverse-lso":
176 return (sbyte)AssetType.LSLBytecode;
177 case "image/tga":
178 // Note that AssetType.TextureTGA will be converted to AssetType.ImageTGA
179 return (sbyte)AssetType.ImageTGA;
180 case "application/vnd.ll.bodypart":
181 case "application/x-metaverse-bodypart":
182 return (sbyte)AssetType.Bodypart;
183 case "application/vnd.ll.trashfolder":
184 return (sbyte)AssetType.TrashFolder;
185 case "application/vnd.ll.snapshotfolder":
186 return (sbyte)AssetType.SnapshotFolder;
187 case "application/vnd.ll.lostandfoundfolder":
188 return (sbyte)AssetType.LostAndFoundFolder;
189 case "audio/x-wav":
190 return (sbyte)AssetType.SoundWAV;
191 case "image/jpeg":
192 return (sbyte)AssetType.ImageJPEG;
193 case "application/vnd.ll.animation":
194 case "application/x-metaverse-animation":
195 return (sbyte)AssetType.Animation;
196 case "application/vnd.ll.gesture":
197 case "application/x-metaverse-gesture":
198 return (sbyte)AssetType.Gesture;
199 case "application/x-metaverse-simstate":
200 return (sbyte)AssetType.Simstate;
201 case "application/vnd.ll.favoritefolder":
202 return (sbyte)AssetType.FavoriteFolder;
203 case "application/vnd.ll.link":
204 return (sbyte)AssetType.Link;
205 case "application/vnd.ll.linkfolder":
206 return (sbyte)AssetType.LinkFolder;
207 case "application/vnd.ll.currentoutfitfolder":
208 return (sbyte)AssetType.CurrentOutfitFolder;
209 case "application/vnd.ll.outfitfolder":
210 return (sbyte)AssetType.OutfitFolder;
211 case "application/vnd.ll.myoutfitsfolder":
212 return (sbyte)AssetType.MyOutfitsFolder;
213 case "application/octet-stream":
214 default:
215 return (sbyte)AssetType.Unknown;
216 }
217 } 208 }
218 209
219 public static sbyte ContentTypeToSLInvType(string contentType) 210 public static sbyte ContentTypeToSLInvType(string contentType)
220 { 211 {
221 switch (contentType) 212 InventoryType invType;
222 { 213 if (!content2Inventory.TryGetValue(contentType, out invType))
223 case "image/x-j2c": 214 invType = InventoryType.Unknown;
224 case "image/jp2": 215 return (sbyte)invType;
225 case "image/tga": 216 }
226 case "image/jpeg": 217
227 return (sbyte)InventoryType.Texture; 218 public static string SLAssetTypeToExtension(int assetType)
228 case "application/ogg": 219 {
229 case "audio/ogg": 220 string extension;
230 case "audio/x-wav": 221 if (!asset2Extension.TryGetValue((sbyte)assetType, out extension))
231 return (sbyte)InventoryType.Sound; 222 extension = asset2Extension[(sbyte)AssetType.Unknown];
232 case "application/vnd.ll.callingcard": 223 return extension;
233 case "application/x-metaverse-callingcard":
234 return (sbyte)InventoryType.CallingCard;
235 case "application/vnd.ll.landmark":
236 case "application/x-metaverse-landmark":
237 return (sbyte)InventoryType.Landmark;
238 case "application/vnd.ll.clothing":
239 case "application/x-metaverse-clothing":
240 case "application/vnd.ll.bodypart":
241 case "application/x-metaverse-bodypart":
242 return (sbyte)InventoryType.Wearable;
243 case "application/vnd.ll.primitive":
244 case "application/x-metaverse-primitive":
245 return (sbyte)InventoryType.Object;
246 case "application/vnd.ll.notecard":
247 case "application/x-metaverse-notecard":
248 return (sbyte)InventoryType.Notecard;
249 case "application/vnd.ll.folder":
250 return (sbyte)InventoryType.Folder;
251 case "application/vnd.ll.rootfolder":
252 return (sbyte)InventoryType.RootCategory;
253 case "application/vnd.ll.lsltext":
254 case "application/x-metaverse-lsl":
255 case "application/vnd.ll.lslbyte":
256 case "application/x-metaverse-lso":
257 return (sbyte)InventoryType.LSL;
258 case "application/vnd.ll.trashfolder":
259 case "application/vnd.ll.snapshotfolder":
260 case "application/vnd.ll.lostandfoundfolder":
261 return (sbyte)InventoryType.Folder;
262 case "application/vnd.ll.animation":
263 case "application/x-metaverse-animation":
264 return (sbyte)InventoryType.Animation;
265 case "application/vnd.ll.gesture":
266 case "application/x-metaverse-gesture":
267 return (sbyte)InventoryType.Gesture;
268 case "application/x-metaverse-simstate":
269 return (sbyte)InventoryType.Snapshot;
270 case "application/octet-stream":
271 default:
272 return (sbyte)InventoryType.Unknown;
273 }
274 } 224 }
275 225
276 #endregion SL / file extension / content-type conversions 226 #endregion SL / file extension / content-type conversions
@@ -377,4 +327,4 @@ namespace OpenSim.Framework
377 return output; 327 return output;
378 } 328 }
379 } 329 }
380} \ No newline at end of file 330}
diff --git a/OpenSim/Framework/Serialization/External/RegionSettingsSerializer.cs b/OpenSim/Framework/Serialization/External/RegionSettingsSerializer.cs
index 931898c..f18435d 100644
--- a/OpenSim/Framework/Serialization/External/RegionSettingsSerializer.cs
+++ b/OpenSim/Framework/Serialization/External/RegionSettingsSerializer.cs
@@ -30,6 +30,8 @@ using System.Text;
30using System.Xml; 30using System.Xml;
31using OpenMetaverse; 31using OpenMetaverse;
32using OpenSim.Framework; 32using OpenSim.Framework;
33using log4net;
34using System.Reflection;
33 35
34namespace OpenSim.Framework.Serialization.External 36namespace OpenSim.Framework.Serialization.External
35{ 37{
@@ -187,7 +189,29 @@ namespace OpenSim.Framework.Serialization.External
187 break; 189 break;
188 } 190 }
189 } 191 }
190 192
193 xtr.ReadEndElement();
194
195 if (xtr.IsStartElement("Telehub"))
196 {
197 xtr.ReadStartElement("Telehub");
198
199 while (xtr.Read() && xtr.NodeType != XmlNodeType.EndElement)
200 {
201 switch (xtr.Name)
202 {
203 case "TelehubObject":
204 settings.TelehubObject = UUID.Parse(xtr.ReadElementContentAsString());
205 break;
206 case "SpawnPoint":
207 string str = xtr.ReadElementContentAsString();
208 SpawnPoint sp = SpawnPoint.Parse(str);
209 settings.AddSpawnPoint(sp);
210 break;
211 }
212 }
213 }
214
191 xtr.Close(); 215 xtr.Close();
192 sr.Close(); 216 sr.Close();
193 217
@@ -243,7 +267,16 @@ namespace OpenSim.Framework.Serialization.External
243 xtw.WriteElementString("SunPosition", settings.SunPosition.ToString()); 267 xtw.WriteElementString("SunPosition", settings.SunPosition.ToString());
244 // Note: 'SunVector' isn't saved because this value is owned by the Sun Module, which 268 // Note: 'SunVector' isn't saved because this value is owned by the Sun Module, which
245 // calculates it automatically according to the date and other factors. 269 // calculates it automatically according to the date and other factors.
246 xtw.WriteEndElement(); 270 xtw.WriteEndElement();
271
272 xtw.WriteStartElement("Telehub");
273 if (settings.TelehubObject != UUID.Zero)
274 {
275 xtw.WriteElementString("TelehubObject", settings.TelehubObject.ToString());
276 foreach (SpawnPoint sp in settings.SpawnPoints())
277 xtw.WriteElementString("SpawnPoint", sp.ToString());
278 }
279 xtw.WriteEndElement();
247 280
248 xtw.WriteEndElement(); 281 xtw.WriteEndElement();
249 282
diff --git a/OpenSim/Framework/Serialization/Tests/RegionSettingsSerializerTests.cs b/OpenSim/Framework/Serialization/Tests/RegionSettingsSerializerTests.cs
index a61e4af..09b6f6d 100644
--- a/OpenSim/Framework/Serialization/Tests/RegionSettingsSerializerTests.cs
+++ b/OpenSim/Framework/Serialization/Tests/RegionSettingsSerializerTests.cs
@@ -78,6 +78,10 @@ namespace OpenSim.Framework.Serialization.Tests
78 <FixedSun>true</FixedSun> 78 <FixedSun>true</FixedSun>
79 <SunPosition>12</SunPosition> 79 <SunPosition>12</SunPosition>
80 </Terrain> 80 </Terrain>
81 <Telehub>
82 <TelehubObject>00000000-0000-0000-0000-111111111111</TelehubObject>
83 <SpawnPoint>1,-2,0.33</SpawnPoint>
84 </Telehub>
81</RegionSettings>"; 85</RegionSettings>";
82 86
83 private RegionSettings m_rs; 87 private RegionSettings m_rs;
@@ -116,6 +120,8 @@ namespace OpenSim.Framework.Serialization.Tests
116 m_rs.TerrainTexture4 = UUID.Parse("00000000-0000-0000-0000-000000000080"); 120 m_rs.TerrainTexture4 = UUID.Parse("00000000-0000-0000-0000-000000000080");
117 m_rs.UseEstateSun = true; 121 m_rs.UseEstateSun = true;
118 m_rs.WaterHeight = 23; 122 m_rs.WaterHeight = 23;
123 m_rs.TelehubObject = UUID.Parse("00000000-0000-0000-0000-111111111111");
124 m_rs.AddSpawnPoint(SpawnPoint.Parse("1,-2,0.33"));
119 } 125 }
120 126
121 [Test] 127 [Test]
@@ -129,6 +135,8 @@ namespace OpenSim.Framework.Serialization.Tests
129 Assert.That(deserRs.TerrainTexture2, Is.EqualTo(m_rs.TerrainTexture2)); 135 Assert.That(deserRs.TerrainTexture2, Is.EqualTo(m_rs.TerrainTexture2));
130 Assert.That(deserRs.DisablePhysics, Is.EqualTo(m_rs.DisablePhysics)); 136 Assert.That(deserRs.DisablePhysics, Is.EqualTo(m_rs.DisablePhysics));
131 Assert.That(deserRs.TerrainLowerLimit, Is.EqualTo(m_rs.TerrainLowerLimit)); 137 Assert.That(deserRs.TerrainLowerLimit, Is.EqualTo(m_rs.TerrainLowerLimit));
138 Assert.That(deserRs.TelehubObject, Is.EqualTo(m_rs.TelehubObject));
139 Assert.That(deserRs.SpawnPoints()[0].ToString(), Is.EqualTo(m_rs.SpawnPoints()[0].ToString()));
132 } 140 }
133 } 141 }
134} 142}
diff --git a/OpenSim/Framework/Servers/HttpServer/BaseHTTPHandler.cs b/OpenSim/Framework/Servers/HttpServer/BaseHTTPHandler.cs
index 2fe9769..9f8f4a8 100644
--- a/OpenSim/Framework/Servers/HttpServer/BaseHTTPHandler.cs
+++ b/OpenSim/Framework/Servers/HttpServer/BaseHTTPHandler.cs
@@ -33,9 +33,9 @@ namespace OpenSim.Framework.Servers.HttpServer
33 { 33 {
34 public abstract Hashtable Handle(string path, Hashtable Request); 34 public abstract Hashtable Handle(string path, Hashtable Request);
35 35
36 protected BaseHTTPHandler(string httpMethod, string path) 36 protected BaseHTTPHandler(string httpMethod, string path) : this(httpMethod, path, null, null) {}
37 : base(httpMethod, path) 37
38 { 38 protected BaseHTTPHandler(string httpMethod, string path, string name, string description)
39 } 39 : base(httpMethod, path, name, description) {}
40 } 40 }
41} 41} \ No newline at end of file
diff --git a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
index ad5af1f..f5addc8 100644
--- a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
+++ b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
@@ -156,7 +156,7 @@ namespace OpenSim.Framework.Servers.HttpServer
156 } 156 }
157 } 157 }
158 158
159 public List<string> GetStreamHandlerKeys() 159 public List<string> GetStreamHandlerKeys()
160 { 160 {
161 lock (m_streamHandlers) 161 lock (m_streamHandlers)
162 return new List<string>(m_streamHandlers.Keys); 162 return new List<string>(m_streamHandlers.Keys);
@@ -356,7 +356,7 @@ namespace OpenSim.Framework.Servers.HttpServer
356 } 356 }
357 catch (Exception e) 357 catch (Exception e)
358 { 358 {
359 m_log.ErrorFormat("[BASE HTTP SERVER]: OnRequest() failed with {0}{1}", e.Message, e.StackTrace); 359 m_log.Error(String.Format("[BASE HTTP SERVER]: OnRequest() failed: {0} ", e.Message), e);
360 } 360 }
361 } 361 }
362 362
@@ -410,6 +410,8 @@ namespace OpenSim.Framework.Servers.HttpServer
410// string reqnum = "unknown"; 410// string reqnum = "unknown";
411 int tickstart = Environment.TickCount; 411 int tickstart = Environment.TickCount;
412 412
413 IRequestHandler requestHandler = null;
414
413 try 415 try
414 { 416 {
415 // OpenSim.Framework.WebUtil.OSHeaderRequestID 417 // OpenSim.Framework.WebUtil.OSHeaderRequestID
@@ -438,8 +440,6 @@ namespace OpenSim.Framework.Servers.HttpServer
438 //response.KeepAlive = true; 440 //response.KeepAlive = true;
439 response.SendChunked = false; 441 response.SendChunked = false;
440 442
441 IRequestHandler requestHandler;
442
443 string path = request.RawUrl; 443 string path = request.RawUrl;
444 string handlerKey = GetHandlerKey(request.HttpMethod, path); 444 string handlerKey = GetHandlerKey(request.HttpMethod, path);
445 445
@@ -447,8 +447,8 @@ namespace OpenSim.Framework.Servers.HttpServer
447 { 447 {
448 if (DebugLevel >= 1) 448 if (DebugLevel >= 1)
449 m_log.DebugFormat( 449 m_log.DebugFormat(
450 "[BASE HTTP SERVER]: Found stream handler for {0} {1}", 450 "[BASE HTTP SERVER]: Found stream handler for {0} {1} {2} {3}",
451 request.HttpMethod, request.Url.PathAndQuery); 451 request.HttpMethod, request.Url.PathAndQuery, requestHandler.Name, requestHandler.Description);
452 452
453 // Okay, so this is bad, but should be considered temporary until everything is IStreamHandler. 453 // Okay, so this is bad, but should be considered temporary until everything is IStreamHandler.
454 byte[] buffer = null; 454 byte[] buffer = null;
@@ -551,11 +551,11 @@ namespace OpenSim.Framework.Servers.HttpServer
551 catch (SocketException e) 551 catch (SocketException e)
552 { 552 {
553 // This has to be here to prevent a Linux/Mono crash 553 // This has to be here to prevent a Linux/Mono crash
554 m_log.WarnFormat("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux.", e); 554 m_log.Warn(String.Format("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux. ", e.Message), e);
555 } 555 }
556 catch (IOException e) 556 catch (IOException e)
557 { 557 {
558 m_log.Warn("[BASE HTTP SERVER]: XmlRpcRequest issue: " + e.Message); 558 m_log.Warn(String.Format("[BASE HTTP SERVER]: XmlRpcRequest issue {0}. ", e.Message), e);
559 } 559 }
560 560
561 return; 561 return;
@@ -658,15 +658,15 @@ namespace OpenSim.Framework.Servers.HttpServer
658 // 658 //
659 // An alternative may be to turn off all response write exceptions on the HttpListener, but let's go 659 // An alternative may be to turn off all response write exceptions on the HttpListener, but let's go
660 // with the minimum first 660 // with the minimum first
661 m_log.WarnFormat("[BASE HTTP SERVER]: HandleRequest threw {0}.\nNOTE: this may be spurious on Linux", e); 661 m_log.Warn(String.Format("[BASE HTTP SERVER]: HandleRequest threw {0}.\nNOTE: this may be spurious on Linux ", e.Message), e);
662 } 662 }
663 catch (IOException e) 663 catch (IOException e)
664 { 664 {
665 m_log.ErrorFormat("[BASE HTTP SERVER]: HandleRequest() threw {0}", e); 665 m_log.Error(String.Format("[BASE HTTP SERVER]: HandleRequest() threw {0} ", e.Message), e);
666 } 666 }
667 catch (Exception e) 667 catch (Exception e)
668 { 668 {
669 m_log.ErrorFormat("[BASE HTTP SERVER]: HandleRequest() threw {0}", e.StackTrace); 669 m_log.Error(String.Format("[BASE HTTP SERVER]: HandleRequest() threw {0} ", e.Message), e);
670 SendHTML500(response); 670 SendHTML500(response);
671 } 671 }
672 finally 672 finally
@@ -675,8 +675,16 @@ namespace OpenSim.Framework.Servers.HttpServer
675 // since its just for reporting, tickdiff limit can be adjusted 675 // since its just for reporting, tickdiff limit can be adjusted
676 int tickdiff = Environment.TickCount - tickstart; 676 int tickdiff = Environment.TickCount - tickstart;
677 if (tickdiff > 3000) 677 if (tickdiff > 3000)
678 {
678 m_log.InfoFormat( 679 m_log.InfoFormat(
679 "[BASE HTTP SERVER]: slow {0} request for {1} from {2} took {3} ms", requestMethod, uriString, request.RemoteIPEndPoint.ToString(), tickdiff); 680 "[BASE HTTP SERVER]: Slow handling of {0} {1} {2} {3} from {4} took {5}ms",
681 requestMethod,
682 uriString,
683 requestHandler != null ? requestHandler.Name : "",
684 requestHandler != null ? requestHandler.Description : "",
685 request.RemoteIPEndPoint.ToString(),
686 tickdiff);
687 }
680 } 688 }
681 } 689 }
682 690
@@ -925,11 +933,11 @@ namespace OpenSim.Framework.Servers.HttpServer
925 catch (SocketException e) 933 catch (SocketException e)
926 { 934 {
927 // This has to be here to prevent a Linux/Mono crash 935 // This has to be here to prevent a Linux/Mono crash
928 m_log.WarnFormat("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux.", e); 936 m_log.Warn(String.Format("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux. ", e.Message), e);
929 } 937 }
930 catch (IOException e) 938 catch (IOException e)
931 { 939 {
932 m_log.Warn("[BASE HTTP SERVER]: XmlRpcRequest issue: " + e.Message); 940 m_log.Warn(String.Format("[BASE HTTP SERVER]: XmlRpcRequest issue {0} ", e.Message), e);
933 } 941 }
934 } 942 }
935 return; 943 return;
@@ -962,11 +970,11 @@ namespace OpenSim.Framework.Servers.HttpServer
962 catch (SocketException e) 970 catch (SocketException e)
963 { 971 {
964 // This has to be here to prevent a Linux/Mono crash 972 // This has to be here to prevent a Linux/Mono crash
965 m_log.WarnFormat("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux.", e); 973 m_log.Warn(String.Format("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux. ", e.Message), e);
966 } 974 }
967 catch (IOException e) 975 catch (IOException e)
968 { 976 {
969 m_log.Warn("[BASE HTTP SERVER]: XmlRpcRequest issue: " + e.Message); 977 m_log.Warn(String.Format("[BASE HTTP SERVER]: XmlRpcRequest issue {0} ", e.Message), e);
970 } 978 }
971 } 979 }
972 } 980 }
@@ -1077,12 +1085,12 @@ namespace OpenSim.Framework.Servers.HttpServer
1077 } 1085 }
1078 catch (IOException e) 1086 catch (IOException e)
1079 { 1087 {
1080 m_log.WarnFormat("[BASE HTTP SERVER]: LLSD IOException {0}.", e); 1088 m_log.Warn(String.Format("[BASE HTTP SERVER]: LLSD IOException {0} ", e.Message), e);
1081 } 1089 }
1082 catch (SocketException e) 1090 catch (SocketException e)
1083 { 1091 {
1084 // This has to be here to prevent a Linux/Mono crash 1092 // This has to be here to prevent a Linux/Mono crash
1085 m_log.WarnFormat("[BASE HTTP SERVER]: LLSD issue {0}.\nNOTE: this may be spurious on Linux.", e); 1093 m_log.Warn(String.Format("[BASE HTTP SERVER]: LLSD issue {0}.\nNOTE: this may be spurious on Linux. ", e.Message), e);
1086 } 1094 }
1087 } 1095 }
1088 } 1096 }
@@ -1334,8 +1342,8 @@ namespace OpenSim.Framework.Servers.HttpServer
1334 catch (SocketException f) 1342 catch (SocketException f)
1335 { 1343 {
1336 // This has to be here to prevent a Linux/Mono crash 1344 // This has to be here to prevent a Linux/Mono crash
1337 m_log.WarnFormat( 1345 m_log.Warn(
1338 "[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux.", f); 1346 String.Format("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux. ", f.Message), f);
1339 } 1347 }
1340 } 1348 }
1341 catch(Exception) 1349 catch(Exception)
@@ -1653,11 +1661,11 @@ namespace OpenSim.Framework.Servers.HttpServer
1653 catch (SocketException e) 1661 catch (SocketException e)
1654 { 1662 {
1655 // This has to be here to prevent a Linux/Mono crash 1663 // This has to be here to prevent a Linux/Mono crash
1656 m_log.WarnFormat("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux.", e); 1664 m_log.Warn(String.Format("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux. ", e.Message), e);
1657 } 1665 }
1658 catch (IOException e) 1666 catch (IOException e)
1659 { 1667 {
1660 m_log.Warn("[BASE HTTP SERVER]: XmlRpcRequest issue: " + e.Message); 1668 m_log.Warn(String.Format("[BASE HTTP SERVER]: XmlRpcRequest issue {0} ", e.Message), e);
1661 } 1669 }
1662 } 1670 }
1663 } 1671 }
@@ -1694,7 +1702,7 @@ namespace OpenSim.Framework.Servers.HttpServer
1694 catch (SocketException e) 1702 catch (SocketException e)
1695 { 1703 {
1696 // This has to be here to prevent a Linux/Mono crash 1704 // This has to be here to prevent a Linux/Mono crash
1697 m_log.WarnFormat("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux.", e); 1705 m_log.Warn(String.Format("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux. ", e.Message), e);
1698 } 1706 }
1699 } 1707 }
1700 } 1708 }
@@ -1730,7 +1738,7 @@ namespace OpenSim.Framework.Servers.HttpServer
1730 catch (SocketException e) 1738 catch (SocketException e)
1731 { 1739 {
1732 // This has to be here to prevent a Linux/Mono crash 1740 // This has to be here to prevent a Linux/Mono crash
1733 m_log.WarnFormat("[BASE HTTP SERVER] XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux.", e); 1741 m_log.Warn(String.Format("[BASE HTTP SERVER] XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux. ", e.Message), e);
1734 } 1742 }
1735 } 1743 }
1736 } 1744 }
@@ -1809,7 +1817,7 @@ namespace OpenSim.Framework.Servers.HttpServer
1809 1817
1810 public void httpServerException(object source, Exception exception) 1818 public void httpServerException(object source, Exception exception)
1811 { 1819 {
1812 m_log.ErrorFormat("[BASE HTTP SERVER]: {0} had an exception {1}", source.ToString(), exception.ToString()); 1820 m_log.Error(String.Format("[BASE HTTP SERVER]: {0} had an exception: {1} ", source.ToString(), exception.Message), exception);
1813 /* 1821 /*
1814 if (HTTPDRunning)// && NotSocketErrors > 5) 1822 if (HTTPDRunning)// && NotSocketErrors > 5)
1815 { 1823 {
diff --git a/OpenSim/Framework/Servers/HttpServer/BaseRequestHandler.cs b/OpenSim/Framework/Servers/HttpServer/BaseRequestHandler.cs
index a2135a3..ae7aaf2 100644
--- a/OpenSim/Framework/Servers/HttpServer/BaseRequestHandler.cs
+++ b/OpenSim/Framework/Servers/HttpServer/BaseRequestHandler.cs
@@ -45,8 +45,16 @@ namespace OpenSim.Framework.Servers.HttpServer
45 45
46 private readonly string m_path; 46 private readonly string m_path;
47 47
48 protected BaseRequestHandler(string httpMethod, string path) 48 public string Name { get; private set; }
49
50 public string Description { get; private set; }
51
52 protected BaseRequestHandler(string httpMethod, string path) : this(httpMethod, path, null, null) {}
53
54 protected BaseRequestHandler(string httpMethod, string path, string name, string description)
49 { 55 {
56 Name = name;
57 Description = description;
50 m_httpMethod = httpMethod; 58 m_httpMethod = httpMethod;
51 m_path = path; 59 m_path = path;
52 } 60 }
diff --git a/OpenSim/Framework/Servers/HttpServer/BaseStreamHandler.cs b/OpenSim/Framework/Servers/HttpServer/BaseStreamHandler.cs
index f1cde74..6342983 100644
--- a/OpenSim/Framework/Servers/HttpServer/BaseStreamHandler.cs
+++ b/OpenSim/Framework/Servers/HttpServer/BaseStreamHandler.cs
@@ -34,8 +34,9 @@ namespace OpenSim.Framework.Servers.HttpServer
34 public abstract byte[] Handle(string path, Stream request, 34 public abstract byte[] Handle(string path, Stream request,
35 IOSHttpRequest httpRequest, IOSHttpResponse httpResponse); 35 IOSHttpRequest httpRequest, IOSHttpResponse httpResponse);
36 36
37 protected BaseStreamHandler(string httpMethod, string path) : base(httpMethod, path) 37 protected BaseStreamHandler(string httpMethod, string path) : this(httpMethod, path, null, null) {}
38 { 38
39 } 39 protected BaseStreamHandler(string httpMethod, string path, string name, string description)
40 : base(httpMethod, path, name, description) {}
40 } 41 }
41} 42} \ No newline at end of file
diff --git a/OpenSim/Framework/Servers/HttpServer/BinaryStreamHandler.cs b/OpenSim/Framework/Servers/HttpServer/BinaryStreamHandler.cs
index 1699233..b94bfb4 100644
--- a/OpenSim/Framework/Servers/HttpServer/BinaryStreamHandler.cs
+++ b/OpenSim/Framework/Servers/HttpServer/BinaryStreamHandler.cs
@@ -36,6 +36,15 @@ namespace OpenSim.Framework.Servers.HttpServer
36 { 36 {
37 private BinaryMethod m_method; 37 private BinaryMethod m_method;
38 38
39 public BinaryStreamHandler(string httpMethod, string path, BinaryMethod binaryMethod)
40 : this(httpMethod, path, binaryMethod, null, null) {}
41
42 public BinaryStreamHandler(string httpMethod, string path, BinaryMethod binaryMethod, string name, string description)
43 : base(httpMethod, path, name, description)
44 {
45 m_method = binaryMethod;
46 }
47
39 public override byte[] Handle(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) 48 public override byte[] Handle(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
40 { 49 {
41 byte[] data = ReadFully(request); 50 byte[] data = ReadFully(request);
@@ -45,12 +54,6 @@ namespace OpenSim.Framework.Servers.HttpServer
45 return Encoding.UTF8.GetBytes(responseString); 54 return Encoding.UTF8.GetBytes(responseString);
46 } 55 }
47 56
48 public BinaryStreamHandler(string httpMethod, string path, BinaryMethod binaryMethod)
49 : base(httpMethod, path)
50 {
51 m_method = binaryMethod;
52 }
53
54 private static byte[] ReadFully(Stream stream) 57 private static byte[] ReadFully(Stream stream)
55 { 58 {
56 byte[] buffer = new byte[1024]; 59 byte[] buffer = new byte[1024];
@@ -70,4 +73,4 @@ namespace OpenSim.Framework.Servers.HttpServer
70 } 73 }
71 } 74 }
72 } 75 }
73} 76} \ No newline at end of file
diff --git a/OpenSim/Framework/Servers/HttpServer/Interfaces/IStreamHandler.cs b/OpenSim/Framework/Servers/HttpServer/Interfaces/IStreamHandler.cs
index a449c2d..cb5cce5 100644
--- a/OpenSim/Framework/Servers/HttpServer/Interfaces/IStreamHandler.cs
+++ b/OpenSim/Framework/Servers/HttpServer/Interfaces/IStreamHandler.cs
@@ -32,6 +32,25 @@ namespace OpenSim.Framework.Servers.HttpServer
32{ 32{
33 public interface IRequestHandler 33 public interface IRequestHandler
34 { 34 {
35
36 /// <summary>
37 /// Name for this handler.
38 /// </summary>
39 /// <remarks>
40 /// Used for diagnostics. The path doesn't always describe what the handler does. Can be null if none
41 /// specified.
42 /// </remarks>
43 string Name { get; }
44
45 /// <summary>
46 /// Description for this handler.
47 /// </summary>
48 /// <remarks>
49 /// Used for diagnostics. The path doesn't always describe what the handler does. Can be null if none
50 /// specified.
51 /// </remarks>
52 string Description { get; }
53
35 // Return response content type 54 // Return response content type
36 string ContentType { get; } 55 string ContentType { get; }
37 56
@@ -58,4 +77,4 @@ namespace OpenSim.Framework.Servers.HttpServer
58 { 77 {
59 Hashtable Handle(string path, Hashtable request); 78 Hashtable Handle(string path, Hashtable request);
60 } 79 }
61} 80} \ No newline at end of file
diff --git a/OpenSim/Framework/Servers/HttpServer/OSHttpRequest.cs b/OpenSim/Framework/Servers/HttpServer/OSHttpRequest.cs
index fc8daf3..3171759 100644
--- a/OpenSim/Framework/Servers/HttpServer/OSHttpRequest.cs
+++ b/OpenSim/Framework/Servers/HttpServer/OSHttpRequest.cs
@@ -107,7 +107,7 @@ namespace OpenSim.Framework.Servers.HttpServer
107 107
108 public bool IsSecured 108 public bool IsSecured
109 { 109 {
110 get { return _context.Secured; } 110 get { return _context.IsSecured; }
111 } 111 }
112 112
113 public bool KeepAlive 113 public bool KeepAlive
diff --git a/OpenSim/Framework/Servers/HttpServer/OSHttpStatusCodes.cs b/OpenSim/Framework/Servers/HttpServer/OSHttpStatusCodes.cs
index 5625227..a736c8b 100644
--- a/OpenSim/Framework/Servers/HttpServer/OSHttpStatusCodes.cs
+++ b/OpenSim/Framework/Servers/HttpServer/OSHttpStatusCodes.cs
@@ -28,143 +28,252 @@
28namespace OpenSim.Framework.Servers.HttpServer 28namespace OpenSim.Framework.Servers.HttpServer
29{ 29{
30 /// <summary> 30 /// <summary>
31 /// HTTP status codes (almost) as defined by W3C in 31 /// HTTP status codes (almost) as defined by W3C in http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html and IETF in http://tools.ietf.org/html/rfc6585
32 /// http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
33 /// </summary> 32 /// </summary>
34 public enum OSHttpStatusCode: int 33 public enum OSHttpStatusCode : int
35 { 34 {
36 // 1xx Informational status codes providing a provisional 35 #region 1xx Informational status codes providing a provisional response.
37 // response. 36
38 // 100 Tells client that to keep on going sending its request 37 /// <summary>
39 InfoContinue = 100, 38 /// 100 Tells client that to keep on going sending its request
40 // 101 Server understands request, proposes to switch to different 39 /// </summary>
41 // application level protocol 40 InfoContinue = 100,
42 InfoSwitchingProtocols = 101, 41
43 42 /// <summary>
44 43 /// 101 Server understands request, proposes to switch to different application level protocol
45 // 2xx Success codes 44 /// </summary>
46 // 200 Request successful 45 InfoSwitchingProtocols = 101,
47 SuccessOk = 200, 46
48 // 201 Request successful, new resource created 47 #endregion
49 SuccessOkCreated = 201, 48
50 // 202 Request accepted, processing still on-going 49 #region 2xx Success codes
51 SuccessOkAccepted = 202, 50
52 // 203 Request successful, meta information not authoritative 51 /// <summary>
53 SuccessOkNonAuthoritativeInformation = 203, 52 /// 200 Request successful
54 // 204 Request successful, nothing to return in the body 53 /// </summary>
55 SuccessOkNoContent = 204, 54 SuccessOk = 200,
56 // 205 Request successful, reset displayed content 55
57 SuccessOkResetContent = 205, 56 /// <summary>
58 // 206 Request successful, partial content returned 57 /// 201 Request successful, new resource created
59 SuccessOkPartialContent = 206, 58 /// </summary>
60 59 SuccessOkCreated = 201,
61 // 3xx Redirect code: user agent needs to go somewhere else 60
62 // 300 Redirect: different presentation forms available, take 61 /// <summary>
63 // a pick 62 /// 202 Request accepted, processing still on-going
64 RedirectMultipleChoices = 300, 63 /// </summary>
65 // 301 Redirect: requested resource has moved and now lives 64 SuccessOkAccepted = 202,
66 // somewhere else 65
67 RedirectMovedPermanently = 301, 66 /// <summary>
68 // 302 Redirect: Resource temporarily somewhere else, location 67 /// 203 Request successful, meta information not authoritative
69 // might change 68 /// </summary>
70 RedirectFound = 302, 69 SuccessOkNonAuthoritativeInformation = 203,
71 // 303 Redirect: See other as result of a POST 70
72 RedirectSeeOther = 303, 71 /// <summary>
73 // 304 Redirect: Resource still the same as before 72 /// 204 Request successful, nothing to return in the body
74 RedirectNotModified = 304, 73 /// </summary>
75 // 305 Redirect: Resource must be accessed via proxy provided 74 SuccessOkNoContent = 204,
76 // in location field 75
77 RedirectUseProxy = 305, 76 /// <summary>
78 // 307 Redirect: Resource temporarily somewhere else, location 77 /// 205 Request successful, reset displayed content
79 // might change 78 /// </summary>
80 RedirectMovedTemporarily = 307, 79 SuccessOkResetContent = 205,
81 80
82 // 4xx Client error: the client borked the request 81 /// <summary>
83 // 400 Client error: bad request, server does not grok what 82 /// 206 Request successful, partial content returned
84 // the client wants 83 /// </summary>
85 ClientErrorBadRequest = 400, 84 SuccessOkPartialContent = 206,
86 // 401 Client error: the client is not authorized, response 85
87 // provides WWW-Authenticate header field with a challenge 86 #endregion
88 ClientErrorUnauthorized = 401, 87
89 // 402 Client error: Payment required (reserved for future use) 88 #region 3xx Redirect code: user agent needs to go somewhere else
90 ClientErrorPaymentRequired = 402, 89
91 // 403 Client error: Server understood request, will not 90 /// <summary>
92 // deliver, do not try again. 91 /// 300 Redirect: different presentation forms available, take a pick
93 ClientErrorForbidden = 403, 92 /// </summary>
94 // 404 Client error: Server cannot find anything matching the 93 RedirectMultipleChoices = 300,
95 // client request. 94
96 ClientErrorNotFound = 404, 95 /// <summary>
97 // 405 Client error: The method specified by the client in the 96 /// 301 Redirect: requested resource has moved and now lives somewhere else
98 // request is not allowed for the resource requested 97 /// </summary>
99 ClientErrorMethodNotAllowed = 405, 98 RedirectMovedPermanently = 301,
100 // 406 Client error: Server cannot generate suitable response 99
101 // for the resource and content characteristics requested by 100 /// <summary>
102 // the client 101 /// 302 Redirect: Resource temporarily somewhere else, location might change
103 ClientErrorNotAcceptable = 406, 102 /// </summary>
104 // 407 Client error: Similar to 401, Server requests that 103 RedirectFound = 302,
105 // client authenticate itself with the proxy first 104
106 ClientErrorProxyAuthRequired = 407, 105 /// <summary>
107 // 408 Client error: Server got impatient with client and 106 /// 303 Redirect: See other as result of a POST
108 // decided to give up waiting for the client's request to 107 /// </summary>
109 // arrive 108 RedirectSeeOther = 303,
110 ClientErrorRequestTimeout = 408, 109
111 // 409 Client error: Server could not fulfill the request for 110 /// <summary>
112 // a resource as there is a conflict with the current state of 111 /// 304 Redirect: Resource still the same as before
113 // the resource but thinks client can do something about this 112 /// </summary>
114 ClientErrorConflict = 409, 113 RedirectNotModified = 304,
115 // 410 Client error: The resource has moved somewhere else, 114
116 // but server has no clue where. 115 /// <summary>
117 ClientErrorGone = 410, 116 /// 305 Redirect: Resource must be accessed via proxy provided in location field
118 // 411 Client error: The server is picky again and insists on 117 /// </summary>
119 // having a content-length header field in the request 118 RedirectUseProxy = 305,
120 ClientErrorLengthRequired = 411, 119
121 // 412 Client error: one or more preconditions supplied in the 120 /// <summary>
122 // client's request is false 121 /// 307 Redirect: Resource temporarily somewhere else, location might change
123 ClientErrorPreconditionFailed = 412, 122 /// </summary>
124 // 413 Client error: For fear of reflux, the server refuses to 123 RedirectMovedTemporarily = 307,
125 // swallow that much data. 124
126 ClientErrorRequestEntityToLarge = 413, 125 #endregion
127 // 414 Client error: The server considers the Request-URI to 126
128 // be indecently long and refuses to even look at it. 127 #region 4xx Client error: the client borked the request
129 ClientErrorRequestURITooLong = 414, 128
130 // 415 Client error: The server has no clue about the media 129 /// <summary>
131 // type requested by the client (contrary to popular belief it 130 /// 400 Client error: bad request, server does not grok what the client wants
132 // is not a warez server) 131 /// </summary>
133 ClientErrorUnsupportedMediaType = 415, 132 ClientErrorBadRequest = 400,
134 // 416 Client error: The requested range cannot be delivered 133
135 // by the server. 134 /// <summary>
135 /// 401 Client error: the client is not authorized, response provides WWW-Authenticate header field with a challenge
136 /// </summary>
137 ClientErrorUnauthorized = 401,
138
139 /// <summary>
140 /// 402 Client error: Payment required (reserved for future use)
141 /// </summary>
142 ClientErrorPaymentRequired = 402,
143
144 /// <summary>
145 /// 403 Client error: Server understood request, will not deliver, do not try again.
146 ClientErrorForbidden = 403,
147
148 /// <summary>
149 /// 404 Client error: Server cannot find anything matching the client request.
150 /// </summary>
151 ClientErrorNotFound = 404,
152
153 /// <summary>
154 /// 405 Client error: The method specified by the client in the request is not allowed for the resource requested
155 /// </summary>
156 ClientErrorMethodNotAllowed = 405,
157
158 /// <summary>
159 /// 406 Client error: Server cannot generate suitable response for the resource and content characteristics requested by the client
160 /// </summary>
161 ClientErrorNotAcceptable = 406,
162
163 /// <summary>
164 /// 407 Client error: Similar to 401, Server requests that client authenticate itself with the proxy first
165 /// </summary>
166 ClientErrorProxyAuthRequired = 407,
167
168 /// <summary>
169 /// 408 Client error: Server got impatient with client and decided to give up waiting for the client's request to arrive
170 /// </summary>
171 ClientErrorRequestTimeout = 408,
172
173 /// <summary>
174 /// 409 Client error: Server could not fulfill the request for a resource as there is a conflict with the current state of the resource but thinks client can do something about this
175 /// </summary>
176 ClientErrorConflict = 409,
177
178 /// <summary>
179 /// 410 Client error: The resource has moved somewhere else, but server has no clue where.
180 /// </summary>
181 ClientErrorGone = 410,
182
183 /// <summary>
184 /// 411 Client error: The server is picky again and insists on having a content-length header field in the request
185 /// </summary>
186 ClientErrorLengthRequired = 411,
187
188 /// <summary>
189 /// 412 Client error: one or more preconditions supplied in the client's request is false
190 /// </summary>
191 ClientErrorPreconditionFailed = 412,
192
193 /// <summary>
194 /// 413 Client error: For fear of reflux, the server refuses to swallow that much data.
195 /// </summary>
196 ClientErrorRequestEntityToLarge = 413,
197
198 /// <summary>
199 /// 414 Client error: The server considers the Request-URI to be indecently long and refuses to even look at it.
200 /// </summary>
201 ClientErrorRequestURITooLong = 414,
202
203 /// <summary>
204 /// 415 Client error: The server has no clue about the media type requested by the client (contrary to popular belief it is not a warez server)
205 /// </summary>
206 ClientErrorUnsupportedMediaType = 415,
207
208 /// <summary>
209 /// 416 Client error: The requested range cannot be delivered by the server.
210 /// </summary>
136 ClientErrorRequestRangeNotSatisfiable = 416, 211 ClientErrorRequestRangeNotSatisfiable = 416,
137 // 417 Client error: The expectations of the client as 212
138 // expressed in one or more Expect header fields cannot be met 213 /// <summary>
139 // by the server, the server is awfully sorry about this. 214 /// 417 Client error: The expectations of the client as expressed in one or more Expect header fields cannot be met by the server, the server is awfully sorry about this.
140 ClientErrorExpectationFailed = 417, 215 /// </summary>
141 // 499 Client error: Wildcard error. 216 ClientErrorExpectationFailed = 417,
142 ClientErrorJoker = 499, 217
143 218 /// <summary>
144 // 5xx Server errors (rare) 219 /// 428 Client error :The 428 status code indicates that the origin server requires the request to be conditional.
145 // 500 Server error: something really strange and unexpected 220 /// </summary>
146 // happened 221 ClientErrorPreconditionRequired = 428,
147 ServerErrorInternalError = 500, 222
148 // 501 Server error: The server does not do the functionality 223 /// <summary>
149 // required to carry out the client request. not at 224 /// 429 Client error: The 429 status code indicates that the user has sent too many requests in a given amount of time ("rate limiting").
150 // all. certainly not before breakfast. but also not after 225 /// </summary>
151 // breakfast. 226 ClientErrorTooManyRequests = 429,
152 ServerErrorNotImplemented = 501, 227
153 // 502 Server error: While acting as a proxy or a gateway, the 228 /// <summary>
154 // server got ditched by the upstream server and as a 229 /// 431 Client error: The 431 status code indicates that the server is unwilling to process the request because its header fields are too large. The request MAY be resubmitted after reducing the size of the request header fields.
155 // consequence regretfully cannot fulfill the client's request 230 /// </summary>
156 ServerErrorBadGateway = 502, 231 ClientErrorRequestHeaderFieldsTooLarge = 431,
157 // 503 Server error: Due to unforseen circumstances the server 232
158 // cannot currently deliver the service requested. Retry-After 233 /// <summary>
159 // header might indicate when to try again. 234 /// 499 Client error: Wildcard error.
160 ServerErrorServiceUnavailable = 503, 235 /// </summary>
161 // 504 Server error: The server blames the upstream server 236 ClientErrorJoker = 499,
162 // for not being able to deliver the service requested and 237
163 // claims that the upstream server is too slow delivering the 238 #endregion
164 // goods. 239
165 ServerErrorGatewayTimeout = 504, 240 #region 5xx Server errors (rare)
166 // 505 Server error: The server does not support the HTTP 241
167 // version conveyed in the client's request. 242 /// <summary>
168 ServerErrorHttpVersionNotSupported = 505, 243 /// 500 Server error: something really strange and unexpected happened
244 /// </summary>
245 ServerErrorInternalError = 500,
246
247 /// <summary>
248 /// 501 Server error: The server does not do the functionality required to carry out the client request. not at all. certainly not before breakfast. but also not after breakfast.
249 /// </summary>
250 ServerErrorNotImplemented = 501,
251
252 /// <summary>
253 /// 502 Server error: While acting as a proxy or a gateway, the server got ditched by the upstream server and as a consequence regretfully cannot fulfill the client's request
254 /// </summary>
255 ServerErrorBadGateway = 502,
256
257 /// <summary>
258 /// 503 Server error: Due to unforseen circumstances the server cannot currently deliver the service requested. Retry-After header might indicate when to try again.
259 /// </summary>
260 ServerErrorServiceUnavailable = 503,
261
262 /// <summary>
263 /// 504 Server error: The server blames the upstream server for not being able to deliver the service requested and claims that the upstream server is too slow delivering the goods.
264 /// </summary>
265 ServerErrorGatewayTimeout = 504,
266
267 /// <summary>
268 /// 505 Server error: The server does not support the HTTP version conveyed in the client's request.
269 /// </summary>
270 ServerErrorHttpVersionNotSupported = 505,
271
272 /// <summary>
273 /// 511 Server error: The 511 status code indicates that the client needs to authenticate to gain network access.
274 /// </summary>
275 ServerErrorNetworkAuthenticationRequired = 511,
276
277 #endregion
169 } 278 }
170} 279}
diff --git a/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs b/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs
index 0062d4e..f96fd1f 100644
--- a/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs
+++ b/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs
@@ -66,6 +66,7 @@ namespace OpenSim.Framework.Servers.HttpServer
66 ThreadPriority.Normal, 66 ThreadPriority.Normal,
67 false, 67 false,
68 true, 68 true,
69 null,
69 int.MaxValue); 70 int.MaxValue);
70 } 71 }
71 72
@@ -75,6 +76,7 @@ namespace OpenSim.Framework.Servers.HttpServer
75 ThreadPriority.Normal, 76 ThreadPriority.Normal,
76 false, 77 false,
77 true, 78 true,
79 null,
78 1000 * 60 * 10); 80 1000 * 60 * 10);
79 } 81 }
80 82
diff --git a/OpenSim/Framework/Servers/HttpServer/RestDeserialiseHandler.cs b/OpenSim/Framework/Servers/HttpServer/RestDeserialiseHandler.cs
index a467a83..07082a8 100644
--- a/OpenSim/Framework/Servers/HttpServer/RestDeserialiseHandler.cs
+++ b/OpenSim/Framework/Servers/HttpServer/RestDeserialiseHandler.cs
@@ -39,7 +39,11 @@ namespace OpenSim.Framework.Servers.HttpServer
39 private RestDeserialiseMethod<TRequest, TResponse> m_method; 39 private RestDeserialiseMethod<TRequest, TResponse> m_method;
40 40
41 public RestDeserialiseHandler(string httpMethod, string path, RestDeserialiseMethod<TRequest, TResponse> method) 41 public RestDeserialiseHandler(string httpMethod, string path, RestDeserialiseMethod<TRequest, TResponse> method)
42 : base(httpMethod, path) 42 : this(httpMethod, path, method, null, null) {}
43
44 public RestDeserialiseHandler(
45 string httpMethod, string path, RestDeserialiseMethod<TRequest, TResponse> method, string name, string description)
46 : base(httpMethod, path, name, description)
43 { 47 {
44 m_method = method; 48 m_method = method;
45 } 49 }
diff --git a/OpenSim/Framework/Servers/HttpServer/RestHTTPHandler.cs b/OpenSim/Framework/Servers/HttpServer/RestHTTPHandler.cs
index 1f23cac..7f89839 100644
--- a/OpenSim/Framework/Servers/HttpServer/RestHTTPHandler.cs
+++ b/OpenSim/Framework/Servers/HttpServer/RestHTTPHandler.cs
@@ -38,19 +38,25 @@ namespace OpenSim.Framework.Servers.HttpServer
38 get { return m_dhttpMethod; } 38 get { return m_dhttpMethod; }
39 } 39 }
40 40
41 public override Hashtable Handle(string path, Hashtable request) 41 public RestHTTPHandler(string httpMethod, string path, GenericHTTPMethod dhttpMethod)
42 : base(httpMethod, path)
42 { 43 {
44 m_dhttpMethod = dhttpMethod;
45 }
46
47 public RestHTTPHandler(
48 string httpMethod, string path, GenericHTTPMethod dhttpMethod, string name, string description)
49 : base(httpMethod, path, name, description)
50 {
51 m_dhttpMethod = dhttpMethod;
52 }
43 53
54 public override Hashtable Handle(string path, Hashtable request)
55 {
44 string param = GetParam(path); 56 string param = GetParam(path);
45 request.Add("param", param); 57 request.Add("param", param);
46 request.Add("path", path); 58 request.Add("path", path);
47 return m_dhttpMethod(request); 59 return m_dhttpMethod(request);
48 } 60 }
49
50 public RestHTTPHandler(string httpMethod, string path, GenericHTTPMethod dhttpMethod)
51 : base(httpMethod, path)
52 {
53 m_dhttpMethod = dhttpMethod;
54 }
55 } 61 }
56} 62}
diff --git a/OpenSim/Framework/Servers/HttpServer/RestStreamHandler.cs b/OpenSim/Framework/Servers/HttpServer/RestStreamHandler.cs
index d2c4002..1f17fee 100644
--- a/OpenSim/Framework/Servers/HttpServer/RestStreamHandler.cs
+++ b/OpenSim/Framework/Servers/HttpServer/RestStreamHandler.cs
@@ -39,6 +39,15 @@ namespace OpenSim.Framework.Servers.HttpServer
39 get { return m_restMethod; } 39 get { return m_restMethod; }
40 } 40 }
41 41
42 public RestStreamHandler(string httpMethod, string path, RestMethod restMethod)
43 : this(httpMethod, path, restMethod, null, null) {}
44
45 public RestStreamHandler(string httpMethod, string path, RestMethod restMethod, string name, string description)
46 : base(httpMethod, path, name, description)
47 {
48 m_restMethod = restMethod;
49 }
50
42 public override byte[] Handle(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) 51 public override byte[] Handle(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
43 { 52 {
44 Encoding encoding = Encoding.UTF8; 53 Encoding encoding = Encoding.UTF8;
@@ -52,10 +61,5 @@ namespace OpenSim.Framework.Servers.HttpServer
52 61
53 return Encoding.UTF8.GetBytes(responseString); 62 return Encoding.UTF8.GetBytes(responseString);
54 } 63 }
55
56 public RestStreamHandler(string httpMethod, string path, RestMethod restMethod) : base(httpMethod, path)
57 {
58 m_restMethod = restMethod;
59 }
60 } 64 }
61} 65}
diff --git a/OpenSim/Framework/TaskInventoryDictionary.cs b/OpenSim/Framework/TaskInventoryDictionary.cs
index 814758a..4d07746 100644
--- a/OpenSim/Framework/TaskInventoryDictionary.cs
+++ b/OpenSim/Framework/TaskInventoryDictionary.cs
@@ -52,10 +52,10 @@ namespace OpenSim.Framework
52 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 52 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
53 53
54 private Thread LockedByThread; 54 private Thread LockedByThread;
55 private string WriterStack; 55// private string WriterStack;
56 56
57 private Dictionary<Thread, string> ReadLockers = 57// private Dictionary<Thread, string> ReadLockers =
58 new Dictionary<Thread, string>(); 58// new Dictionary<Thread, string>();
59 59
60 /// <value> 60 /// <value>
61 /// An advanced lock for inventory data 61 /// An advanced lock for inventory data
@@ -98,14 +98,25 @@ namespace OpenSim.Framework
98 m_log.Error("[TaskInventoryDictionary] Recursive read lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue."); 98 m_log.Error("[TaskInventoryDictionary] Recursive read lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue.");
99 try 99 try
100 { 100 {
101 StackTrace stackTrace = new StackTrace(); // get call stack 101 // That call stack is useful for end users only. RealProgrammers need a full dump. Commented.
102 StackFrame[] stackFrames = stackTrace.GetFrames(); // get method calls (frames) 102 // StackTrace stackTrace = new StackTrace(); // get call stack
103 // StackFrame[] stackFrames = stackTrace.GetFrames(); // get method calls (frames)
104 //
105 // // write call stack method names
106 // foreach (StackFrame stackFrame in stackFrames)
107 // {
108 // m_log.Error("[SceneObjectGroup.m_parts] "+(stackFrame.GetMethod().Name)); // write method name
109 // }
103 110
104 // write call stack method names 111 // The below is far more useful
105 foreach (StackFrame stackFrame in stackFrames) 112// System.Console.WriteLine("------------------------------------------");
106 { 113// System.Console.WriteLine("My call stack:\n" + Environment.StackTrace);
107 m_log.Error("[SceneObjectGroup.m_parts] "+(stackFrame.GetMethod().Name)); // write method name 114// System.Console.WriteLine("------------------------------------------");
108 } 115// foreach (KeyValuePair<Thread, string> kvp in ReadLockers)
116// {
117// System.Console.WriteLine("Locker name {0} call stack:\n" + kvp.Value, kvp.Key.Name);
118// System.Console.WriteLine("------------------------------------------");
119// }
109 } 120 }
110 catch 121 catch
111 {} 122 {}
@@ -114,6 +125,16 @@ namespace OpenSim.Framework
114 if (m_itemLock.RecursiveWriteCount > 0) 125 if (m_itemLock.RecursiveWriteCount > 0)
115 { 126 {
116 m_log.Error("[TaskInventoryDictionary] Recursive write lock requested. This should not happen and means something needs to be fixed."); 127 m_log.Error("[TaskInventoryDictionary] Recursive write lock requested. This should not happen and means something needs to be fixed.");
128// try
129// {
130// System.Console.WriteLine("------------------------------------------");
131// System.Console.WriteLine("My call stack:\n" + Environment.StackTrace);
132// System.Console.WriteLine("------------------------------------------");
133// System.Console.WriteLine("Locker's call stack:\n" + WriterStack);
134// System.Console.WriteLine("------------------------------------------");
135// }
136// catch
137// {}
117 m_itemLock.ExitWriteLock(); 138 m_itemLock.ExitWriteLock();
118 } 139 }
119 140
@@ -123,15 +144,16 @@ namespace OpenSim.Framework
123 if (m_itemLock.IsWriteLockHeld) 144 if (m_itemLock.IsWriteLockHeld)
124 { 145 {
125 m_itemLock = new System.Threading.ReaderWriterLockSlim(); 146 m_itemLock = new System.Threading.ReaderWriterLockSlim();
126 System.Console.WriteLine("------------------------------------------"); 147// System.Console.WriteLine("------------------------------------------");
127 System.Console.WriteLine("My call stack:\n" + Environment.StackTrace); 148// System.Console.WriteLine("My call stack:\n" + Environment.StackTrace);
128 System.Console.WriteLine("------------------------------------------"); 149// System.Console.WriteLine("------------------------------------------");
129 System.Console.WriteLine("Locker's call stack:\n" + WriterStack); 150// System.Console.WriteLine("Locker's call stack:\n" + WriterStack);
130 System.Console.WriteLine("------------------------------------------"); 151// System.Console.WriteLine("------------------------------------------");
131 LockedByThread = null; 152// LockedByThread = null;
132 ReadLockers.Clear(); 153// ReadLockers.Clear();
133 } 154 }
134 } 155 }
156// ReadLockers[Thread.CurrentThread] = Environment.StackTrace;
135 } 157 }
136 else 158 else
137 { 159 {
@@ -139,6 +161,8 @@ namespace OpenSim.Framework
139 { 161 {
140 m_itemLock.ExitReadLock(); 162 m_itemLock.ExitReadLock();
141 } 163 }
164// if (m_itemLock.RecursiveReadCount == 0)
165// ReadLockers.Remove(Thread.CurrentThread);
142 } 166 }
143 } 167 }
144 168
@@ -158,6 +182,7 @@ namespace OpenSim.Framework
158 if (m_itemLock.RecursiveWriteCount > 0) 182 if (m_itemLock.RecursiveWriteCount > 0)
159 { 183 {
160 m_log.Error("[TaskInventoryDictionary] Recursive write lock requested. This should not happen and means something needs to be fixed."); 184 m_log.Error("[TaskInventoryDictionary] Recursive write lock requested. This should not happen and means something needs to be fixed.");
185
161 m_itemLock.ExitWriteLock(); 186 m_itemLock.ExitWriteLock();
162 } 187 }
163 while (!m_itemLock.TryEnterWriteLock(60000)) 188 while (!m_itemLock.TryEnterWriteLock(60000))
@@ -165,30 +190,30 @@ namespace OpenSim.Framework
165 if (m_itemLock.IsWriteLockHeld) 190 if (m_itemLock.IsWriteLockHeld)
166 { 191 {
167 m_log.Error("Thread lock detected while trying to aquire WRITE lock in TaskInventoryDictionary. Locked by thread " + LockedByThread.Name + ". I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed."); 192 m_log.Error("Thread lock detected while trying to aquire WRITE lock in TaskInventoryDictionary. Locked by thread " + LockedByThread.Name + ". I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed.");
168 System.Console.WriteLine("------------------------------------------"); 193// System.Console.WriteLine("------------------------------------------");
169 System.Console.WriteLine("My call stack:\n" + Environment.StackTrace); 194// System.Console.WriteLine("My call stack:\n" + Environment.StackTrace);
170 System.Console.WriteLine("------------------------------------------"); 195// System.Console.WriteLine("------------------------------------------");
171 System.Console.WriteLine("Locker's call stack:\n" + WriterStack); 196// System.Console.WriteLine("Locker's call stack:\n" + WriterStack);
172 System.Console.WriteLine("------------------------------------------"); 197// System.Console.WriteLine("------------------------------------------");
173 } 198 }
174 else 199 else
175 { 200 {
176 m_log.Error("Thread lock detected while trying to aquire WRITE lock in TaskInventoryDictionary. Locked by a reader. I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed."); 201 m_log.Error("Thread lock detected while trying to aquire WRITE lock in TaskInventoryDictionary. Locked by a reader. I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed.");
177 System.Console.WriteLine("------------------------------------------"); 202// System.Console.WriteLine("------------------------------------------");
178 System.Console.WriteLine("My call stack:\n" + Environment.StackTrace); 203// System.Console.WriteLine("My call stack:\n" + Environment.StackTrace);
179 System.Console.WriteLine("------------------------------------------"); 204// System.Console.WriteLine("------------------------------------------");
180 foreach (KeyValuePair<Thread, string> kvp in ReadLockers) 205// foreach (KeyValuePair<Thread, string> kvp in ReadLockers)
181 { 206// {
182 System.Console.WriteLine("Locker name {0} call stack:\n" + kvp.Value, kvp.Key.Name); 207// System.Console.WriteLine("Locker name {0} call stack:\n" + kvp.Value, kvp.Key.Name);
183 System.Console.WriteLine("------------------------------------------"); 208// System.Console.WriteLine("------------------------------------------");
184 } 209// }
185 } 210 }
186 m_itemLock = new System.Threading.ReaderWriterLockSlim(); 211 m_itemLock = new System.Threading.ReaderWriterLockSlim();
187 ReadLockers.Clear(); 212// ReadLockers.Clear();
188 } 213 }
189 214
190 LockedByThread = Thread.CurrentThread; 215 LockedByThread = Thread.CurrentThread;
191 WriterStack = Environment.StackTrace; 216// WriterStack = Environment.StackTrace;
192 } 217 }
193 else 218 else
194 { 219 {
diff --git a/OpenSim/Framework/TaskInventoryItem.cs b/OpenSim/Framework/TaskInventoryItem.cs
index 7ef8bf7..fb818ee 100644
--- a/OpenSim/Framework/TaskInventoryItem.cs
+++ b/OpenSim/Framework/TaskInventoryItem.cs
@@ -26,6 +26,8 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Reflection;
30using log4net;
29using OpenMetaverse; 31using OpenMetaverse;
30 32
31namespace OpenSim.Framework 33namespace OpenSim.Framework
@@ -35,6 +37,8 @@ namespace OpenSim.Framework
35 /// </summary> 37 /// </summary>
36 public class TaskInventoryItem : ICloneable 38 public class TaskInventoryItem : ICloneable
37 { 39 {
40// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
41
38 /// <summary> 42 /// <summary>
39 /// XXX This should really be factored out into some constants class. 43 /// XXX This should really be factored out into some constants class.
40 /// </summary> 44 /// </summary>
@@ -334,12 +338,18 @@ namespace OpenSim.Framework
334 } 338 }
335 } 339 }
336 340
337 public bool OwnerChanged { 341 public bool OwnerChanged
338 get { 342 {
343 get
344 {
339 return _ownerChanged; 345 return _ownerChanged;
340 } 346 }
341 set { 347 set
348 {
342 _ownerChanged = value; 349 _ownerChanged = value;
350// m_log.DebugFormat(
351// "[TASK INVENTORY ITEM]: Owner changed set {0} for {1} {2} owned by {3}",
352// _ownerChanged, Name, ItemID, OwnerID);
343 } 353 }
344 } 354 }
345 355
diff --git a/OpenSim/Framework/Tests/MundaneFrameworkTests.cs b/OpenSim/Framework/Tests/MundaneFrameworkTests.cs
index 34a3f15..6fde488 100644
--- a/OpenSim/Framework/Tests/MundaneFrameworkTests.cs
+++ b/OpenSim/Framework/Tests/MundaneFrameworkTests.cs
@@ -227,10 +227,10 @@ namespace OpenSim.Framework.Tests
227 es.AddEstateManager(UUID.Zero); 227 es.AddEstateManager(UUID.Zero);
228 228
229 es.AddEstateManager(bannedUserId); 229 es.AddEstateManager(bannedUserId);
230 Assert.IsTrue(es.IsEstateManager(bannedUserId), "bannedUserId should be EstateManager but isn't."); 230 Assert.IsTrue(es.IsEstateManagerOrOwner(bannedUserId), "bannedUserId should be EstateManager but isn't.");
231 231
232 es.RemoveEstateManager(bannedUserId); 232 es.RemoveEstateManager(bannedUserId);
233 Assert.IsFalse(es.IsEstateManager(bannedUserId), "bannedUserID is estateManager but shouldn't be"); 233 Assert.IsFalse(es.IsEstateManagerOrOwner(bannedUserId), "bannedUserID is estateManager but shouldn't be");
234 234
235 Assert.IsFalse(es.HasAccess(bannedUserId), "bannedUserID has access but shouldn't"); 235 Assert.IsFalse(es.HasAccess(bannedUserId), "bannedUserID has access but shouldn't");
236 236
diff --git a/OpenSim/Framework/Tests/UtilTest.cs b/OpenSim/Framework/Tests/UtilTest.cs
index 1ca35df..f0d2a3f 100644
--- a/OpenSim/Framework/Tests/UtilTest.cs
+++ b/OpenSim/Framework/Tests/UtilTest.cs
@@ -214,16 +214,13 @@ namespace OpenSim.Framework.Tests
214 214
215 for (int i = 0; i < contenttypes.Length; i++) 215 for (int i = 0; i < contenttypes.Length; i++)
216 { 216 {
217 if (SLUtil.ContentTypeToSLAssetType(contenttypes[i]) == 18) 217 int expected;
218 { 218 if (contenttypes[i] == "image/tga")
219 Assert.That(contenttypes[i] == "image/tga"); 219 expected = 12; // if we know only the content-type "image/tga", then we assume the asset type is TextureTGA; not ImageTGA
220 }
221 else 220 else
222 { 221 expected = assettypes[i];
223 Assert.That(SLUtil.ContentTypeToSLAssetType(contenttypes[i]) == assettypes[i], 222 Assert.AreEqual(expected, SLUtil.ContentTypeToSLAssetType(contenttypes[i]),
224 "Expecting {0} but got {1}", assettypes[i], 223 String.Format("Incorrect AssetType mapped from Content-Type {0}", contenttypes[i]));
225 SLUtil.ContentTypeToSLAssetType(contenttypes[i]));
226 }
227 } 224 }
228 225
229 int[] inventorytypes = new int[] {-1,0,1,2,3,6,7,8,9,10,15,17,18,20}; 226 int[] inventorytypes = new int[] {-1,0,1,2,3,6,7,8,9,10,15,17,18,20};
@@ -237,7 +234,7 @@ namespace OpenSim.Framework.Tests
237 "application/vnd.ll.primitive", 234 "application/vnd.ll.primitive",
238 "application/vnd.ll.notecard", 235 "application/vnd.ll.notecard",
239 "application/vnd.ll.folder", 236 "application/vnd.ll.folder",
240 "application/octet-stream", 237 "application/vnd.ll.rootfolder",
241 "application/vnd.ll.lsltext", 238 "application/vnd.ll.lsltext",
242 "image/x-j2c", 239 "image/x-j2c",
243 "application/vnd.ll.primitive", 240 "application/vnd.ll.primitive",
@@ -247,7 +244,8 @@ namespace OpenSim.Framework.Tests
247 244
248 for (int i=0;i<inventorytypes.Length;i++) 245 for (int i=0;i<inventorytypes.Length;i++)
249 { 246 {
250 Assert.That(SLUtil.SLInvTypeToContentType(inventorytypes[i]) == invcontenttypes[i], "Expected {0}, Got {1}", invcontenttypes[i], SLUtil.SLInvTypeToContentType(inventorytypes[i])); 247 Assert.AreEqual(invcontenttypes[i], SLUtil.SLInvTypeToContentType(inventorytypes[i]),
248 String.Format("Incorrect Content-Type mapped from InventoryType {0}", inventorytypes[i]));
251 } 249 }
252 250
253 invcontenttypes = new string[] 251 invcontenttypes = new string[]
@@ -280,7 +278,8 @@ namespace OpenSim.Framework.Tests
280 278
281 for (int i = 0; i < invtypes.Length; i++) 279 for (int i = 0; i < invtypes.Length; i++)
282 { 280 {
283 Assert.That(SLUtil.ContentTypeToSLInvType(invcontenttypes[i]) == invtypes[i], "Expected {0}, Got {1}", invtypes[i], SLUtil.ContentTypeToSLInvType(invcontenttypes[i])); 281 Assert.AreEqual(invtypes[i], SLUtil.ContentTypeToSLInvType(invcontenttypes[i]),
282 String.Format("Incorrect InventoryType mapped from Content-Type {0}", invcontenttypes[i]));
284 } 283 }
285 } 284 }
286 } 285 }
diff --git a/OpenSim/Framework/Watchdog.cs b/OpenSim/Framework/Watchdog.cs
index 881b6aa..68bf477 100644
--- a/OpenSim/Framework/Watchdog.cs
+++ b/OpenSim/Framework/Watchdog.cs
@@ -42,7 +42,7 @@ namespace OpenSim.Framework
42 const double WATCHDOG_INTERVAL_MS = 2500.0d; 42 const double WATCHDOG_INTERVAL_MS = 2500.0d;
43 43
44 /// <summary>Maximum timeout in milliseconds before a thread is considered dead</summary> 44 /// <summary>Maximum timeout in milliseconds before a thread is considered dead</summary>
45 const int WATCHDOG_TIMEOUT_MS = 5000; 45 public const int WATCHDOG_TIMEOUT_MS = 5000;
46 46
47 [System.Diagnostics.DebuggerDisplay("{Thread.Name}")] 47 [System.Diagnostics.DebuggerDisplay("{Thread.Name}")]
48 public class ThreadWatchdogInfo 48 public class ThreadWatchdogInfo
@@ -58,7 +58,7 @@ namespace OpenSim.Framework
58 public int FirstTick { get; private set; } 58 public int FirstTick { get; private set; }
59 59
60 /// <summary> 60 /// <summary>
61 /// First time this heartbeat update was invoked 61 /// Last time this heartbeat update was invoked
62 /// </summary> 62 /// </summary>
63 public int LastTick { get; set; } 63 public int LastTick { get; set; }
64 64
@@ -77,6 +77,11 @@ namespace OpenSim.Framework
77 /// </summary> 77 /// </summary>
78 public bool AlarmIfTimeout { get; set; } 78 public bool AlarmIfTimeout { get; set; }
79 79
80 /// <summary>
81 /// Method execute if alarm goes off. If null then no alarm method is fired.
82 /// </summary>
83 public Func<string> AlarmMethod { get; set; }
84
80 public ThreadWatchdogInfo(Thread thread, int timeout) 85 public ThreadWatchdogInfo(Thread thread, int timeout)
81 { 86 {
82 Thread = thread; 87 Thread = thread;
@@ -87,16 +92,10 @@ namespace OpenSim.Framework
87 } 92 }
88 93
89 /// <summary> 94 /// <summary>
90 /// This event is called whenever a tracked thread is stopped or 95 /// This event is called whenever a tracked thread is
91 /// has not called UpdateThread() in time 96 /// stopped or has not called UpdateThread() in time<
92 /// </summary> 97 /// /summary>
93 /// <param name="thread">The thread that has been identified as dead</param> 98 public static event Action<ThreadWatchdogInfo> OnWatchdogTimeout;
94 /// <param name="lastTick">The last time this thread called UpdateThread()</param>
95 public delegate void WatchdogTimeout(Thread thread, int lastTick);
96
97 /// <summary>This event is called whenever a tracked thread is
98 /// stopped or has not called UpdateThread() in time</summary>
99 public static event WatchdogTimeout OnWatchdogTimeout;
100 99
101 private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); 100 private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
102 private static Dictionary<int, ThreadWatchdogInfo> m_threads; 101 private static Dictionary<int, ThreadWatchdogInfo> m_threads;
@@ -123,7 +122,7 @@ namespace OpenSim.Framework
123 public static Thread StartThread( 122 public static Thread StartThread(
124 ThreadStart start, string name, ThreadPriority priority, bool isBackground, bool alarmIfTimeout) 123 ThreadStart start, string name, ThreadPriority priority, bool isBackground, bool alarmIfTimeout)
125 { 124 {
126 return StartThread(start, name, priority, isBackground, alarmIfTimeout, WATCHDOG_TIMEOUT_MS); 125 return StartThread(start, name, priority, isBackground, alarmIfTimeout, null, WATCHDOG_TIMEOUT_MS);
127 } 126 }
128 127
129 /// <summary> 128 /// <summary>
@@ -135,17 +134,24 @@ namespace OpenSim.Framework
135 /// <param name="isBackground">True to run this thread as a background 134 /// <param name="isBackground">True to run this thread as a background
136 /// thread, otherwise false</param> 135 /// thread, otherwise false</param>
137 /// <param name="alarmIfTimeout">Trigger an alarm function is we have timed out</param> 136 /// <param name="alarmIfTimeout">Trigger an alarm function is we have timed out</param>
137 /// <param name="alarmMethod">
138 /// Alarm method to call if alarmIfTimeout is true and there is a timeout.
139 /// Normally, this will just return some useful debugging information.
140 /// </param>
138 /// <param name="timeout">Number of milliseconds to wait until we issue a warning about timeout.</param> 141 /// <param name="timeout">Number of milliseconds to wait until we issue a warning about timeout.</param>
139 /// <returns>The newly created Thread object</returns> 142 /// <returns>The newly created Thread object</returns>
140 public static Thread StartThread( 143 public static Thread StartThread(
141 ThreadStart start, string name, ThreadPriority priority, bool isBackground, bool alarmIfTimeout, int timeout) 144 ThreadStart start, string name, ThreadPriority priority, bool isBackground,
145 bool alarmIfTimeout, Func<string> alarmMethod, int timeout)
142 { 146 {
143 Thread thread = new Thread(start); 147 Thread thread = new Thread(start);
144 thread.Name = name; 148 thread.Name = name;
145 thread.Priority = priority; 149 thread.Priority = priority;
146 thread.IsBackground = isBackground; 150 thread.IsBackground = isBackground;
147 151
148 ThreadWatchdogInfo twi = new ThreadWatchdogInfo(thread, timeout) { AlarmIfTimeout = alarmIfTimeout }; 152 ThreadWatchdogInfo twi
153 = new ThreadWatchdogInfo(thread, timeout)
154 { AlarmIfTimeout = alarmIfTimeout, AlarmMethod = alarmMethod };
149 155
150 m_log.DebugFormat( 156 m_log.DebugFormat(
151 "[WATCHDOG]: Started tracking thread {0}, ID {1}", twi.Thread.Name, twi.Thread.ManagedThreadId); 157 "[WATCHDOG]: Started tracking thread {0}, ID {1}", twi.Thread.Name, twi.Thread.ManagedThreadId);
@@ -258,7 +264,7 @@ namespace OpenSim.Framework
258 /// <param name="e"></param> 264 /// <param name="e"></param>
259 private static void WatchdogTimerElapsed(object sender, System.Timers.ElapsedEventArgs e) 265 private static void WatchdogTimerElapsed(object sender, System.Timers.ElapsedEventArgs e)
260 { 266 {
261 WatchdogTimeout callback = OnWatchdogTimeout; 267 Action<ThreadWatchdogInfo> callback = OnWatchdogTimeout;
262 268
263 if (callback != null) 269 if (callback != null)
264 { 270 {
@@ -296,7 +302,7 @@ namespace OpenSim.Framework
296 302
297 if (callbackInfos != null) 303 if (callbackInfos != null)
298 foreach (ThreadWatchdogInfo callbackInfo in callbackInfos) 304 foreach (ThreadWatchdogInfo callbackInfo in callbackInfos)
299 callback(callbackInfo.Thread, callbackInfo.LastTick); 305 callback(callbackInfo);
300 } 306 }
301 307
302 m_watchdogTimer.Start(); 308 m_watchdogTimer.Start();
diff --git a/OpenSim/Framework/WebUtil.cs b/OpenSim/Framework/WebUtil.cs
index aac575c..6a40cd5 100644
--- a/OpenSim/Framework/WebUtil.cs
+++ b/OpenSim/Framework/WebUtil.cs
@@ -53,19 +53,36 @@ namespace OpenSim.Framework
53 LogManager.GetLogger( 53 LogManager.GetLogger(
54 MethodBase.GetCurrentMethod().DeclaringType); 54 MethodBase.GetCurrentMethod().DeclaringType);
55 55
56 private static int m_requestNumber = 0; 56 /// <summary>
57 /// Request number for diagnostic purposes.
58 /// </summary>
59 public static int RequestNumber = 0;
57 60
58 // this is the header field used to communicate the local request id 61 /// <summary>
59 // used for performance and debugging 62 /// this is the header field used to communicate the local request id
63 /// used for performance and debugging
64 /// </summary>
60 public const string OSHeaderRequestID = "opensim-request-id"; 65 public const string OSHeaderRequestID = "opensim-request-id";
61 66
62 // number of milliseconds a call can take before it is considered 67 /// <summary>
63 // a "long" call for warning & debugging purposes 68 /// Number of milliseconds a call can take before it is considered
64 public const int LongCallTime = 500; 69 /// a "long" call for warning & debugging purposes
70 /// </summary>
71 public const int LongCallTime = 3000;
65 72
66 // dictionary of end points 73 /// <summary>
74 /// The maximum length of any data logged because of a long request time.
75 /// </summary>
76 /// <remarks>
77 /// This is to truncate any really large post data, such as an asset. In theory, the first section should
78 /// give us useful information about the call (which agent it relates to if applicable, etc.).
79 /// </remarks>
80 public const int MaxRequestDiagLength = 100;
81
82 /// <summary>
83 /// Dictionary of end points
84 /// </summary>
67 private static Dictionary<string,object> m_endpointSerializer = new Dictionary<string,object>(); 85 private static Dictionary<string,object> m_endpointSerializer = new Dictionary<string,object>();
68
69 86
70 private static object EndPointLock(string url) 87 private static object EndPointLock(string url)
71 { 88 {
@@ -86,8 +103,7 @@ namespace OpenSim.Framework
86 return eplock; 103 return eplock;
87 } 104 }
88 } 105 }
89 106
90
91 #region JSONRequest 107 #region JSONRequest
92 108
93 /// <summary> 109 /// <summary>
@@ -129,12 +145,13 @@ namespace OpenSim.Framework
129 145
130 private static OSDMap ServiceOSDRequestWorker(string url, OSDMap data, string method, int timeout, bool compressed) 146 private static OSDMap ServiceOSDRequestWorker(string url, OSDMap data, string method, int timeout, bool compressed)
131 { 147 {
132 int reqnum = m_requestNumber++; 148 int reqnum = RequestNumber++;
133 // m_log.DebugFormat("[WEB UTIL]: <{0}> start osd request for {1}, method {2}",reqnum,url,method); 149 // m_log.DebugFormat("[WEB UTIL]: <{0}> start osd request for {1}, method {2}",reqnum,url,method);
134 150
135 string errorMessage = "unknown error"; 151 string errorMessage = "unknown error";
136 int tickstart = Util.EnvironmentTickCount(); 152 int tickstart = Util.EnvironmentTickCount();
137 int tickdata = 0; 153 int tickdata = 0;
154 string strBuffer = null;
138 155
139 try 156 try
140 { 157 {
@@ -149,7 +166,7 @@ namespace OpenSim.Framework
149 // If there is some input, write it into the request 166 // If there is some input, write it into the request
150 if (data != null) 167 if (data != null)
151 { 168 {
152 string strBuffer = OSDParser.SerializeJsonString(data); 169 strBuffer = OSDParser.SerializeJsonString(data);
153 byte[] buffer = System.Text.Encoding.UTF8.GetBytes(strBuffer); 170 byte[] buffer = System.Text.Encoding.UTF8.GetBytes(strBuffer);
154 171
155 if (compressed) 172 if (compressed)
@@ -210,14 +227,23 @@ namespace OpenSim.Framework
210 } 227 }
211 finally 228 finally
212 { 229 {
213 // This just dumps a warning for any operation that takes more than 100 ms
214 int tickdiff = Util.EnvironmentTickCountSubtract(tickstart); 230 int tickdiff = Util.EnvironmentTickCountSubtract(tickstart);
215 if (tickdiff > LongCallTime) 231 if (tickdiff > LongCallTime)
216 m_log.DebugFormat("[WEB UTIL]: osd request <{0}> (URI:{1}, METHOD:{2}) took {3}ms overall, {4}ms writing", 232 m_log.InfoFormat(
217 reqnum,url,method,tickdiff,tickdata); 233 "[OSD REQUEST]: Slow request to <{0}> {1} {2} took {3}ms, {4}ms writing, {5}",
234 reqnum,
235 method,
236 url,
237 tickdiff,
238 tickdata,
239 strBuffer != null
240 ? (strBuffer.Length > MaxRequestDiagLength ? strBuffer.Remove(MaxRequestDiagLength) : strBuffer)
241 : "");
218 } 242 }
219 243
220 m_log.DebugFormat("[WEB UTIL]: <{0}> osd request for {1}, method {2} FAILED: {3}", reqnum, url, method, errorMessage); 244 m_log.DebugFormat(
245 "[WEB UTIL]: <{0}> osd request for {1}, method {2} FAILED: {3}", reqnum, url, method, errorMessage);
246
221 return ErrorResponseMap(errorMessage); 247 return ErrorResponseMap(errorMessage);
222 } 248 }
223 249
@@ -290,17 +316,17 @@ namespace OpenSim.Framework
290 316
291 private static OSDMap ServiceFormRequestWorker(string url, NameValueCollection data, int timeout) 317 private static OSDMap ServiceFormRequestWorker(string url, NameValueCollection data, int timeout)
292 { 318 {
293 int reqnum = m_requestNumber++; 319 int reqnum = RequestNumber++;
294 string method = (data != null && data["RequestMethod"] != null) ? data["RequestMethod"] : "unknown"; 320 string method = (data != null && data["RequestMethod"] != null) ? data["RequestMethod"] : "unknown";
295 // m_log.DebugFormat("[WEB UTIL]: <{0}> start form request for {1}, method {2}",reqnum,url,method); 321 // m_log.DebugFormat("[WEB UTIL]: <{0}> start form request for {1}, method {2}",reqnum,url,method);
296 322
297 string errorMessage = "unknown error"; 323 string errorMessage = "unknown error";
298 int tickstart = Util.EnvironmentTickCount(); 324 int tickstart = Util.EnvironmentTickCount();
299 int tickdata = 0; 325 int tickdata = 0;
326 string queryString = null;
300 327
301 try 328 try
302 { 329 {
303
304 HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url); 330 HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
305 request.Method = "POST"; 331 request.Method = "POST";
306 request.Timeout = timeout; 332 request.Timeout = timeout;
@@ -311,7 +337,7 @@ namespace OpenSim.Framework
311 337
312 if (data != null) 338 if (data != null)
313 { 339 {
314 string queryString = BuildQueryString(data); 340 queryString = BuildQueryString(data);
315 byte[] buffer = System.Text.Encoding.UTF8.GetBytes(queryString); 341 byte[] buffer = System.Text.Encoding.UTF8.GetBytes(queryString);
316 342
317 request.ContentLength = buffer.Length; 343 request.ContentLength = buffer.Length;
@@ -354,11 +380,20 @@ namespace OpenSim.Framework
354 { 380 {
355 int tickdiff = Util.EnvironmentTickCountSubtract(tickstart); 381 int tickdiff = Util.EnvironmentTickCountSubtract(tickstart);
356 if (tickdiff > LongCallTime) 382 if (tickdiff > LongCallTime)
357 m_log.InfoFormat("[WEB UTIL]: form request <{0}> (URI:{1}, METHOD:{2}) took {3}ms overall, {4}ms writing", 383 m_log.InfoFormat(
358 reqnum,url,method,tickdiff,tickdata); 384 "[SERVICE FORM]: Slow request to <{0}> {1} {2} took {3}ms, {4}ms writing, {5}",
385 reqnum,
386 method,
387 url,
388 tickdiff,
389 tickdata,
390 queryString != null
391 ? (queryString.Length > MaxRequestDiagLength) ? queryString.Remove(MaxRequestDiagLength) : queryString
392 : "");
359 } 393 }
360 394
361 m_log.WarnFormat("[WEB UTIL]: <{0}> form request failed: {1}",reqnum,errorMessage); 395 m_log.WarnFormat("[SERVICE FORM]: <{0}> form request to {1} failed: {2}", reqnum, url, errorMessage);
396
362 return ErrorResponseMap(errorMessage); 397 return ErrorResponseMap(errorMessage);
363 } 398 }
364 399
@@ -638,8 +673,6 @@ namespace OpenSim.Framework
638 673
639 return new string[0]; 674 return new string[0];
640 } 675 }
641
642
643 } 676 }
644 677
645 public static class AsynchronousRestObjectRequester 678 public static class AsynchronousRestObjectRequester
@@ -662,6 +695,12 @@ namespace OpenSim.Framework
662 public static void MakeRequest<TRequest, TResponse>(string verb, 695 public static void MakeRequest<TRequest, TResponse>(string verb,
663 string requestUrl, TRequest obj, Action<TResponse> action) 696 string requestUrl, TRequest obj, Action<TResponse> action)
664 { 697 {
698 int reqnum = WebUtil.RequestNumber++;
699 // m_log.DebugFormat("[WEB UTIL]: <{0}> start osd request for {1}, method {2}",reqnum,url,method);
700
701 int tickstart = Util.EnvironmentTickCount();
702 int tickdata = 0;
703
665 // m_log.DebugFormat("[ASYNC REQUEST]: Starting {0} {1}", verb, requestUrl); 704 // m_log.DebugFormat("[ASYNC REQUEST]: Starting {0} {1}", verb, requestUrl);
666 705
667 Type type = typeof(TRequest); 706 Type type = typeof(TRequest);
@@ -672,12 +711,13 @@ namespace OpenSim.Framework
672 XmlSerializer deserializer = new XmlSerializer(typeof(TResponse)); 711 XmlSerializer deserializer = new XmlSerializer(typeof(TResponse));
673 712
674 request.Method = verb; 713 request.Method = verb;
714 MemoryStream buffer = null;
675 715
676 if (verb == "POST") 716 if (verb == "POST")
677 { 717 {
678 request.ContentType = "text/xml"; 718 request.ContentType = "text/xml";
679 719
680 MemoryStream buffer = new MemoryStream(); 720 buffer = new MemoryStream();
681 721
682 XmlWriterSettings settings = new XmlWriterSettings(); 722 XmlWriterSettings settings = new XmlWriterSettings();
683 settings.Encoding = Encoding.UTF8; 723 settings.Encoding = Encoding.UTF8;
@@ -699,6 +739,9 @@ namespace OpenSim.Framework
699 requestStream.Write(buffer.ToArray(), 0, length); 739 requestStream.Write(buffer.ToArray(), 0, length);
700 requestStream.Close(); 740 requestStream.Close();
701 741
742 // capture how much time was spent writing
743 tickdata = Util.EnvironmentTickCountSubtract(tickstart);
744
702 request.BeginGetResponse(delegate(IAsyncResult ar) 745 request.BeginGetResponse(delegate(IAsyncResult ar)
703 { 746 {
704 response = request.EndGetResponse(ar); 747 response = request.EndGetResponse(ar);
@@ -724,83 +767,108 @@ namespace OpenSim.Framework
724 767
725 }, null); 768 }, null);
726 }, null); 769 }, null);
727
728
729 return;
730 } 770 }
731 771 else
732 request.BeginGetResponse(delegate(IAsyncResult res2)
733 { 772 {
734 try 773 request.BeginGetResponse(delegate(IAsyncResult res2)
735 { 774 {
736 // If the server returns a 404, this appears to trigger a System.Net.WebException even though that isn't
737 // documented in MSDN
738 response = request.EndGetResponse(res2);
739
740 Stream respStream = null;
741 try 775 try
742 { 776 {
743 respStream = response.GetResponseStream(); 777 // If the server returns a 404, this appears to trigger a System.Net.WebException even though that isn't
744 deserial = (TResponse)deserializer.Deserialize(respStream); 778 // documented in MSDN
745 } 779 response = request.EndGetResponse(res2);
746 catch (System.InvalidOperationException) 780
747 { 781 Stream respStream = null;
748 } 782 try
749 finally 783 {
750 { 784 respStream = response.GetResponseStream();
751 respStream.Close(); 785 deserial = (TResponse)deserializer.Deserialize(respStream);
752 response.Close(); 786 }
787 catch (System.InvalidOperationException)
788 {
789 }
790 finally
791 {
792 respStream.Close();
793 response.Close();
794 }
753 } 795 }
754 } 796 catch (WebException e)
755 catch (WebException e)
756 {
757 if (e.Status == WebExceptionStatus.ProtocolError)
758 { 797 {
759 if (e.Response is HttpWebResponse) 798 if (e.Status == WebExceptionStatus.ProtocolError)
760 { 799 {
761 HttpWebResponse httpResponse = (HttpWebResponse)e.Response; 800 if (e.Response is HttpWebResponse)
762
763 if (httpResponse.StatusCode != HttpStatusCode.NotFound)
764 { 801 {
765 // We don't appear to be handling any other status codes, so log these feailures to that 802 HttpWebResponse httpResponse = (HttpWebResponse)e.Response;
766 // people don't spend unnecessary hours hunting phantom bugs. 803
767 m_log.DebugFormat( 804 if (httpResponse.StatusCode != HttpStatusCode.NotFound)
768 "[ASYNC REQUEST]: Request {0} {1} failed with unexpected status code {2}", 805 {
769 verb, requestUrl, httpResponse.StatusCode); 806 // We don't appear to be handling any other status codes, so log these feailures to that
807 // people don't spend unnecessary hours hunting phantom bugs.
808 m_log.DebugFormat(
809 "[ASYNC REQUEST]: Request {0} {1} failed with unexpected status code {2}",
810 verb, requestUrl, httpResponse.StatusCode);
811 }
770 } 812 }
771 } 813 }
814 else
815 {
816 m_log.ErrorFormat(
817 "[ASYNC REQUEST]: Request {0} {1} failed with status {2} and message {3}",
818 verb, requestUrl, e.Status, e.Message);
819 }
772 } 820 }
773 else 821 catch (Exception e)
774 { 822 {
775 m_log.ErrorFormat("[ASYNC REQUEST]: Request {0} {1} failed with status {2} and message {3}", verb, requestUrl, e.Status, e.Message); 823 m_log.ErrorFormat(
824 "[ASYNC REQUEST]: Request {0} {1} failed with exception {2}{3}",
825 verb, requestUrl, e.Message, e.StackTrace);
776 } 826 }
777 } 827
778 catch (Exception e) 828 // m_log.DebugFormat("[ASYNC REQUEST]: Received {0}", deserial.ToString());
779 {
780 m_log.ErrorFormat("[ASYNC REQUEST]: Request {0} {1} failed with exception {2}", verb, requestUrl, e);
781 }
782 829
783 // m_log.DebugFormat("[ASYNC REQUEST]: Received {0}", deserial.ToString()); 830 try
831 {
832 action(deserial);
833 }
834 catch (Exception e)
835 {
836 m_log.ErrorFormat(
837 "[ASYNC REQUEST]: Request {0} {1} callback failed with exception {2}{3}",
838 verb, requestUrl, e.Message, e.StackTrace);
839 }
840
841 }, null);
842 }
784 843
785 try 844 int tickdiff = Util.EnvironmentTickCountSubtract(tickstart);
786 { 845 if (tickdiff > WebUtil.LongCallTime)
787 action(deserial); 846 {
788 } 847 string originalRequest = null;
789 catch (Exception e) 848
849 if (buffer != null)
790 { 850 {
791 m_log.ErrorFormat( 851 originalRequest = Encoding.UTF8.GetString(buffer.ToArray());
792 "[ASYNC REQUEST]: Request {0} {1} callback failed with exception {2}", verb, requestUrl, e); 852
853 if (originalRequest.Length > WebUtil.MaxRequestDiagLength)
854 originalRequest = originalRequest.Remove(WebUtil.MaxRequestDiagLength);
793 } 855 }
794 856
795 }, null); 857 m_log.InfoFormat(
858 "[ASYNC REQUEST]: Slow request to <{0}> {1} {2} took {3}ms, {4}ms writing, {5}",
859 reqnum,
860 verb,
861 requestUrl,
862 tickdiff,
863 tickdata,
864 originalRequest);
865 }
796 } 866 }
797 } 867 }
798 868
799 public static class SynchronousRestFormsRequester 869 public static class SynchronousRestFormsRequester
800 { 870 {
801 private static readonly ILog m_log = 871 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
802 LogManager.GetLogger(
803 MethodBase.GetCurrentMethod().DeclaringType);
804 872
805 /// <summary> 873 /// <summary>
806 /// Perform a synchronous REST request. 874 /// Perform a synchronous REST request.
@@ -814,6 +882,12 @@ namespace OpenSim.Framework
814 /// the request. You'll want to make sure you deal with this as they're not uncommon</exception> 882 /// the request. You'll want to make sure you deal with this as they're not uncommon</exception>
815 public static string MakeRequest(string verb, string requestUrl, string obj) 883 public static string MakeRequest(string verb, string requestUrl, string obj)
816 { 884 {
885 int reqnum = WebUtil.RequestNumber++;
886 // m_log.DebugFormat("[WEB UTIL]: <{0}> start osd request for {1}, method {2}",reqnum,url,method);
887
888 int tickstart = Util.EnvironmentTickCount();
889 int tickdata = 0;
890
817 WebRequest request = WebRequest.Create(requestUrl); 891 WebRequest request = WebRequest.Create(requestUrl);
818 request.Method = verb; 892 request.Method = verb;
819 string respstring = String.Empty; 893 string respstring = String.Empty;
@@ -842,12 +916,16 @@ namespace OpenSim.Framework
842 } 916 }
843 catch (Exception e) 917 catch (Exception e)
844 { 918 {
845 m_log.DebugFormat("[FORMS]: exception occured on sending request to {0}: " + e.ToString(), requestUrl); 919 m_log.DebugFormat(
920 "[FORMS]: exception occured {0} {1}: {2}{3}", verb, requestUrl, e.Message, e.StackTrace);
846 } 921 }
847 finally 922 finally
848 { 923 {
849 if (requestStream != null) 924 if (requestStream != null)
850 requestStream.Close(); 925 requestStream.Close();
926
927 // capture how much time was spent writing
928 tickdata = Util.EnvironmentTickCountSubtract(tickstart);
851 } 929 }
852 } 930 }
853 931
@@ -868,7 +946,9 @@ namespace OpenSim.Framework
868 } 946 }
869 catch (Exception e) 947 catch (Exception e)
870 { 948 {
871 m_log.DebugFormat("[FORMS]: exception occured on receiving reply " + e.ToString()); 949 m_log.DebugFormat(
950 "[FORMS]: Exception occured on receiving {0} {1}: {2}{3}",
951 verb, requestUrl, e.Message, e.StackTrace);
872 } 952 }
873 finally 953 finally
874 { 954 {
@@ -881,9 +961,21 @@ namespace OpenSim.Framework
881 catch (System.InvalidOperationException) 961 catch (System.InvalidOperationException)
882 { 962 {
883 // This is what happens when there is invalid XML 963 // This is what happens when there is invalid XML
884 m_log.DebugFormat("[FORMS]: InvalidOperationException on receiving request"); 964 m_log.DebugFormat("[FORMS]: InvalidOperationException on receiving {0} {1}", verb, requestUrl);
885 } 965 }
886 } 966 }
967
968 int tickdiff = Util.EnvironmentTickCountSubtract(tickstart);
969 if (tickdiff > WebUtil.LongCallTime)
970 m_log.InfoFormat(
971 "[FORMS]: Slow request to <{0}> {1} {2} took {3}ms, {4}ms writing, {5}",
972 reqnum,
973 verb,
974 requestUrl,
975 tickdiff,
976 tickdata,
977 obj.Length > WebUtil.MaxRequestDiagLength ? obj.Remove(WebUtil.MaxRequestDiagLength) : obj);
978
887 return respstring; 979 return respstring;
888 } 980 }
889 } 981 }
@@ -911,6 +1003,12 @@ namespace OpenSim.Framework
911 1003
912 public static TResponse MakeRequest<TRequest, TResponse>(string verb, string requestUrl, TRequest obj, int pTimeout) 1004 public static TResponse MakeRequest<TRequest, TResponse>(string verb, string requestUrl, TRequest obj, int pTimeout)
913 { 1005 {
1006 int reqnum = WebUtil.RequestNumber++;
1007 // m_log.DebugFormat("[WEB UTIL]: <{0}> start osd request for {1}, method {2}",reqnum,url,method);
1008
1009 int tickstart = Util.EnvironmentTickCount();
1010 int tickdata = 0;
1011
914 Type type = typeof(TRequest); 1012 Type type = typeof(TRequest);
915 TResponse deserial = default(TResponse); 1013 TResponse deserial = default(TResponse);
916 1014
@@ -918,12 +1016,13 @@ namespace OpenSim.Framework
918 request.Method = verb; 1016 request.Method = verb;
919 if (pTimeout != 0) 1017 if (pTimeout != 0)
920 request.Timeout = pTimeout * 1000; 1018 request.Timeout = pTimeout * 1000;
1019 MemoryStream buffer = null;
921 1020
922 if ((verb == "POST") || (verb == "PUT")) 1021 if ((verb == "POST") || (verb == "PUT"))
923 { 1022 {
924 request.ContentType = "text/xml"; 1023 request.ContentType = "text/xml";
925 1024
926 MemoryStream buffer = new MemoryStream(); 1025 buffer = new MemoryStream();
927 1026
928 XmlWriterSettings settings = new XmlWriterSettings(); 1027 XmlWriterSettings settings = new XmlWriterSettings();
929 settings.Encoding = Encoding.UTF8; 1028 settings.Encoding = Encoding.UTF8;
@@ -946,13 +1045,19 @@ namespace OpenSim.Framework
946 } 1045 }
947 catch (Exception e) 1046 catch (Exception e)
948 { 1047 {
949 m_log.DebugFormat("[SynchronousRestObjectRequester]: exception in sending data to {0}: {1}", requestUrl, e); 1048 m_log.DebugFormat(
1049 "[SynchronousRestObjectRequester]: Exception in making request {0} {1}: {2}{3}",
1050 verb, requestUrl, e.Message, e.StackTrace);
1051
950 return deserial; 1052 return deserial;
951 } 1053 }
952 finally 1054 finally
953 { 1055 {
954 if (requestStream != null) 1056 if (requestStream != null)
955 requestStream.Close(); 1057 requestStream.Close();
1058
1059 // capture how much time was spent writing
1060 tickdata = Util.EnvironmentTickCountSubtract(tickstart);
956 } 1061 }
957 } 1062 }
958 1063
@@ -968,7 +1073,11 @@ namespace OpenSim.Framework
968 respStream.Close(); 1073 respStream.Close();
969 } 1074 }
970 else 1075 else
971 m_log.DebugFormat("[SynchronousRestObjectRequester]: Oops! no content found in response stream from {0} {1}", requestUrl, verb); 1076 {
1077 m_log.DebugFormat(
1078 "[SynchronousRestObjectRequester]: Oops! no content found in response stream from {0} {1}",
1079 verb, requestUrl);
1080 }
972 } 1081 }
973 } 1082 }
974 catch (WebException e) 1083 catch (WebException e)
@@ -979,17 +1088,44 @@ namespace OpenSim.Framework
979 return deserial; 1088 return deserial;
980 else 1089 else
981 m_log.ErrorFormat( 1090 m_log.ErrorFormat(
982 "[SynchronousRestObjectRequester]: WebException {0} {1} {2} {3}", 1091 "[SynchronousRestObjectRequester]: WebException for {0} {1} {2}: {3} {4}",
983 requestUrl, typeof(TResponse).ToString(), e.Message, e.StackTrace); 1092 verb, requestUrl, typeof(TResponse).ToString(), e.Message, e.StackTrace);
984 } 1093 }
985 catch (System.InvalidOperationException) 1094 catch (System.InvalidOperationException)
986 { 1095 {
987 // This is what happens when there is invalid XML 1096 // This is what happens when there is invalid XML
988 m_log.DebugFormat("[SynchronousRestObjectRequester]: Invalid XML {0} {1}", requestUrl, typeof(TResponse).ToString()); 1097 m_log.DebugFormat(
1098 "[SynchronousRestObjectRequester]: Invalid XML from {0} {1} {2}",
1099 verb, requestUrl, typeof(TResponse).ToString());
989 } 1100 }
990 catch (Exception e) 1101 catch (Exception e)
991 { 1102 {
992 m_log.DebugFormat("[SynchronousRestObjectRequester]: Exception on response from {0} {1}", requestUrl, e); 1103 m_log.DebugFormat(
1104 "[SynchronousRestObjectRequester]: Exception on response from {0} {1}: {2}{3}",
1105 verb, requestUrl, e.Message, e.StackTrace);
1106 }
1107
1108 int tickdiff = Util.EnvironmentTickCountSubtract(tickstart);
1109 if (tickdiff > WebUtil.LongCallTime)
1110 {
1111 string originalRequest = null;
1112
1113 if (buffer != null)
1114 {
1115 originalRequest = Encoding.UTF8.GetString(buffer.ToArray());
1116
1117 if (originalRequest.Length > WebUtil.MaxRequestDiagLength)
1118 originalRequest = originalRequest.Remove(WebUtil.MaxRequestDiagLength);
1119 }
1120
1121 m_log.InfoFormat(
1122 "[SynchronousRestObjectRequester]: Slow request to <{0}> {1} {2} took {3}ms, {4}ms writing, {5}",
1123 reqnum,
1124 verb,
1125 requestUrl,
1126 tickdiff,
1127 tickdata,
1128 originalRequest);
993 } 1129 }
994 1130
995 return deserial; 1131 return deserial;