aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Framework/Servers/HttpServer
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Framework/Servers/HttpServer')
-rw-r--r--OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs90
-rw-r--r--OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs19
-rw-r--r--OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs285
-rw-r--r--OpenSim/Framework/Servers/HttpServer/PollServiceWorkerThread.cs16
4 files changed, 377 insertions, 33 deletions
diff --git a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
index 96a030b..74954cc 100644
--- a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
+++ b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
@@ -395,6 +395,7 @@ namespace OpenSim.Framework.Servers.HttpServer
395 StreamReader reader = new StreamReader(requestStream, encoding); 395 StreamReader reader = new StreamReader(requestStream, encoding);
396 396
397 string requestBody = reader.ReadToEnd(); 397 string requestBody = reader.ReadToEnd();
398 reader.Close();
398 399
399 Hashtable keysvals = new Hashtable(); 400 Hashtable keysvals = new Hashtable();
400 Hashtable headervals = new Hashtable(); 401 Hashtable headervals = new Hashtable();
@@ -736,7 +737,7 @@ namespace OpenSim.Framework.Servers.HttpServer
736 // Every month or so this will wrap and give bad numbers, not really a problem 737 // Every month or so this will wrap and give bad numbers, not really a problem
737 // since its just for reporting 738 // since its just for reporting
738 int tickdiff = requestEndTick - requestStartTick; 739 int tickdiff = requestEndTick - requestStartTick;
739 if (tickdiff > 3000 && requestHandler != null && requestHandler.Name != "GetTexture") 740 if (tickdiff > 3000 && (requestHandler == null || requestHandler.Name == null || requestHandler.Name != "GetTexture"))
740 { 741 {
741 m_log.InfoFormat( 742 m_log.InfoFormat(
742 "[BASE HTTP SERVER]: Slow handling of {0} {1} {2} {3} {4} from {5} took {6}ms", 743 "[BASE HTTP SERVER]: Slow handling of {0} {1} {2} {3} {4} from {5} took {6}ms",
@@ -1657,10 +1658,40 @@ namespace OpenSim.Framework.Servers.HttpServer
1657 1658
1658 internal byte[] DoHTTPGruntWork(Hashtable responsedata, OSHttpResponse response) 1659 internal byte[] DoHTTPGruntWork(Hashtable responsedata, OSHttpResponse response)
1659 { 1660 {
1660 //m_log.Info("[BASE HTTP SERVER]: Doing HTTP Grunt work with response"); 1661 int responsecode;
1661 int responsecode = (int)responsedata["int_response_code"]; 1662 string responseString = String.Empty;
1662 string responseString = (string)responsedata["str_response_string"]; 1663 byte[] responseData = null;
1663 string contentType = (string)responsedata["content_type"]; 1664 string contentType;
1665
1666 if (responsedata == null)
1667 {
1668 responsecode = 500;
1669 responseString = "No response could be obtained";
1670 contentType = "text/plain";
1671 responsedata = new Hashtable();
1672 }
1673 else
1674 {
1675 try
1676 {
1677 //m_log.Info("[BASE HTTP SERVER]: Doing HTTP Grunt work with response");
1678 responsecode = (int)responsedata["int_response_code"];
1679 if (responsedata["bin_response_data"] != null)
1680 responseData = (byte[])responsedata["bin_response_data"];
1681 else
1682 responseString = (string)responsedata["str_response_string"];
1683 contentType = (string)responsedata["content_type"];
1684 if (responseString == null)
1685 responseString = String.Empty;
1686 }
1687 catch
1688 {
1689 responsecode = 500;
1690 responseString = "No response could be obtained";
1691 contentType = "text/plain";
1692 responsedata = new Hashtable();
1693 }
1694 }
1664 1695
1665 if (responsedata.ContainsKey("error_status_text")) 1696 if (responsedata.ContainsKey("error_status_text"))
1666 { 1697 {
@@ -1705,25 +1736,40 @@ namespace OpenSim.Framework.Servers.HttpServer
1705 1736
1706 response.AddHeader("Content-Type", contentType); 1737 response.AddHeader("Content-Type", contentType);
1707 1738
1739 if (responsedata.ContainsKey("headers"))
1740 {
1741 Hashtable headerdata = (Hashtable)responsedata["headers"];
1742
1743 foreach (string header in headerdata.Keys)
1744 response.AddHeader(header, (string)headerdata[header]);
1745 }
1746
1708 byte[] buffer; 1747 byte[] buffer;
1709 1748
1710 if (!(contentType.Contains("image") 1749 if (responseData != null)
1711 || contentType.Contains("x-shockwave-flash")
1712 || contentType.Contains("application/x-oar")
1713 || contentType.Contains("application/vnd.ll.mesh")))
1714 { 1750 {
1715 // Text 1751 buffer = responseData;
1716 buffer = Encoding.UTF8.GetBytes(responseString);
1717 } 1752 }
1718 else 1753 else
1719 { 1754 {
1720 // Binary! 1755 if (!(contentType.Contains("image")
1721 buffer = Convert.FromBase64String(responseString); 1756 || contentType.Contains("x-shockwave-flash")
1722 } 1757 || contentType.Contains("application/x-oar")
1758 || contentType.Contains("application/vnd.ll.mesh")))
1759 {
1760 // Text
1761 buffer = Encoding.UTF8.GetBytes(responseString);
1762 }
1763 else
1764 {
1765 // Binary!
1766 buffer = Convert.FromBase64String(responseString);
1767 }
1723 1768
1724 response.SendChunked = false; 1769 response.SendChunked = false;
1725 response.ContentLength64 = buffer.Length; 1770 response.ContentLength64 = buffer.Length;
1726 response.ContentEncoding = Encoding.UTF8; 1771 response.ContentEncoding = Encoding.UTF8;
1772 }
1727 1773
1728 return buffer; 1774 return buffer;
1729 } 1775 }
@@ -1804,8 +1850,8 @@ namespace OpenSim.Framework.Servers.HttpServer
1804 m_httpListener2.Start(64); 1850 m_httpListener2.Start(64);
1805 1851
1806 // Long Poll Service Manager with 3 worker threads a 25 second timeout for no events 1852 // Long Poll Service Manager with 3 worker threads a 25 second timeout for no events
1807 m_PollServiceManager = new PollServiceRequestManager(this, 3, 25000); 1853// m_PollServiceManager = new PollServiceRequestManager(this, 3, 25000);
1808 m_PollServiceManager.Start(); 1854 m_PollServiceManager = new PollServiceRequestManager(this, 4, 25000);
1809 HTTPDRunning = true; 1855 HTTPDRunning = true;
1810 1856
1811 //HttpListenerContext context; 1857 //HttpListenerContext context;
@@ -1839,7 +1885,9 @@ namespace OpenSim.Framework.Servers.HttpServer
1839 1885
1840 public void httpServerException(object source, Exception exception) 1886 public void httpServerException(object source, Exception exception)
1841 { 1887 {
1842 m_log.Error(String.Format("[BASE HTTP SERVER]: {0} had an exception: {1} ", source.ToString(), exception.Message), exception); 1888 if (source.ToString() == "HttpServer.HttpListener" && exception.ToString().StartsWith("Mono.Security.Protocol.Tls.TlsException"))
1889 return;
1890 m_log.ErrorFormat("[BASE HTTP SERVER]: {0} had an exception {1}", source.ToString(), exception.ToString());
1843 /* 1891 /*
1844 if (HTTPDRunning)// && NotSocketErrors > 5) 1892 if (HTTPDRunning)// && NotSocketErrors > 5)
1845 { 1893 {
@@ -1856,7 +1904,7 @@ namespace OpenSim.Framework.Servers.HttpServer
1856 HTTPDRunning = false; 1904 HTTPDRunning = false;
1857 try 1905 try
1858 { 1906 {
1859 m_PollServiceManager.Stop(); 1907// m_PollServiceManager.Stop();
1860 1908
1861 m_httpListener2.ExceptionThrown -= httpServerException; 1909 m_httpListener2.ExceptionThrown -= httpServerException;
1862 //m_httpListener2.DisconnectHandler = null; 1910 //m_httpListener2.DisconnectHandler = null;
diff --git a/OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs b/OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs
index 3089351..c19ac32 100644
--- a/OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs
+++ b/OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs
@@ -34,7 +34,7 @@ namespace OpenSim.Framework.Servers.HttpServer
34 public delegate void RequestMethod(UUID requestID, Hashtable request); 34 public delegate void RequestMethod(UUID requestID, Hashtable request);
35 public delegate bool HasEventsMethod(UUID requestID, UUID pId); 35 public delegate bool HasEventsMethod(UUID requestID, UUID pId);
36 36
37 public delegate Hashtable GetEventsMethod(UUID requestID, UUID pId, string request); 37 public delegate Hashtable GetEventsMethod(UUID requestID, UUID pId);
38 38
39 public delegate Hashtable NoEventsMethod(UUID requestID, UUID pId); 39 public delegate Hashtable NoEventsMethod(UUID requestID, UUID pId);
40 40
@@ -45,17 +45,30 @@ namespace OpenSim.Framework.Servers.HttpServer
45 public NoEventsMethod NoEvents; 45 public NoEventsMethod NoEvents;
46 public RequestMethod Request; 46 public RequestMethod Request;
47 public UUID Id; 47 public UUID Id;
48 public int TimeOutms;
49 public EventType Type;
50
51 public enum EventType : int
52 {
53 Normal = 0,
54 LslHttp = 1,
55 Inventory = 2,
56 Texture = 3,
57 Mesh = 4
58 }
48 59
49 public PollServiceEventArgs( 60 public PollServiceEventArgs(
50 RequestMethod pRequest, 61 RequestMethod pRequest,
51 HasEventsMethod pHasEvents, GetEventsMethod pGetEvents, NoEventsMethod pNoEvents, 62 HasEventsMethod pHasEvents, GetEventsMethod pGetEvents, NoEventsMethod pNoEvents,
52 UUID pId) 63 UUID pId, int pTimeOutms)
53 { 64 {
54 Request = pRequest; 65 Request = pRequest;
55 HasEvents = pHasEvents; 66 HasEvents = pHasEvents;
56 GetEvents = pGetEvents; 67 GetEvents = pGetEvents;
57 NoEvents = pNoEvents; 68 NoEvents = pNoEvents;
58 Id = pId; 69 Id = pId;
70 TimeOutms = pTimeOutms;
71 Type = EventType.Normal;
59 } 72 }
60 } 73 }
61} \ No newline at end of file 74}
diff --git a/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs b/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs
index 3e84c55..07bd48a 100644
--- a/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs
+++ b/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs
@@ -33,15 +33,20 @@ using log4net;
33using HttpServer; 33using HttpServer;
34using OpenSim.Framework; 34using OpenSim.Framework;
35using OpenSim.Framework.Monitoring; 35using OpenSim.Framework.Monitoring;
36using Amib.Threading;
36 37
38
39/*
37namespace OpenSim.Framework.Servers.HttpServer 40namespace OpenSim.Framework.Servers.HttpServer
38{ 41{
42
39 public class PollServiceRequestManager 43 public class PollServiceRequestManager
40 { 44 {
41// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 45// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
42 46
43 private readonly BaseHttpServer m_server; 47 private readonly BaseHttpServer m_server;
44 private static Queue m_requests = Queue.Synchronized(new Queue()); 48 private static Queue m_requests = Queue.Synchronized(new Queue());
49 private static ManualResetEvent m_ev = new ManualResetEvent(false);
45 private uint m_WorkerThreadCount = 0; 50 private uint m_WorkerThreadCount = 0;
46 private Thread[] m_workerThreads; 51 private Thread[] m_workerThreads;
47 private PollServiceWorkerThread[] m_PollServiceWorkerThreads; 52 private PollServiceWorkerThread[] m_PollServiceWorkerThreads;
@@ -74,7 +79,6 @@ namespace OpenSim.Framework.Servers.HttpServer
74 ThreadPriority.Normal, 79 ThreadPriority.Normal,
75 false, 80 false,
76 true, 81 true,
77 null,
78 int.MaxValue); 82 int.MaxValue);
79 } 83 }
80 84
@@ -84,7 +88,6 @@ namespace OpenSim.Framework.Servers.HttpServer
84 ThreadPriority.Normal, 88 ThreadPriority.Normal,
85 false, 89 false,
86 true, 90 true,
87 null,
88 1000 * 60 * 10); 91 1000 * 60 * 10);
89 } 92 }
90 93
@@ -98,15 +101,17 @@ namespace OpenSim.Framework.Servers.HttpServer
98 { 101 {
99 lock (m_requests) 102 lock (m_requests)
100 m_requests.Enqueue(req); 103 m_requests.Enqueue(req);
104 m_ev.Set();
101 } 105 }
102 106
103 public void ThreadStart() 107 public void ThreadStart()
104 { 108 {
105 while (m_running) 109 while (m_running)
106 { 110 {
111 m_ev.WaitOne(1000);
112 m_ev.Reset();
107 Watchdog.UpdateThread(); 113 Watchdog.UpdateThread();
108 ProcessQueuedRequests(); 114 ProcessQueuedRequests();
109 Thread.Sleep(1000);
110 } 115 }
111 } 116 }
112 117
@@ -150,8 +155,9 @@ namespace OpenSim.Framework.Servers.HttpServer
150 foreach (object o in m_requests) 155 foreach (object o in m_requests)
151 { 156 {
152 PollServiceHttpRequest req = (PollServiceHttpRequest) o; 157 PollServiceHttpRequest req = (PollServiceHttpRequest) o;
153 PollServiceWorkerThread.DoHTTPGruntWork( 158 m_server.DoHTTPGruntWork(
154 m_server, req, req.PollServiceArgs.NoEvents(req.RequestID, req.PollServiceArgs.Id)); 159 req.PollServiceArgs.NoEvents(req.RequestID, req.PollServiceArgs.Id),
160 new OSHttpResponse(new HttpResponse(req.HttpContext, req.Request), req.HttpContext));
155 } 161 }
156 162
157 m_requests.Clear(); 163 m_requests.Clear();
@@ -162,4 +168,271 @@ namespace OpenSim.Framework.Servers.HttpServer
162 } 168 }
163 } 169 }
164 } 170 }
165} \ No newline at end of file 171}
172 */
173
174using System.IO;
175using System.Text;
176using System.Collections.Generic;
177
178namespace OpenSim.Framework.Servers.HttpServer
179{
180 public class PollServiceRequestManager
181 {
182 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
183
184 private readonly BaseHttpServer m_server;
185
186 private BlockingQueue<PollServiceHttpRequest> m_requests = new BlockingQueue<PollServiceHttpRequest>();
187 private static Queue<PollServiceHttpRequest> m_slowRequests = new Queue<PollServiceHttpRequest>();
188 private static Queue<PollServiceHttpRequest> m_retryRequests = new Queue<PollServiceHttpRequest>();
189
190 private uint m_WorkerThreadCount = 0;
191 private Thread[] m_workerThreads;
192 private Thread m_retrysThread;
193
194 private bool m_running = true;
195 private int slowCount = 0;
196
197 private SmartThreadPool m_threadPool = new SmartThreadPool(20000, 12, 2);
198
199// private int m_timeout = 1000; // increase timeout 250; now use the event one
200
201 public PollServiceRequestManager(BaseHttpServer pSrv, uint pWorkerThreadCount, int pTimeout)
202 {
203 m_server = pSrv;
204 m_WorkerThreadCount = pWorkerThreadCount;
205 m_workerThreads = new Thread[m_WorkerThreadCount];
206
207 //startup worker threads
208 for (uint i = 0; i < m_WorkerThreadCount; i++)
209 {
210 m_workerThreads[i]
211 = Watchdog.StartThread(
212 PoolWorkerJob,
213 String.Format("PollServiceWorkerThread{0}", i),
214 ThreadPriority.Normal,
215 false,
216 false,
217 null,
218 int.MaxValue);
219 }
220
221 m_retrysThread = Watchdog.StartThread(
222 this.CheckRetries,
223 "PollServiceWatcherThread",
224 ThreadPriority.Normal,
225 false,
226 true,
227 null,
228 1000 * 60 * 10);
229 }
230
231
232 private void ReQueueEvent(PollServiceHttpRequest req)
233 {
234 if (m_running)
235 {
236 lock (m_retryRequests)
237 m_retryRequests.Enqueue(req);
238 }
239 }
240
241 public void Enqueue(PollServiceHttpRequest req)
242 {
243 if (m_running)
244 {
245 if (req.PollServiceArgs.Type != PollServiceEventArgs.EventType.Normal)
246 {
247 m_requests.Enqueue(req);
248 }
249 else
250 {
251 lock (m_slowRequests)
252 m_slowRequests.Enqueue(req);
253 }
254 }
255 }
256
257 private void CheckRetries()
258 {
259 while (m_running)
260 {
261 Thread.Sleep(100); // let the world move .. back to faster rate
262 Watchdog.UpdateThread();
263 lock (m_retryRequests)
264 {
265 while (m_retryRequests.Count > 0 && m_running)
266 m_requests.Enqueue(m_retryRequests.Dequeue());
267 }
268 slowCount++;
269 if (slowCount >= 10)
270 {
271 slowCount = 0;
272
273 lock (m_slowRequests)
274 {
275 while (m_slowRequests.Count > 0 && m_running)
276 m_requests.Enqueue(m_slowRequests.Dequeue());
277 }
278 }
279 }
280 }
281
282 ~PollServiceRequestManager()
283 {
284 m_running = false;
285// m_timeout = -10000; // cause all to expire
286 Thread.Sleep(1000); // let the world move
287
288 foreach (Thread t in m_workerThreads)
289 Watchdog.AbortThread(t.ManagedThreadId);
290
291 try
292 {
293 foreach (PollServiceHttpRequest req in m_retryRequests)
294 {
295 DoHTTPGruntWork(m_server,req,
296 req.PollServiceArgs.NoEvents(req.RequestID, req.PollServiceArgs.Id));
297 }
298 }
299 catch
300 {
301 }
302
303 PollServiceHttpRequest wreq;
304 m_retryRequests.Clear();
305
306 lock (m_slowRequests)
307 {
308 while (m_slowRequests.Count > 0 && m_running)
309 m_requests.Enqueue(m_slowRequests.Dequeue());
310 }
311
312 while (m_requests.Count() > 0)
313 {
314 try
315 {
316 wreq = m_requests.Dequeue(0);
317 DoHTTPGruntWork(m_server,wreq,
318 wreq.PollServiceArgs.NoEvents(wreq.RequestID, wreq.PollServiceArgs.Id));
319 }
320 catch
321 {
322 }
323 }
324
325 m_requests.Clear();
326 }
327
328 // work threads
329
330 private void PoolWorkerJob()
331 {
332 while (m_running)
333 {
334 PollServiceHttpRequest req = m_requests.Dequeue(5000);
335
336 Watchdog.UpdateThread();
337 if (req != null)
338 {
339 try
340 {
341 if (req.PollServiceArgs.HasEvents(req.RequestID, req.PollServiceArgs.Id))
342 {
343 Hashtable responsedata = req.PollServiceArgs.GetEvents(req.RequestID, req.PollServiceArgs.Id);
344
345 if (responsedata == null)
346 continue;
347
348 if (req.PollServiceArgs.Type == PollServiceEventArgs.EventType.Normal)
349 {
350 try
351 {
352 DoHTTPGruntWork(m_server, req, responsedata);
353 }
354 catch (ObjectDisposedException) // Browser aborted before we could read body, server closed the stream
355 {
356 // Ignore it, no need to reply
357 }
358 }
359 else
360 {
361 m_threadPool.QueueWorkItem(x =>
362 {
363 try
364 {
365 DoHTTPGruntWork(m_server, req, responsedata);
366 }
367 catch (ObjectDisposedException) // Browser aborted before we could read body, server closed the stream
368 {
369 // Ignore it, no need to reply
370 }
371
372 return null;
373 }, null);
374 }
375 }
376 else
377 {
378 if ((Environment.TickCount - req.RequestTime) > req.PollServiceArgs.TimeOutms)
379 {
380 DoHTTPGruntWork(m_server, req,
381 req.PollServiceArgs.NoEvents(req.RequestID, req.PollServiceArgs.Id));
382 }
383 else
384 {
385 ReQueueEvent(req);
386 }
387 }
388 }
389 catch (Exception e)
390 {
391 m_log.ErrorFormat("Exception in poll service thread: " + e.ToString());
392 }
393 }
394 }
395 }
396
397 // DoHTTPGruntWork changed, not sending response
398 // do the same work around as core
399
400 internal static void DoHTTPGruntWork(BaseHttpServer server, PollServiceHttpRequest req, Hashtable responsedata)
401 {
402 OSHttpResponse response
403 = new OSHttpResponse(new HttpResponse(req.HttpContext, req.Request), req.HttpContext);
404
405 byte[] buffer = server.DoHTTPGruntWork(responsedata, response);
406
407 response.SendChunked = false;
408 response.ContentLength64 = buffer.Length;
409 response.ContentEncoding = Encoding.UTF8;
410
411 try
412 {
413 response.OutputStream.Write(buffer, 0, buffer.Length);
414 }
415 catch (Exception ex)
416 {
417 m_log.Warn(string.Format("[POLL SERVICE WORKER THREAD]: Error ", ex));
418 }
419 finally
420 {
421 //response.OutputStream.Close();
422 try
423 {
424 response.OutputStream.Flush();
425 response.Send();
426
427 //if (!response.KeepAlive && response.ReuseContext)
428 // response.FreeContext();
429 }
430 catch (Exception e)
431 {
432 m_log.Warn(String.Format("[POLL SERVICE WORKER THREAD]: Error ", e));
433 }
434 }
435 }
436 }
437}
438
diff --git a/OpenSim/Framework/Servers/HttpServer/PollServiceWorkerThread.cs b/OpenSim/Framework/Servers/HttpServer/PollServiceWorkerThread.cs
index 5adbcd1..1c529b6 100644
--- a/OpenSim/Framework/Servers/HttpServer/PollServiceWorkerThread.cs
+++ b/OpenSim/Framework/Servers/HttpServer/PollServiceWorkerThread.cs
@@ -25,6 +25,8 @@
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27 27
28/* Ubit work moved to PollServiceRequestManager
29
28using System; 30using System;
29using System.Collections; 31using System.Collections;
30using System.Collections.Generic; 32using System.Collections.Generic;
@@ -90,8 +92,15 @@ namespace OpenSim.Framework.Servers.HttpServer
90 continue; 92 continue;
91 } 93 }
92 94
93 Hashtable responsedata = req.PollServiceArgs.GetEvents(req.RequestID, req.PollServiceArgs.Id, str.ReadToEnd()); 95 try
94 DoHTTPGruntWork(m_server, req, responsedata); 96 {
97 Hashtable responsedata = req.PollServiceArgs.GetEvents(req.RequestID, req.PollServiceArgs.Id, str.ReadToEnd());
98 DoHTTPGruntWork(m_server, req, responsedata);
99 }
100 catch (ObjectDisposedException) // Browser aborted before we could read body, server closed the stream
101 {
102 // Ignore it, no need to reply
103 }
95 } 104 }
96 else 105 else
97 { 106 {
@@ -162,4 +171,5 @@ namespace OpenSim.Framework.Servers.HttpServer
162 } 171 }
163 } 172 }
164 } 173 }
165} \ No newline at end of file 174}
175*/ \ No newline at end of file