diff options
Diffstat (limited to 'OpenSim/Framework')
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 | |||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using System.Linq; | ||
31 | using System.Text; | ||
32 | |||
33 | namespace 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 | |||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using System.Linq; | ||
31 | using System.Text; | ||
32 | |||
33 | namespace 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; | |||
29 | using System.Collections.Generic; | 29 | using System.Collections.Generic; |
30 | using System.IO; | 30 | using System.IO; |
31 | using OpenMetaverse; | 31 | using OpenMetaverse; |
32 | using System.Runtime.Serialization; | ||
32 | 33 | ||
33 | namespace OpenSim.Framework | 34 | namespace 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; | |||
30 | using System.Xml; | 30 | using System.Xml; |
31 | using OpenMetaverse; | 31 | using OpenMetaverse; |
32 | using OpenSim.Framework; | 32 | using OpenSim.Framework; |
33 | using log4net; | ||
34 | using System.Reflection; | ||
33 | 35 | ||
34 | namespace OpenSim.Framework.Serialization.External | 36 | namespace 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 @@ | |||
28 | namespace OpenSim.Framework.Servers.HttpServer | 28 | namespace 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 | ||
28 | using System; | 28 | using System; |
29 | using System.Reflection; | ||
30 | using log4net; | ||
29 | using OpenMetaverse; | 31 | using OpenMetaverse; |
30 | 32 | ||
31 | namespace OpenSim.Framework | 33 | namespace 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; |