aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Framework/Servers
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Framework/Servers')
-rw-r--r--OpenSim/Framework/Servers/BaseOpenSimServer.cs46
-rw-r--r--OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs40
-rw-r--r--OpenSim/Framework/Servers/HttpServer/BaseOutputStreamHandler.cs60
-rw-r--r--OpenSim/Framework/Servers/HttpServer/BaseRequestHandler.cs4
-rw-r--r--OpenSim/Framework/Servers/HttpServer/BaseStreamHandler.cs27
-rw-r--r--OpenSim/Framework/Servers/HttpServer/BinaryStreamHandler.cs2
-rw-r--r--OpenSim/Framework/Servers/HttpServer/Interfaces/IStreamHandler.cs15
-rw-r--r--OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs18
-rw-r--r--OpenSim/Framework/Servers/HttpServer/PollServiceHttpRequest.cs45
-rw-r--r--OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs16
-rw-r--r--OpenSim/Framework/Servers/HttpServer/RestDeserialiseHandler.cs4
-rw-r--r--OpenSim/Framework/Servers/HttpServer/RestSessionService.cs13
-rw-r--r--OpenSim/Framework/Servers/HttpServer/RestStreamHandler.cs2
-rw-r--r--OpenSim/Framework/Servers/HttpServer/WebsocketServerHandler.cs20
-rw-r--r--OpenSim/Framework/Servers/MainServer.cs13
-rw-r--r--OpenSim/Framework/Servers/ServerBase.cs100
16 files changed, 341 insertions, 84 deletions
diff --git a/OpenSim/Framework/Servers/BaseOpenSimServer.cs b/OpenSim/Framework/Servers/BaseOpenSimServer.cs
index 6c04c69..bfd67c7 100644
--- a/OpenSim/Framework/Servers/BaseOpenSimServer.cs
+++ b/OpenSim/Framework/Servers/BaseOpenSimServer.cs
@@ -86,26 +86,23 @@ namespace OpenSim.Framework.Servers
86 /// </summary> 86 /// </summary>
87 protected virtual void StartupSpecific() 87 protected virtual void StartupSpecific()
88 { 88 {
89 if (m_console == null) 89 StatsManager.SimExtraStats = new SimExtraStatsCollector();
90 return;
91
92 RegisterCommonCommands(); 90 RegisterCommonCommands();
93 91 RegisterCommonComponents(Config);
94 m_console.Commands.AddCommand("General", false, "quit", 92 }
95 "quit", 93
96 "Quit the application", HandleQuit); 94 protected override void ShutdownSpecific()
95 {
96 m_log.Info("[SHUTDOWN]: Shutdown processing on main thread complete. Exiting...");
97
98 RemovePIDFile();
97 99
98 m_console.Commands.AddCommand("General", false, "shutdown", 100 base.ShutdownSpecific();
99 "shutdown", 101
100 "Quit the application", HandleQuit); 102 Environment.Exit(0);
101 } 103 }
102 104
103 /// <summary> 105 /// <summary>
104 /// Should be overriden and referenced by descendents if they need to perform extra shutdown processing
105 /// </summary>
106 public virtual void ShutdownSpecific() {}
107
108 /// <summary>
109 /// Provides a list of help topics that are available. Overriding classes should append their topics to the 106 /// Provides a list of help topics that are available. Overriding classes should append their topics to the
110 /// information returned when the base method is called. 107 /// information returned when the base method is called.
111 /// </summary> 108 /// </summary>
@@ -153,25 +150,8 @@ namespace OpenSim.Framework.Servers
153 timeTaken.Minutes, timeTaken.Seconds); 150 timeTaken.Minutes, timeTaken.Seconds);
154 } 151 }
155 152
156 /// <summary> 153 public string osSecret
157 /// Should be overriden and referenced by descendents if they need to perform extra shutdown processing
158 /// </summary>
159 public virtual void Shutdown()
160 { 154 {
161 ShutdownSpecific();
162
163 m_log.Info("[SHUTDOWN]: Shutdown processing on main thread complete. Exiting...");
164 RemovePIDFile();
165
166 Environment.Exit(0);
167 }
168
169 private void HandleQuit(string module, string[] args)
170 {
171 Shutdown();
172 }
173
174 public string osSecret {
175 // Secret uuid for the simulator 155 // Secret uuid for the simulator
176 get { return m_osSecret; } 156 get { return m_osSecret; }
177 } 157 }
diff --git a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
index 97035e3..f4b4156 100644
--- a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
+++ b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
@@ -54,7 +54,6 @@ namespace OpenSim.Framework.Servers.HttpServer
54 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 54 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
55 private HttpServerLogWriter httpserverlog = new HttpServerLogWriter(); 55 private HttpServerLogWriter httpserverlog = new HttpServerLogWriter();
56 56
57
58 /// <summary> 57 /// <summary>
59 /// This is a pending websocket request before it got an sucessful upgrade response. 58 /// This is a pending websocket request before it got an sucessful upgrade response.
60 /// The consumer must call handler.HandshakeAndUpgrade() to signal to the handler to 59 /// The consumer must call handler.HandshakeAndUpgrade() to signal to the handler to
@@ -81,6 +80,11 @@ namespace OpenSim.Framework.Servers.HttpServer
81 /// </remarks> 80 /// </remarks>
82 public int RequestNumber { get; private set; } 81 public int RequestNumber { get; private set; }
83 82
83 /// <summary>
84 /// Statistic for holding number of requests processed.
85 /// </summary>
86 private Stat m_requestsProcessedStat;
87
84 private volatile int NotSocketErrors = 0; 88 private volatile int NotSocketErrors = 0;
85 public volatile bool HTTPDRunning = false; 89 public volatile bool HTTPDRunning = false;
86 90
@@ -383,6 +387,8 @@ namespace OpenSim.Framework.Servers.HttpServer
383 387
384 if (TryGetPollServiceHTTPHandler(request.UriPath.ToString(), out psEvArgs)) 388 if (TryGetPollServiceHTTPHandler(request.UriPath.ToString(), out psEvArgs))
385 { 389 {
390 psEvArgs.RequestsReceived++;
391
386 PollServiceHttpRequest psreq = new PollServiceHttpRequest(psEvArgs, context, request); 392 PollServiceHttpRequest psreq = new PollServiceHttpRequest(psEvArgs, context, request);
387 393
388 if (psEvArgs.Request != null) 394 if (psEvArgs.Request != null)
@@ -437,9 +443,8 @@ namespace OpenSim.Framework.Servers.HttpServer
437 } 443 }
438 } 444 }
439 445
440 public void OnHandleRequestIOThread(IHttpClientContext context, IHttpRequest request) 446 private void OnHandleRequestIOThread(IHttpClientContext context, IHttpRequest request)
441 { 447 {
442
443 OSHttpRequest req = new OSHttpRequest(context, request); 448 OSHttpRequest req = new OSHttpRequest(context, request);
444 WebSocketRequestDelegate dWebSocketRequestDelegate = null; 449 WebSocketRequestDelegate dWebSocketRequestDelegate = null;
445 lock (m_WebSocketHandlers) 450 lock (m_WebSocketHandlers)
@@ -454,9 +459,8 @@ namespace OpenSim.Framework.Servers.HttpServer
454 } 459 }
455 460
456 OSHttpResponse resp = new OSHttpResponse(new HttpResponse(context, request),context); 461 OSHttpResponse resp = new OSHttpResponse(new HttpResponse(context, request),context);
457 462 resp.ReuseContext = true;
458 HandleRequest(req, resp); 463 HandleRequest(req, resp);
459
460 464
461 // !!!HACK ALERT!!! 465 // !!!HACK ALERT!!!
462 // There seems to be a bug in the underlying http code that makes subsequent requests 466 // There seems to be a bug in the underlying http code that makes subsequent requests
@@ -687,7 +691,7 @@ namespace OpenSim.Framework.Servers.HttpServer
687 691
688 if (buffer != null) 692 if (buffer != null)
689 { 693 {
690 if (!response.SendChunked) 694 if (!response.SendChunked && response.ContentLength64 <= 0)
691 response.ContentLength64 = buffer.LongLength; 695 response.ContentLength64 = buffer.LongLength;
692 696
693 response.OutputStream.Write(buffer, 0, buffer.Length); 697 response.OutputStream.Write(buffer, 0, buffer.Length);
@@ -1850,8 +1854,8 @@ namespace OpenSim.Framework.Servers.HttpServer
1850 m_httpListener2.Start(64); 1854 m_httpListener2.Start(64);
1851 1855
1852 // Long Poll Service Manager with 3 worker threads a 25 second timeout for no events 1856 // Long Poll Service Manager with 3 worker threads a 25 second timeout for no events
1853// m_PollServiceManager = new PollServiceRequestManager(this, 3, 25000);
1854 m_PollServiceManager = new PollServiceRequestManager(this, 4, 25000); 1857 m_PollServiceManager = new PollServiceRequestManager(this, 4, 25000);
1858 m_PollServiceManager.Start();
1855 HTTPDRunning = true; 1859 HTTPDRunning = true;
1856 1860
1857 //HttpListenerContext context; 1861 //HttpListenerContext context;
@@ -1870,6 +1874,21 @@ namespace OpenSim.Framework.Servers.HttpServer
1870 // useful without inbound HTTP. 1874 // useful without inbound HTTP.
1871 throw e; 1875 throw e;
1872 } 1876 }
1877
1878 m_requestsProcessedStat
1879 = new Stat(
1880 "HTTPRequestsServed",
1881 "Number of inbound HTTP requests processed",
1882 "",
1883 "requests",
1884 "httpserver",
1885 Port.ToString(),
1886 StatType.Pull,
1887 MeasuresOfInterest.AverageChangeOverTime,
1888 stat => stat.Value = RequestNumber,
1889 StatVerbosity.Debug);
1890
1891 StatsManager.RegisterStat(m_requestsProcessedStat);
1873 } 1892 }
1874 1893
1875 public void httpServerDisconnectMonitor(IHttpClientContext source, SocketError err) 1894 public void httpServerDisconnectMonitor(IHttpClientContext source, SocketError err)
@@ -1902,9 +1921,12 @@ namespace OpenSim.Framework.Servers.HttpServer
1902 public void Stop() 1921 public void Stop()
1903 { 1922 {
1904 HTTPDRunning = false; 1923 HTTPDRunning = false;
1924
1925 StatsManager.DeregisterStat(m_requestsProcessedStat);
1926
1905 try 1927 try
1906 { 1928 {
1907// m_PollServiceManager.Stop(); 1929 m_PollServiceManager.Stop();
1908 1930
1909 m_httpListener2.ExceptionThrown -= httpServerException; 1931 m_httpListener2.ExceptionThrown -= httpServerException;
1910 //m_httpListener2.DisconnectHandler = null; 1932 //m_httpListener2.DisconnectHandler = null;
diff --git a/OpenSim/Framework/Servers/HttpServer/BaseOutputStreamHandler.cs b/OpenSim/Framework/Servers/HttpServer/BaseOutputStreamHandler.cs
new file mode 100644
index 0000000..72b3065
--- /dev/null
+++ b/OpenSim/Framework/Servers/HttpServer/BaseOutputStreamHandler.cs
@@ -0,0 +1,60 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System.IO;
29
30namespace OpenSim.Framework.Servers.HttpServer
31{
32 /// <summary>
33 /// Base handler for writing to an output stream
34 /// </summary>
35 /// <remarks>
36 /// Inheriting classes should override ProcessRequest() rather than Handle()
37 /// </remarks>
38 public abstract class BaseOutputStreamHandler : BaseRequestHandler, IRequestHandler
39 {
40 protected BaseOutputStreamHandler(string httpMethod, string path) : this(httpMethod, path, null, null) {}
41
42 protected BaseOutputStreamHandler(string httpMethod, string path, string name, string description)
43 : base(httpMethod, path, name, description) {}
44
45 public virtual void Handle(
46 string path, Stream request, Stream response, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
47 {
48 RequestsReceived++;
49
50 ProcessRequest(path, request, response, httpRequest, httpResponse);
51
52 RequestsHandled++;
53 }
54
55 protected virtual void ProcessRequest(
56 string path, Stream request, Stream response, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
57 {
58 }
59 }
60} \ No newline at end of file
diff --git a/OpenSim/Framework/Servers/HttpServer/BaseRequestHandler.cs b/OpenSim/Framework/Servers/HttpServer/BaseRequestHandler.cs
index ae7aaf2..bbac699 100644
--- a/OpenSim/Framework/Servers/HttpServer/BaseRequestHandler.cs
+++ b/OpenSim/Framework/Servers/HttpServer/BaseRequestHandler.cs
@@ -31,6 +31,10 @@ namespace OpenSim.Framework.Servers.HttpServer
31{ 31{
32 public abstract class BaseRequestHandler 32 public abstract class BaseRequestHandler
33 { 33 {
34 public int RequestsReceived { get; protected set; }
35
36 public int RequestsHandled { get; protected set; }
37
34 public virtual string ContentType 38 public virtual string ContentType
35 { 39 {
36 get { return "application/xml"; } 40 get { return "application/xml"; }
diff --git a/OpenSim/Framework/Servers/HttpServer/BaseStreamHandler.cs b/OpenSim/Framework/Servers/HttpServer/BaseStreamHandler.cs
index 6342983..252cc2a 100644
--- a/OpenSim/Framework/Servers/HttpServer/BaseStreamHandler.cs
+++ b/OpenSim/Framework/Servers/HttpServer/BaseStreamHandler.cs
@@ -29,14 +29,35 @@ using System.IO;
29 29
30namespace OpenSim.Framework.Servers.HttpServer 30namespace OpenSim.Framework.Servers.HttpServer
31{ 31{
32 /// <summary>
33 /// Base streamed request handler.
34 /// </summary>
35 /// <remarks>
36 /// Inheriting classes should override ProcessRequest() rather than Handle()
37 /// </remarks>
32 public abstract class BaseStreamHandler : BaseRequestHandler, IStreamedRequestHandler 38 public abstract class BaseStreamHandler : BaseRequestHandler, IStreamedRequestHandler
33 { 39 {
34 public abstract byte[] Handle(string path, Stream request,
35 IOSHttpRequest httpRequest, IOSHttpResponse httpResponse);
36
37 protected BaseStreamHandler(string httpMethod, string path) : this(httpMethod, path, null, null) {} 40 protected BaseStreamHandler(string httpMethod, string path) : this(httpMethod, path, null, null) {}
38 41
39 protected BaseStreamHandler(string httpMethod, string path, string name, string description) 42 protected BaseStreamHandler(string httpMethod, string path, string name, string description)
40 : base(httpMethod, path, name, description) {} 43 : base(httpMethod, path, name, description) {}
44
45 public virtual byte[] Handle(
46 string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
47 {
48 RequestsReceived++;
49
50 byte[] result = ProcessRequest(path, request, httpRequest, httpResponse);
51
52 RequestsHandled++;
53
54 return result;
55 }
56
57 protected virtual byte[] ProcessRequest(
58 string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
59 {
60 return null;
61 }
41 } 62 }
42} \ No newline at end of file 63} \ No newline at end of file
diff --git a/OpenSim/Framework/Servers/HttpServer/BinaryStreamHandler.cs b/OpenSim/Framework/Servers/HttpServer/BinaryStreamHandler.cs
index b94bfb4..1b03f54 100644
--- a/OpenSim/Framework/Servers/HttpServer/BinaryStreamHandler.cs
+++ b/OpenSim/Framework/Servers/HttpServer/BinaryStreamHandler.cs
@@ -45,7 +45,7 @@ namespace OpenSim.Framework.Servers.HttpServer
45 m_method = binaryMethod; 45 m_method = binaryMethod;
46 } 46 }
47 47
48 public override byte[] Handle(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) 48 protected override byte[] ProcessRequest(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
49 { 49 {
50 byte[] data = ReadFully(request); 50 byte[] data = ReadFully(request);
51 string param = GetParam(path); 51 string param = GetParam(path);
diff --git a/OpenSim/Framework/Servers/HttpServer/Interfaces/IStreamHandler.cs b/OpenSim/Framework/Servers/HttpServer/Interfaces/IStreamHandler.cs
index cb5cce5..b8541cb 100644
--- a/OpenSim/Framework/Servers/HttpServer/Interfaces/IStreamHandler.cs
+++ b/OpenSim/Framework/Servers/HttpServer/Interfaces/IStreamHandler.cs
@@ -32,7 +32,6 @@ namespace OpenSim.Framework.Servers.HttpServer
32{ 32{
33 public interface IRequestHandler 33 public interface IRequestHandler
34 { 34 {
35
36 /// <summary> 35 /// <summary>
37 /// Name for this handler. 36 /// Name for this handler.
38 /// </summary> 37 /// </summary>
@@ -59,6 +58,19 @@ namespace OpenSim.Framework.Servers.HttpServer
59 58
60 // Return path 59 // Return path
61 string Path { get; } 60 string Path { get; }
61
62 /// <summary>
63 /// Number of requests received by this handler
64 /// </summary>
65 int RequestsReceived { get; }
66
67 /// <summary>
68 /// Number of requests handled.
69 /// </summary>
70 /// <remarks>
71 /// Should be equal to RequestsReceived unless requested are being handled slowly or there is deadlock.
72 /// </remarks>
73 int RequestsHandled { get; }
62 } 74 }
63 75
64 public interface IStreamedRequestHandler : IRequestHandler 76 public interface IStreamedRequestHandler : IRequestHandler
@@ -69,7 +81,6 @@ namespace OpenSim.Framework.Servers.HttpServer
69 81
70 public interface IStreamHandler : IRequestHandler 82 public interface IStreamHandler : IRequestHandler
71 { 83 {
72 // Handle request stream, return byte array
73 void Handle(string path, Stream request, Stream response, IOSHttpRequest httpReqbuest, IOSHttpResponse httpResponse); 84 void Handle(string path, Stream request, Stream response, IOSHttpRequest httpReqbuest, IOSHttpResponse httpResponse);
74 } 85 }
75 86
diff --git a/OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs b/OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs
index c19ac32..3fd3bf7 100644
--- a/OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs
+++ b/OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs
@@ -50,25 +50,39 @@ namespace OpenSim.Framework.Servers.HttpServer
50 50
51 public enum EventType : int 51 public enum EventType : int
52 { 52 {
53 Normal = 0, 53 LongPoll = 0,
54 LslHttp = 1, 54 LslHttp = 1,
55 Inventory = 2, 55 Inventory = 2,
56 Texture = 3, 56 Texture = 3,
57 Mesh = 4 57 Mesh = 4
58 } 58 }
59 59
60 public string Url { get; set; }
61
62 /// <summary>
63 /// Number of requests received for this poll service.
64 /// </summary>
65 public int RequestsReceived { get; set; }
66
67 /// <summary>
68 /// Number of requests handled by this poll service.
69 /// </summary>
70 public int RequestsHandled { get; set; }
71
60 public PollServiceEventArgs( 72 public PollServiceEventArgs(
61 RequestMethod pRequest, 73 RequestMethod pRequest,
74 string pUrl,
62 HasEventsMethod pHasEvents, GetEventsMethod pGetEvents, NoEventsMethod pNoEvents, 75 HasEventsMethod pHasEvents, GetEventsMethod pGetEvents, NoEventsMethod pNoEvents,
63 UUID pId, int pTimeOutms) 76 UUID pId, int pTimeOutms)
64 { 77 {
65 Request = pRequest; 78 Request = pRequest;
79 Url = pUrl;
66 HasEvents = pHasEvents; 80 HasEvents = pHasEvents;
67 GetEvents = pGetEvents; 81 GetEvents = pGetEvents;
68 NoEvents = pNoEvents; 82 NoEvents = pNoEvents;
69 Id = pId; 83 Id = pId;
70 TimeOutms = pTimeOutms; 84 TimeOutms = pTimeOutms;
71 Type = EventType.Normal; 85 Type = EventType.LongPoll;
72 } 86 }
73 } 87 }
74} 88}
diff --git a/OpenSim/Framework/Servers/HttpServer/PollServiceHttpRequest.cs b/OpenSim/Framework/Servers/HttpServer/PollServiceHttpRequest.cs
index 723530a..6aa9479 100644
--- a/OpenSim/Framework/Servers/HttpServer/PollServiceHttpRequest.cs
+++ b/OpenSim/Framework/Servers/HttpServer/PollServiceHttpRequest.cs
@@ -26,13 +26,19 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Collections;
30using System.Reflection;
31using System.Text;
29using HttpServer; 32using HttpServer;
33using log4net;
30using OpenMetaverse; 34using OpenMetaverse;
31 35
32namespace OpenSim.Framework.Servers.HttpServer 36namespace OpenSim.Framework.Servers.HttpServer
33{ 37{
34 public class PollServiceHttpRequest 38 public class PollServiceHttpRequest
35 { 39 {
40 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
41
36 public readonly PollServiceEventArgs PollServiceArgs; 42 public readonly PollServiceEventArgs PollServiceArgs;
37 public readonly IHttpClientContext HttpContext; 43 public readonly IHttpClientContext HttpContext;
38 public readonly IHttpRequest Request; 44 public readonly IHttpRequest Request;
@@ -48,5 +54,44 @@ namespace OpenSim.Framework.Servers.HttpServer
48 RequestTime = System.Environment.TickCount; 54 RequestTime = System.Environment.TickCount;
49 RequestID = UUID.Random(); 55 RequestID = UUID.Random();
50 } 56 }
57
58 internal void DoHTTPGruntWork(BaseHttpServer server, Hashtable responsedata)
59 {
60 OSHttpResponse response
61 = new OSHttpResponse(new HttpResponse(HttpContext, Request), HttpContext);
62
63 byte[] buffer = server.DoHTTPGruntWork(responsedata, response);
64
65 response.SendChunked = false;
66 response.ContentLength64 = buffer.Length;
67 response.ContentEncoding = Encoding.UTF8;
68
69 try
70 {
71 response.OutputStream.Write(buffer, 0, buffer.Length);
72 }
73 catch (Exception ex)
74 {
75 m_log.Warn(string.Format("[POLL SERVICE WORKER THREAD]: Error ", ex));
76 }
77 finally
78 {
79 //response.OutputStream.Close();
80 try
81 {
82 response.OutputStream.Flush();
83 response.Send();
84
85 //if (!response.KeepAlive && response.ReuseContext)
86 // response.FreeContext();
87 }
88 catch (Exception e)
89 {
90 m_log.Warn(String.Format("[POLL SERVICE WORKER THREAD]: Error ", e));
91 }
92
93 PollServiceArgs.RequestsHandled++;
94 }
95 }
51 } 96 }
52} \ No newline at end of file 97} \ No newline at end of file
diff --git a/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs b/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs
index 5406f00..44f7045 100644
--- a/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs
+++ b/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs
@@ -64,14 +64,17 @@ namespace OpenSim.Framework.Servers.HttpServer
64 m_server = pSrv; 64 m_server = pSrv;
65 m_WorkerThreadCount = pWorkerThreadCount; 65 m_WorkerThreadCount = pWorkerThreadCount;
66 m_workerThreads = new Thread[m_WorkerThreadCount]; 66 m_workerThreads = new Thread[m_WorkerThreadCount];
67 }
67 68
69 public void Start()
70 {
68 //startup worker threads 71 //startup worker threads
69 for (uint i = 0; i < m_WorkerThreadCount; i++) 72 for (uint i = 0; i < m_WorkerThreadCount; i++)
70 { 73 {
71 m_workerThreads[i] 74 m_workerThreads[i]
72 = Watchdog.StartThread( 75 = Watchdog.StartThread(
73 PoolWorkerJob, 76 PoolWorkerJob,
74 String.Format("PollServiceWorkerThread{0}", i), 77 string.Format("PollServiceWorkerThread{0}:{1}", i, m_server.Port),
75 ThreadPriority.Normal, 78 ThreadPriority.Normal,
76 false, 79 false,
77 false, 80 false,
@@ -81,7 +84,7 @@ namespace OpenSim.Framework.Servers.HttpServer
81 84
82 m_retrysThread = Watchdog.StartThread( 85 m_retrysThread = Watchdog.StartThread(
83 this.CheckRetries, 86 this.CheckRetries,
84 "PollServiceWatcherThread", 87 string.Format("PollServiceWatcherThread:{0}", m_server.Port),
85 ThreadPriority.Normal, 88 ThreadPriority.Normal,
86 false, 89 false,
87 true, 90 true,
@@ -89,7 +92,6 @@ namespace OpenSim.Framework.Servers.HttpServer
89 1000 * 60 * 10); 92 1000 * 60 * 10);
90 } 93 }
91 94
92
93 private void ReQueueEvent(PollServiceHttpRequest req) 95 private void ReQueueEvent(PollServiceHttpRequest req)
94 { 96 {
95 if (m_running) 97 if (m_running)
@@ -103,7 +105,7 @@ namespace OpenSim.Framework.Servers.HttpServer
103 { 105 {
104 if (m_running) 106 if (m_running)
105 { 107 {
106 if (req.PollServiceArgs.Type != PollServiceEventArgs.EventType.Normal) 108 if (req.PollServiceArgs.Type != PollServiceEventArgs.EventType.LongPoll)
107 { 109 {
108 m_requests.Enqueue(req); 110 m_requests.Enqueue(req);
109 } 111 }
@@ -140,13 +142,13 @@ namespace OpenSim.Framework.Servers.HttpServer
140 } 142 }
141 } 143 }
142 144
143 ~PollServiceRequestManager() 145 public void Stop()
144 { 146 {
145 m_running = false; 147 m_running = false;
146 Thread.Sleep(1000); // let the world move 148 Thread.Sleep(1000); // let the world move
147 149
148 foreach (Thread t in m_workerThreads) 150 foreach (Thread t in m_workerThreads)
149 Watchdog.AbortThread(t.ManagedThreadId); 151 Watchdog.AbortThread(t.ManagedThreadId);
150 152
151 try 153 try
152 { 154 {
@@ -205,7 +207,7 @@ namespace OpenSim.Framework.Servers.HttpServer
205 if (responsedata == null) 207 if (responsedata == null)
206 continue; 208 continue;
207 209
208 if (req.PollServiceArgs.Type == PollServiceEventArgs.EventType.Normal) // This is the event queue 210 if (req.PollServiceArgs.Type == PollServiceEventArgs.EventType.LongPoll) // This is the event queue
209 { 211 {
210 try 212 try
211 { 213 {
diff --git a/OpenSim/Framework/Servers/HttpServer/RestDeserialiseHandler.cs b/OpenSim/Framework/Servers/HttpServer/RestDeserialiseHandler.cs
index 07082a8..bd55657 100644
--- a/OpenSim/Framework/Servers/HttpServer/RestDeserialiseHandler.cs
+++ b/OpenSim/Framework/Servers/HttpServer/RestDeserialiseHandler.cs
@@ -33,7 +33,7 @@ namespace OpenSim.Framework.Servers.HttpServer
33{ 33{
34 public delegate TResponse RestDeserialiseMethod<TRequest, TResponse>(TRequest request); 34 public delegate TResponse RestDeserialiseMethod<TRequest, TResponse>(TRequest request);
35 35
36 public class RestDeserialiseHandler<TRequest, TResponse> : BaseRequestHandler, IStreamHandler 36 public class RestDeserialiseHandler<TRequest, TResponse> : BaseOutputStreamHandler, IStreamHandler
37 where TRequest : new() 37 where TRequest : new()
38 { 38 {
39 private RestDeserialiseMethod<TRequest, TResponse> m_method; 39 private RestDeserialiseMethod<TRequest, TResponse> m_method;
@@ -48,7 +48,7 @@ namespace OpenSim.Framework.Servers.HttpServer
48 m_method = method; 48 m_method = method;
49 } 49 }
50 50
51 public void Handle(string path, Stream request, Stream responseStream, 51 protected override void ProcessRequest(string path, Stream request, Stream responseStream,
52 IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) 52 IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
53 { 53 {
54 TRequest deserial; 54 TRequest deserial;
diff --git a/OpenSim/Framework/Servers/HttpServer/RestSessionService.cs b/OpenSim/Framework/Servers/HttpServer/RestSessionService.cs
index edcd134..83c9848 100644
--- a/OpenSim/Framework/Servers/HttpServer/RestSessionService.cs
+++ b/OpenSim/Framework/Servers/HttpServer/RestSessionService.cs
@@ -183,7 +183,7 @@ namespace OpenSim.Framework.Servers.HttpServer
183 183
184 public delegate bool CheckIdentityMethod(string sid, string aid); 184 public delegate bool CheckIdentityMethod(string sid, string aid);
185 185
186 public class RestDeserialiseSecureHandler<TRequest, TResponse> : BaseRequestHandler, IStreamHandler 186 public class RestDeserialiseSecureHandler<TRequest, TResponse> : BaseOutputStreamHandler, IStreamHandler
187 where TRequest : new() 187 where TRequest : new()
188 { 188 {
189 private static readonly ILog m_log 189 private static readonly ILog m_log
@@ -201,7 +201,7 @@ namespace OpenSim.Framework.Servers.HttpServer
201 m_method = method; 201 m_method = method;
202 } 202 }
203 203
204 public void Handle(string path, Stream request, Stream responseStream, 204 protected override void ProcessRequest(string path, Stream request, Stream responseStream,
205 IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) 205 IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
206 { 206 {
207 RestSessionObject<TRequest> deserial = default(RestSessionObject<TRequest>); 207 RestSessionObject<TRequest> deserial = default(RestSessionObject<TRequest>);
@@ -237,7 +237,7 @@ namespace OpenSim.Framework.Servers.HttpServer
237 237
238 public delegate bool CheckTrustedSourceMethod(IPEndPoint peer); 238 public delegate bool CheckTrustedSourceMethod(IPEndPoint peer);
239 239
240 public class RestDeserialiseTrustedHandler<TRequest, TResponse> : BaseRequestHandler, IStreamHandler 240 public class RestDeserialiseTrustedHandler<TRequest, TResponse> : BaseOutputStreamHandler, IStreamHandler
241 where TRequest : new() 241 where TRequest : new()
242 { 242 {
243 private static readonly ILog m_log 243 private static readonly ILog m_log
@@ -260,7 +260,7 @@ namespace OpenSim.Framework.Servers.HttpServer
260 m_method = method; 260 m_method = method;
261 } 261 }
262 262
263 public void Handle(string path, Stream request, Stream responseStream, 263 protected override void ProcessRequest(string path, Stream request, Stream responseStream,
264 IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) 264 IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
265 { 265 {
266 TRequest deserial = default(TRequest); 266 TRequest deserial = default(TRequest);
@@ -292,6 +292,5 @@ namespace OpenSim.Framework.Servers.HttpServer
292 serializer.Serialize(xmlWriter, response); 292 serializer.Serialize(xmlWriter, response);
293 } 293 }
294 } 294 }
295 } 295 }
296 296} \ No newline at end of file
297}
diff --git a/OpenSim/Framework/Servers/HttpServer/RestStreamHandler.cs b/OpenSim/Framework/Servers/HttpServer/RestStreamHandler.cs
index 1f17fee..0305dee 100644
--- a/OpenSim/Framework/Servers/HttpServer/RestStreamHandler.cs
+++ b/OpenSim/Framework/Servers/HttpServer/RestStreamHandler.cs
@@ -48,7 +48,7 @@ namespace OpenSim.Framework.Servers.HttpServer
48 m_restMethod = restMethod; 48 m_restMethod = restMethod;
49 } 49 }
50 50
51 public override byte[] Handle(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) 51 protected override byte[] ProcessRequest(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
52 { 52 {
53 Encoding encoding = Encoding.UTF8; 53 Encoding encoding = Encoding.UTF8;
54 StreamReader streamReader = new StreamReader(request, encoding); 54 StreamReader streamReader = new StreamReader(request, encoding);
diff --git a/OpenSim/Framework/Servers/HttpServer/WebsocketServerHandler.cs b/OpenSim/Framework/Servers/HttpServer/WebsocketServerHandler.cs
index ee96b47..de89e2e 100644
--- a/OpenSim/Framework/Servers/HttpServer/WebsocketServerHandler.cs
+++ b/OpenSim/Framework/Servers/HttpServer/WebsocketServerHandler.cs
@@ -75,7 +75,7 @@ namespace OpenSim.Framework.Servers.HttpServer
75 /// <summary> 75 /// <summary>
76 /// This is a regular HTTP Request... This may be removed in the future. 76 /// This is a regular HTTP Request... This may be removed in the future.
77 /// </summary> 77 /// </summary>
78 public event RegularHttpRequestDelegate OnRegularHttpRequest; 78// public event RegularHttpRequestDelegate OnRegularHttpRequest;
79 79
80 /// <summary> 80 /// <summary>
81 /// When the upgrade from a HTTP request to a Websocket is completed, this will be fired 81 /// When the upgrade from a HTTP request to a Websocket is completed, this will be fired
@@ -304,15 +304,14 @@ namespace OpenSim.Framework.Servers.HttpServer
304 if (d != null) 304 if (d != null)
305 d(this, new UpgradeCompletedEventArgs()); 305 d(this, new UpgradeCompletedEventArgs());
306 } 306 }
307 catch (IOException fail) 307 catch (IOException)
308 { 308 {
309 Close(string.Empty); 309 Close(string.Empty);
310 } 310 }
311 catch (ObjectDisposedException fail) 311 catch (ObjectDisposedException)
312 { 312 {
313 Close(string.Empty); 313 Close(string.Empty);
314 } 314 }
315
316 } 315 }
317 316
318 /// <summary> 317 /// <summary>
@@ -414,8 +413,6 @@ namespace OpenSim.Framework.Servers.HttpServer
414 _socketState.Header = pheader; 413 _socketState.Header = pheader;
415 } 414 }
416 415
417
418
419 if (_socketState.FrameComplete) 416 if (_socketState.FrameComplete)
420 { 417 {
421 ProcessFrame(_socketState); 418 ProcessFrame(_socketState);
@@ -424,7 +421,6 @@ namespace OpenSim.Framework.Servers.HttpServer
424 _socketState.ExpectedBytes = 0; 421 _socketState.ExpectedBytes = 0;
425 422
426 } 423 }
427
428 } 424 }
429 } 425 }
430 else 426 else
@@ -457,8 +453,7 @@ namespace OpenSim.Framework.Servers.HttpServer
457 _socketState.ReceivedBytes.Clear(); 453 _socketState.ReceivedBytes.Clear();
458 _socketState.ExpectedBytes = 0; 454 _socketState.ExpectedBytes = 0;
459 // do some processing 455 // do some processing
460 } 456 }
461
462 } 457 }
463 } 458 }
464 if (offset > 0) 459 if (offset > 0)
@@ -477,13 +472,12 @@ namespace OpenSim.Framework.Servers.HttpServer
477 { 472 {
478 // We can't read the stream anymore... 473 // We can't read the stream anymore...
479 } 474 }
480
481 } 475 }
482 catch (IOException fail) 476 catch (IOException)
483 { 477 {
484 Close(string.Empty); 478 Close(string.Empty);
485 } 479 }
486 catch (ObjectDisposedException fail) 480 catch (ObjectDisposedException)
487 { 481 {
488 Close(string.Empty); 482 Close(string.Empty);
489 } 483 }
diff --git a/OpenSim/Framework/Servers/MainServer.cs b/OpenSim/Framework/Servers/MainServer.cs
index cfd34bb..57931d4 100644
--- a/OpenSim/Framework/Servers/MainServer.cs
+++ b/OpenSim/Framework/Servers/MainServer.cs
@@ -121,12 +121,14 @@ namespace OpenSim.Framework.Servers
121 + " level >= 2 then long warnings are logged when receiving bad input data.\n" 121 + " level >= 2 then long warnings are logged when receiving bad input data.\n"
122 + " level >= 3 then short notices about all incoming non-poll HTTP requests are logged.\n" 122 + " level >= 3 then short notices about all incoming non-poll HTTP requests are logged.\n"
123 + " level >= 4 then the time taken to fulfill the request is logged.\n" 123 + " level >= 4 then the time taken to fulfill the request is logged.\n"
124 + " level >= 5 then a sample from the beginning of the incoming data is logged.\n" 124 + " level >= 5 then a sample from the beginning of the data is logged.\n"
125 + " level >= 6 then the entire incoming data is logged.\n" 125 + " level >= 6 then the entire data is logged.\n"
126 + " no level is specified then the current level is returned.\n\n" 126 + " no level is specified then the current level is returned.\n\n"
127 + "If out or all and\n" 127 + "If out or all and\n"
128 + " level >= 3 then short notices about all outgoing requests going through WebUtil are logged.\n" 128 + " level >= 3 then short notices about all outgoing requests going through WebUtil are logged.\n"
129 + " level >= 4 then the time taken to fulfill the request is logged.\n", 129 + " level >= 4 then the time taken to fulfill the request is logged.\n"
130 + " level >= 5 then a sample from the beginning of the data is logged.\n"
131 + " level >= 6 then the entire data is logged.\n",
130 HandleDebugHttpCommand); 132 HandleDebugHttpCommand);
131 } 133 }
132 134
@@ -283,7 +285,12 @@ namespace OpenSim.Framework.Servers
283 public static bool RemoveHttpServer(uint port) 285 public static bool RemoveHttpServer(uint port)
284 { 286 {
285 lock (m_Servers) 287 lock (m_Servers)
288 {
289 if (instance != null && instance.Port == port)
290 instance = null;
291
286 return m_Servers.Remove(port); 292 return m_Servers.Remove(port);
293 }
287 } 294 }
288 295
289 /// <summary> 296 /// <summary>
diff --git a/OpenSim/Framework/Servers/ServerBase.cs b/OpenSim/Framework/Servers/ServerBase.cs
index 1ff8aca..eb8c9f8 100644
--- a/OpenSim/Framework/Servers/ServerBase.cs
+++ b/OpenSim/Framework/Servers/ServerBase.cs
@@ -62,6 +62,8 @@ namespace OpenSim.Framework.Servers
62 62
63 protected string m_pidFile = String.Empty; 63 protected string m_pidFile = String.Empty;
64 64
65 protected ServerStatsCollector m_serverStatsCollector;
66
65 /// <summary> 67 /// <summary>
66 /// Server version information. Usually VersionInfo + information about git commit, operating system, etc. 68 /// Server version information. Usually VersionInfo + information about git commit, operating system, etc.
67 /// </summary> 69 /// </summary>
@@ -76,6 +78,11 @@ namespace OpenSim.Framework.Servers
76 78
77 protected void CreatePIDFile(string path) 79 protected void CreatePIDFile(string path)
78 { 80 {
81 if (File.Exists(path))
82 m_log.ErrorFormat(
83 "[SERVER BASE]: Previous pid file {0} still exists on startup. Possibly previously unclean shutdown.",
84 path);
85
79 try 86 try
80 { 87 {
81 string pidstring = System.Diagnostics.Process.GetCurrentProcess().Id.ToString(); 88 string pidstring = System.Diagnostics.Process.GetCurrentProcess().Id.ToString();
@@ -254,6 +261,25 @@ namespace OpenSim.Framework.Servers
254 "force gc", 261 "force gc",
255 "Manually invoke runtime garbage collection. For debugging purposes", 262 "Manually invoke runtime garbage collection. For debugging purposes",
256 HandleForceGc); 263 HandleForceGc);
264
265 m_console.Commands.AddCommand(
266 "General", false, "quit",
267 "quit",
268 "Quit the application", (mod, args) => Shutdown());
269
270 m_console.Commands.AddCommand(
271 "General", false, "shutdown",
272 "shutdown",
273 "Quit the application", (mod, args) => Shutdown());
274
275 StatsManager.RegisterConsoleCommands(m_console);
276 }
277
278 public void RegisterCommonComponents(IConfigSource configSource)
279 {
280 m_serverStatsCollector = new ServerStatsCollector();
281 m_serverStatsCollector.Initialise(configSource);
282 m_serverStatsCollector.Start();
257 } 283 }
258 284
259 private void HandleForceGc(string module, string[] args) 285 private void HandleForceGc(string module, string[] args)
@@ -641,7 +667,68 @@ namespace OpenSim.Framework.Servers
641 sb.AppendFormat("Total threads active: {0}\n\n", totalThreads); 667 sb.AppendFormat("Total threads active: {0}\n\n", totalThreads);
642 668
643 sb.Append("Main threadpool (excluding script engine pools)\n"); 669 sb.Append("Main threadpool (excluding script engine pools)\n");
644 sb.Append(Util.GetThreadPoolReport()); 670 sb.Append(GetThreadPoolReport());
671
672 return sb.ToString();
673 }
674
675 /// <summary>
676 /// Get a thread pool report.
677 /// </summary>
678 /// <returns></returns>
679 public static string GetThreadPoolReport()
680 {
681 string threadPoolUsed = null;
682 int maxThreads = 0;
683 int minThreads = 0;
684 int allocatedThreads = 0;
685 int inUseThreads = 0;
686 int waitingCallbacks = 0;
687 int completionPortThreads = 0;
688
689 StringBuilder sb = new StringBuilder();
690 if (Util.FireAndForgetMethod == FireAndForgetMethod.SmartThreadPool)
691 {
692 STPInfo stpi = Util.GetSmartThreadPoolInfo();
693
694 // ROBUST currently leaves this the FireAndForgetMethod but never actually initializes the threadpool.
695 if (stpi != null)
696 {
697 threadPoolUsed = "SmartThreadPool";
698 maxThreads = stpi.MaxThreads;
699 minThreads = stpi.MinThreads;
700 inUseThreads = stpi.InUseThreads;
701 allocatedThreads = stpi.ActiveThreads;
702 waitingCallbacks = stpi.WaitingCallbacks;
703 }
704 }
705 else if (
706 Util.FireAndForgetMethod == FireAndForgetMethod.QueueUserWorkItem
707 || Util.FireAndForgetMethod == FireAndForgetMethod.UnsafeQueueUserWorkItem)
708 {
709 threadPoolUsed = "BuiltInThreadPool";
710 ThreadPool.GetMaxThreads(out maxThreads, out completionPortThreads);
711 ThreadPool.GetMinThreads(out minThreads, out completionPortThreads);
712 int availableThreads;
713 ThreadPool.GetAvailableThreads(out availableThreads, out completionPortThreads);
714 inUseThreads = maxThreads - availableThreads;
715 allocatedThreads = -1;
716 waitingCallbacks = -1;
717 }
718
719 if (threadPoolUsed != null)
720 {
721 sb.AppendFormat("Thread pool used : {0}\n", threadPoolUsed);
722 sb.AppendFormat("Max threads : {0}\n", maxThreads);
723 sb.AppendFormat("Min threads : {0}\n", minThreads);
724 sb.AppendFormat("Allocated threads : {0}\n", allocatedThreads < 0 ? "not applicable" : allocatedThreads.ToString());
725 sb.AppendFormat("In use threads : {0}\n", inUseThreads);
726 sb.AppendFormat("Work items waiting : {0}\n", waitingCallbacks < 0 ? "not available" : waitingCallbacks.ToString());
727 }
728 else
729 {
730 sb.AppendFormat("Thread pool not used\n");
731 }
645 732
646 return sb.ToString(); 733 return sb.ToString();
647 } 734 }
@@ -693,5 +780,16 @@ namespace OpenSim.Framework.Servers
693 if (m_console != null) 780 if (m_console != null)
694 m_console.OutputFormat(format, components); 781 m_console.OutputFormat(format, components);
695 } 782 }
783
784 public virtual void Shutdown()
785 {
786 m_serverStatsCollector.Close();
787 ShutdownSpecific();
788 }
789
790 /// <summary>
791 /// Should be overriden and referenced by descendents if they need to perform extra shutdown processing
792 /// </summary>
793 protected virtual void ShutdownSpecific() {}
696 } 794 }
697} 795}