diff options
author | Melanie | 2018-09-12 13:22:17 +0100 |
---|---|---|
committer | Melanie | 2018-09-12 13:22:17 +0100 |
commit | e874e3a2ad47af6a045dbe3f4dd91364cd92750a (patch) | |
tree | a92dc21f85d01e421842cb2fbfa4ecdf3430334a /OpenSim/Framework/Servers | |
parent | Squelch "connection reset by peer" exceptions (diff) | |
parent | oooops (diff) | |
download | opensim-SC-e874e3a2ad47af6a045dbe3f4dd91364cd92750a.zip opensim-SC-e874e3a2ad47af6a045dbe3f4dd91364cd92750a.tar.gz opensim-SC-e874e3a2ad47af6a045dbe3f4dd91364cd92750a.tar.bz2 opensim-SC-e874e3a2ad47af6a045dbe3f4dd91364cd92750a.tar.xz |
Merge branch 'master' of opensimulator.org:/var/git/opensim
Diffstat (limited to 'OpenSim/Framework/Servers')
11 files changed, 449 insertions, 308 deletions
diff --git a/OpenSim/Framework/Servers/BaseOpenSimServer.cs b/OpenSim/Framework/Servers/BaseOpenSimServer.cs index f761813..f832f81 100644 --- a/OpenSim/Framework/Servers/BaseOpenSimServer.cs +++ b/OpenSim/Framework/Servers/BaseOpenSimServer.cs | |||
@@ -33,6 +33,9 @@ using System.Text; | |||
33 | using System.Text.RegularExpressions; | 33 | using System.Text.RegularExpressions; |
34 | using System.Threading; | 34 | using System.Threading; |
35 | using System.Timers; | 35 | using System.Timers; |
36 | using System.Net; | ||
37 | using System.Net.Security; | ||
38 | using System.Security.Cryptography.X509Certificates; | ||
36 | using log4net; | 39 | using log4net; |
37 | using log4net.Appender; | 40 | using log4net.Appender; |
38 | using log4net.Core; | 41 | using log4net.Core; |
@@ -86,6 +89,26 @@ namespace OpenSim.Framework.Servers | |||
86 | m_osSecret = UUID.Random().ToString(); | 89 | m_osSecret = UUID.Random().ToString(); |
87 | } | 90 | } |
88 | 91 | ||
92 | private static bool m_NoVerifyCertChain = false; | ||
93 | private static bool m_NoVerifyCertHostname = false; | ||
94 | |||
95 | public static bool ValidateServerCertificate( | ||
96 | object sender, | ||
97 | X509Certificate certificate, | ||
98 | X509Chain chain, | ||
99 | SslPolicyErrors sslPolicyErrors) | ||
100 | { | ||
101 | if (m_NoVerifyCertChain) | ||
102 | sslPolicyErrors &= ~SslPolicyErrors.RemoteCertificateChainErrors; | ||
103 | |||
104 | if (m_NoVerifyCertHostname) | ||
105 | sslPolicyErrors &= ~SslPolicyErrors.RemoteCertificateNameMismatch; | ||
106 | |||
107 | if (sslPolicyErrors == SslPolicyErrors.None) | ||
108 | return true; | ||
109 | |||
110 | return false; | ||
111 | } | ||
89 | /// <summary> | 112 | /// <summary> |
90 | /// Must be overriden by child classes for their own server specific startup behaviour. | 113 | /// Must be overriden by child classes for their own server specific startup behaviour. |
91 | /// </summary> | 114 | /// </summary> |
@@ -96,6 +119,11 @@ namespace OpenSim.Framework.Servers | |||
96 | RegisterCommonComponents(Config); | 119 | RegisterCommonComponents(Config); |
97 | 120 | ||
98 | IConfig startupConfig = Config.Configs["Startup"]; | 121 | IConfig startupConfig = Config.Configs["Startup"]; |
122 | |||
123 | m_NoVerifyCertChain = startupConfig.GetBoolean("NoVerifyCertChain", m_NoVerifyCertChain); | ||
124 | m_NoVerifyCertHostname = startupConfig.GetBoolean("NoVerifyCertHostname", m_NoVerifyCertHostname); | ||
125 | ServicePointManager.ServerCertificateValidationCallback = ValidateServerCertificate; | ||
126 | |||
99 | int logShowStatsSeconds = startupConfig.GetInt("LogShowStatsSeconds", m_periodDiagnosticTimerMS / 1000); | 127 | int logShowStatsSeconds = startupConfig.GetInt("LogShowStatsSeconds", m_periodDiagnosticTimerMS / 1000); |
100 | m_periodDiagnosticTimerMS = logShowStatsSeconds * 1000; | 128 | m_periodDiagnosticTimerMS = logShowStatsSeconds * 1000; |
101 | m_periodicDiagnosticsTimer.Elapsed += new ElapsedEventHandler(LogDiagnostics); | 129 | m_periodicDiagnosticsTimer.Elapsed += new ElapsedEventHandler(LogDiagnostics); |
@@ -108,13 +136,21 @@ namespace OpenSim.Framework.Servers | |||
108 | 136 | ||
109 | protected override void ShutdownSpecific() | 137 | protected override void ShutdownSpecific() |
110 | { | 138 | { |
111 | m_log.Info("[SHUTDOWN]: Shutdown processing on main thread complete. Exiting..."); | 139 | Watchdog.Enabled = false; |
140 | base.ShutdownSpecific(); | ||
141 | |||
142 | MainServer.Stop(); | ||
143 | |||
144 | Thread.Sleep(5000); | ||
145 | Util.StopThreadPool(); | ||
146 | WorkManager.Stop(); | ||
112 | 147 | ||
148 | Thread.Sleep(1000); | ||
113 | RemovePIDFile(); | 149 | RemovePIDFile(); |
114 | 150 | ||
115 | base.ShutdownSpecific(); | 151 | m_log.Info("[SHUTDOWN]: Shutdown processing on main thread complete. Exiting..."); |
116 | 152 | ||
117 | if (!SuppressExit) | 153 | if (!SuppressExit) |
118 | Environment.Exit(0); | 154 | Environment.Exit(0); |
119 | } | 155 | } |
120 | 156 | ||
@@ -163,8 +199,7 @@ namespace OpenSim.Framework.Servers | |||
163 | } | 199 | } |
164 | catch(Exception e) | 200 | catch(Exception e) |
165 | { | 201 | { |
166 | m_log.FatalFormat("Fatal error: {0}", | 202 | m_log.Fatal("Fatal error: " + e.ToString()); |
167 | (e.Message == null || e.Message == String.Empty) ? "Unknown reason":e.Message ); | ||
168 | Environment.Exit(1); | 203 | Environment.Exit(1); |
169 | } | 204 | } |
170 | 205 | ||
diff --git a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs index fb92b92..2819bc9 100644 --- a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs +++ b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs | |||
@@ -32,6 +32,7 @@ using System.Collections.Specialized; | |||
32 | using System.IO; | 32 | using System.IO; |
33 | using System.Net; | 33 | using System.Net; |
34 | using System.Net.Sockets; | 34 | using System.Net.Sockets; |
35 | using System.Net.Security; | ||
35 | using System.Security.Cryptography.X509Certificates; | 36 | using System.Security.Cryptography.X509Certificates; |
36 | using System.Reflection; | 37 | using System.Reflection; |
37 | using System.Globalization; | 38 | using System.Globalization; |
@@ -43,10 +44,11 @@ using log4net; | |||
43 | using Nwc.XmlRpc; | 44 | using Nwc.XmlRpc; |
44 | using OpenMetaverse.StructuredData; | 45 | using OpenMetaverse.StructuredData; |
45 | using CoolHTTPListener = HttpServer.HttpListener; | 46 | using CoolHTTPListener = HttpServer.HttpListener; |
46 | using HttpListener=System.Net.HttpListener; | 47 | using HttpListener = System.Net.HttpListener; |
47 | using LogPrio=HttpServer.LogPrio; | 48 | using LogPrio = HttpServer.LogPrio; |
48 | using OpenSim.Framework.Monitoring; | 49 | using OpenSim.Framework.Monitoring; |
49 | using System.IO.Compression; | 50 | using System.IO.Compression; |
51 | using System.Security.Cryptography; | ||
50 | 52 | ||
51 | namespace OpenSim.Framework.Servers.HttpServer | 53 | namespace OpenSim.Framework.Servers.HttpServer |
52 | { | 54 | { |
@@ -107,19 +109,26 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
107 | new Dictionary<string, WebSocketRequestDelegate>(); | 109 | new Dictionary<string, WebSocketRequestDelegate>(); |
108 | 110 | ||
109 | protected uint m_port; | 111 | protected uint m_port; |
110 | protected uint m_sslport; | ||
111 | protected bool m_ssl; | 112 | protected bool m_ssl; |
112 | private X509Certificate2 m_cert; | 113 | private X509Certificate2 m_cert; |
113 | protected bool m_firstcaps = true; | ||
114 | protected string m_SSLCommonName = ""; | 114 | protected string m_SSLCommonName = ""; |
115 | protected List<string> m_certNames = new List<string>(); | ||
116 | protected List<string> m_certIPs = new List<string>(); | ||
117 | protected string m_certCN= ""; | ||
118 | protected RemoteCertificateValidationCallback m_certificateValidationCallback = null; | ||
115 | 119 | ||
116 | protected IPAddress m_listenIPAddress = IPAddress.Any; | 120 | protected IPAddress m_listenIPAddress = IPAddress.Any; |
117 | 121 | ||
118 | public PollServiceRequestManager PollServiceRequestManager { get; private set; } | 122 | public PollServiceRequestManager PollServiceRequestManager { get; private set; } |
119 | 123 | ||
124 | public string Protocol | ||
125 | { | ||
126 | get { return m_ssl ? "https://" : "http://"; } | ||
127 | } | ||
128 | |||
120 | public uint SSLPort | 129 | public uint SSLPort |
121 | { | 130 | { |
122 | get { return m_sslport; } | 131 | get { return m_port; } |
123 | } | 132 | } |
124 | 133 | ||
125 | public string SSLCommonName | 134 | public string SSLCommonName |
@@ -148,27 +157,166 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
148 | m_port = port; | 157 | m_port = port; |
149 | } | 158 | } |
150 | 159 | ||
151 | public BaseHttpServer(uint port, bool ssl) : this (port) | 160 | private void load_cert(string CPath, string CPass) |
152 | { | 161 | { |
153 | m_ssl = ssl; | 162 | try |
163 | { | ||
164 | m_cert = new X509Certificate2(CPath, CPass); | ||
165 | X509Extension ext = m_cert.Extensions["2.5.29.17"]; | ||
166 | if(ext != null) | ||
167 | { | ||
168 | AsnEncodedData asndata = new AsnEncodedData(ext.Oid, ext.RawData); | ||
169 | string datastr = asndata.Format(true); | ||
170 | string[] lines = datastr.Split(new char[] {'\n','\r'}); | ||
171 | foreach(string s in lines) | ||
172 | { | ||
173 | if(String.IsNullOrEmpty(s)) | ||
174 | continue; | ||
175 | string[] parts = s.Split(new char[] {'='}); | ||
176 | if(String.IsNullOrEmpty(parts[0])) | ||
177 | continue; | ||
178 | string entryName = parts[0].Replace(" ",""); | ||
179 | if(entryName == "DNSName") | ||
180 | m_certNames.Add(parts[1]); | ||
181 | else if(entryName == "IPAddress") | ||
182 | m_certIPs.Add(parts[1]); | ||
183 | else if(entryName == "Unknown(135)") // stupid mono | ||
184 | { | ||
185 | try | ||
186 | { | ||
187 | if(parts[1].Length == 8) | ||
188 | { | ||
189 | long tmp = long.Parse(parts[1], NumberStyles.AllowHexSpecifier); | ||
190 | tmp = IPAddress.HostToNetworkOrder(tmp); | ||
191 | tmp = (long)((ulong) tmp >> 32); | ||
192 | IPAddress ia = new IPAddress(tmp); | ||
193 | m_certIPs.Add(ia.ToString()); | ||
194 | } | ||
195 | } | ||
196 | catch {} | ||
197 | } | ||
198 | } | ||
199 | } | ||
200 | m_certCN = m_cert.GetNameInfo(X509NameType.SimpleName, false); | ||
201 | } | ||
202 | catch | ||
203 | { | ||
204 | throw new Exception("SSL cert load error"); | ||
205 | } | ||
154 | } | 206 | } |
155 | 207 | ||
156 | public BaseHttpServer(uint port, bool ssl, uint sslport, string CN) : this (port, ssl) | 208 | public BaseHttpServer(uint port, bool ssl, string CN, string CPath, string CPass) |
157 | { | 209 | { |
158 | if (m_ssl) | 210 | m_port = port; |
211 | if (ssl) | ||
159 | { | 212 | { |
160 | m_sslport = sslport; | 213 | if(string.IsNullOrEmpty(CPath)) |
214 | throw new Exception("invalid main http server cert path"); | ||
215 | |||
216 | if(Uri.CheckHostName(CN) == UriHostNameType.Unknown) | ||
217 | throw new Exception("invalid main http server CN (ExternalHostName)"); | ||
218 | |||
219 | m_certNames.Clear(); | ||
220 | m_certIPs.Clear(); | ||
221 | m_certCN= ""; | ||
222 | |||
223 | m_ssl = true; | ||
224 | load_cert(CPath, CPass); | ||
225 | |||
226 | if(!CheckSSLCertHost(CN)) | ||
227 | throw new Exception("invalid main http server CN (ExternalHostName)"); | ||
228 | |||
229 | m_SSLCommonName = CN; | ||
230 | |||
231 | if(m_cert.Issuer == m_cert.Subject ) | ||
232 | m_log.Warn("Self signed certificate. Clients need to allow this (some viewers debug option NoVerifySSLcert must be set to true"); | ||
161 | } | 233 | } |
234 | else | ||
235 | m_ssl = false; | ||
162 | } | 236 | } |
163 | 237 | ||
164 | public BaseHttpServer(uint port, bool ssl, string CPath, string CPass) : this (port, ssl) | 238 | public BaseHttpServer(uint port, bool ssl, string CPath, string CPass) |
165 | { | 239 | { |
166 | if (m_ssl) | 240 | m_port = port; |
241 | if (ssl) | ||
167 | { | 242 | { |
168 | m_cert = new X509Certificate2(CPath, CPass); | 243 | load_cert(CPath, CPass); |
244 | if(m_cert.Issuer == m_cert.Subject ) | ||
245 | m_log.Warn("Self signed certificate. Http clients need to allow this"); | ||
246 | m_ssl = true; | ||
247 | } | ||
248 | else | ||
249 | m_ssl = false; | ||
250 | } | ||
251 | |||
252 | static bool MatchDNS (string hostname, string dns) | ||
253 | { | ||
254 | int indx = dns.IndexOf ('*'); | ||
255 | if (indx == -1) | ||
256 | return (String.Compare(hostname, dns, true, CultureInfo.InvariantCulture) == 0); | ||
257 | |||
258 | int dnslen = dns.Length; | ||
259 | dnslen--; | ||
260 | if(indx == dnslen) | ||
261 | return true; // just * ? | ||
262 | |||
263 | if(indx > dnslen - 2) | ||
264 | return false; // 2 short ? | ||
265 | |||
266 | if (dns[indx + 1] != '.') | ||
267 | return false; | ||
268 | |||
269 | int indx2 = dns.IndexOf ('*', indx + 1); | ||
270 | if (indx2 != -1) | ||
271 | return false; // there can only be one; | ||
272 | |||
273 | string end = dns.Substring(indx + 1); | ||
274 | int hostlen = hostname.Length; | ||
275 | int endlen = end.Length; | ||
276 | int length = hostlen - endlen; | ||
277 | if (length <= 0) | ||
278 | return false; | ||
279 | |||
280 | if (String.Compare(hostname, length, end, 0, endlen, true, CultureInfo.InvariantCulture) != 0) | ||
281 | return false; | ||
282 | |||
283 | if (indx == 0) | ||
284 | { | ||
285 | indx2 = hostname.IndexOf ('.'); | ||
286 | return ((indx2 == -1) || (indx2 >= length)); | ||
287 | } | ||
288 | |||
289 | string start = dns.Substring (0, indx); | ||
290 | return (String.Compare (hostname, 0, start, 0, start.Length, true, CultureInfo.InvariantCulture) == 0); | ||
291 | } | ||
292 | |||
293 | public bool CheckSSLCertHost(string hostname) | ||
294 | { | ||
295 | UriHostNameType htype = Uri.CheckHostName(hostname); | ||
296 | |||
297 | if(htype == UriHostNameType.Unknown || htype == UriHostNameType.Basic) | ||
298 | return false; | ||
299 | if(htype == UriHostNameType.Dns) | ||
300 | { | ||
301 | foreach(string name in m_certNames) | ||
302 | { | ||
303 | if(MatchDNS(hostname, name)) | ||
304 | return true; | ||
305 | } | ||
306 | if(MatchDNS(hostname, m_certCN)) | ||
307 | return true; | ||
308 | } | ||
309 | else | ||
310 | { | ||
311 | foreach(string ip in m_certIPs) | ||
312 | { | ||
313 | if (String.Compare(hostname, ip, true, CultureInfo.InvariantCulture) == 0) | ||
314 | return true; | ||
315 | } | ||
169 | } | 316 | } |
170 | } | ||
171 | 317 | ||
318 | return false; | ||
319 | } | ||
172 | /// <summary> | 320 | /// <summary> |
173 | /// Add a stream handler to the http server. If the handler already exists, then nothing happens. | 321 | /// Add a stream handler to the http server. If the handler already exists, then nothing happens. |
174 | /// </summary> | 322 | /// </summary> |
@@ -396,14 +544,10 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
396 | if (psEvArgs.Request != null) | 544 | if (psEvArgs.Request != null) |
397 | { | 545 | { |
398 | OSHttpRequest req = new OSHttpRequest(context, request); | 546 | OSHttpRequest req = new OSHttpRequest(context, request); |
399 | 547 | string requestBody; | |
400 | Stream requestStream = req.InputStream; | ||
401 | |||
402 | Encoding encoding = Encoding.UTF8; | 548 | Encoding encoding = Encoding.UTF8; |
403 | StreamReader reader = new StreamReader(requestStream, encoding); | 549 | using(StreamReader reader = new StreamReader(req.InputStream, encoding)) |
404 | 550 | requestBody = reader.ReadToEnd(); | |
405 | string requestBody = reader.ReadToEnd(); | ||
406 | reader.Close(); | ||
407 | 551 | ||
408 | Hashtable keysvals = new Hashtable(); | 552 | Hashtable keysvals = new Hashtable(); |
409 | Hashtable headervals = new Hashtable(); | 553 | Hashtable headervals = new Hashtable(); |
@@ -461,8 +605,7 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
461 | } | 605 | } |
462 | 606 | ||
463 | OSHttpResponse resp = new OSHttpResponse(new HttpResponse(context, request),context); | 607 | OSHttpResponse resp = new OSHttpResponse(new HttpResponse(context, request),context); |
464 | resp.ReuseContext = true; | 608 | |
465 | // resp.ReuseContext = false; | ||
466 | HandleRequest(req, resp); | 609 | HandleRequest(req, resp); |
467 | 610 | ||
468 | // !!!HACK ALERT!!! | 611 | // !!!HACK ALERT!!! |
@@ -494,6 +637,8 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
494 | { | 637 | { |
495 | try | 638 | try |
496 | { | 639 | { |
640 | if(request.InputStream != null && request.InputStream.CanRead) | ||
641 | request.InputStream.Close(); | ||
497 | byte[] buffer500 = SendHTML500(response); | 642 | byte[] buffer500 = SendHTML500(response); |
498 | response.OutputStream.Write(buffer500, 0, buffer500.Length); | 643 | response.OutputStream.Write(buffer500, 0, buffer500.Length); |
499 | response.Send(); | 644 | response.Send(); |
@@ -541,7 +686,6 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
541 | // } | 686 | // } |
542 | // } | 687 | // } |
543 | 688 | ||
544 | //response.KeepAlive = true; | ||
545 | response.SendChunked = false; | 689 | response.SendChunked = false; |
546 | 690 | ||
547 | string path = request.RawUrl; | 691 | string path = request.RawUrl; |
@@ -565,15 +709,11 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
565 | { | 709 | { |
566 | //m_log.Debug("[BASE HTTP SERVER]: Found Caps based HTTP Handler"); | 710 | //m_log.Debug("[BASE HTTP SERVER]: Found Caps based HTTP Handler"); |
567 | IGenericHTTPHandler HTTPRequestHandler = requestHandler as IGenericHTTPHandler; | 711 | IGenericHTTPHandler HTTPRequestHandler = requestHandler as IGenericHTTPHandler; |
568 | Stream requestStream = request.InputStream; | ||
569 | 712 | ||
713 | string requestBody; | ||
570 | Encoding encoding = Encoding.UTF8; | 714 | Encoding encoding = Encoding.UTF8; |
571 | StreamReader reader = new StreamReader(requestStream, encoding); | 715 | using(StreamReader reader = new StreamReader(request.InputStream, encoding)) |
572 | 716 | requestBody = reader.ReadToEnd(); | |
573 | string requestBody = reader.ReadToEnd(); | ||
574 | |||
575 | reader.Close(); | ||
576 | //requestStream.Close(); | ||
577 | 717 | ||
578 | Hashtable keysvals = new Hashtable(); | 718 | Hashtable keysvals = new Hashtable(); |
579 | Hashtable headervals = new Hashtable(); | 719 | Hashtable headervals = new Hashtable(); |
@@ -613,7 +753,6 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
613 | else | 753 | else |
614 | { | 754 | { |
615 | IStreamHandler streamHandler = (IStreamHandler)requestHandler; | 755 | IStreamHandler streamHandler = (IStreamHandler)requestHandler; |
616 | |||
617 | using (MemoryStream memoryStream = new MemoryStream()) | 756 | using (MemoryStream memoryStream = new MemoryStream()) |
618 | { | 757 | { |
619 | streamHandler.Handle(path, request.InputStream, memoryStream, request, response); | 758 | streamHandler.Handle(path, request.InputStream, memoryStream, request, response); |
@@ -690,7 +829,8 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
690 | } | 829 | } |
691 | } | 830 | } |
692 | 831 | ||
693 | request.InputStream.Close(); | 832 | if(request.InputStream != null && request.InputStream.CanRead) |
833 | request.InputStream.Dispose(); | ||
694 | 834 | ||
695 | if (buffer != null) | 835 | if (buffer != null) |
696 | { | 836 | { |
@@ -723,10 +863,6 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
723 | requestEndTick = Environment.TickCount; | 863 | requestEndTick = Environment.TickCount; |
724 | 864 | ||
725 | response.Send(); | 865 | response.Send(); |
726 | |||
727 | //response.OutputStream.Close(); | ||
728 | |||
729 | //response.FreeContext(); | ||
730 | } | 866 | } |
731 | catch (SocketException e) | 867 | catch (SocketException e) |
732 | { | 868 | { |
@@ -758,6 +894,9 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
758 | } | 894 | } |
759 | finally | 895 | finally |
760 | { | 896 | { |
897 | if(request.InputStream != null && request.InputStream.CanRead) | ||
898 | request.InputStream.Close(); | ||
899 | |||
761 | // Every month or so this will wrap and give bad numbers, not really a problem | 900 | // Every month or so this will wrap and give bad numbers, not really a problem |
762 | // since its just for reporting | 901 | // since its just for reporting |
763 | int tickdiff = requestEndTick - requestStartTick; | 902 | int tickdiff = requestEndTick - requestStartTick; |
@@ -998,7 +1137,7 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
998 | { | 1137 | { |
999 | String requestBody; | 1138 | String requestBody; |
1000 | 1139 | ||
1001 | Stream requestStream = request.InputStream; | 1140 | Stream requestStream = Util.Copy(request.InputStream); |
1002 | Stream innerStream = null; | 1141 | Stream innerStream = null; |
1003 | try | 1142 | try |
1004 | { | 1143 | { |
@@ -1009,15 +1148,15 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
1009 | } | 1148 | } |
1010 | 1149 | ||
1011 | using (StreamReader reader = new StreamReader(requestStream, Encoding.UTF8)) | 1150 | using (StreamReader reader = new StreamReader(requestStream, Encoding.UTF8)) |
1012 | { | ||
1013 | requestBody = reader.ReadToEnd(); | 1151 | requestBody = reader.ReadToEnd(); |
1152 | |||
1014 | } | 1153 | } |
1015 | } | ||
1016 | finally | 1154 | finally |
1017 | { | 1155 | { |
1018 | if (innerStream != null) | 1156 | if (innerStream != null && innerStream.CanRead) |
1019 | innerStream.Dispose(); | 1157 | innerStream.Dispose(); |
1020 | requestStream.Dispose(); | 1158 | if (requestStream.CanRead) |
1159 | requestStream.Dispose(); | ||
1021 | } | 1160 | } |
1022 | 1161 | ||
1023 | //m_log.Debug(requestBody); | 1162 | //m_log.Debug(requestBody); |
@@ -1098,6 +1237,17 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
1098 | 1237 | ||
1099 | if (gridproxy) | 1238 | if (gridproxy) |
1100 | xmlRprcRequest.Params.Add("gridproxy"); // Param[4] | 1239 | xmlRprcRequest.Params.Add("gridproxy"); // Param[4] |
1240 | |||
1241 | // reserve this for | ||
1242 | // ... by Fumi.Iseki for DTLNSLMoneyServer | ||
1243 | // BUT make its presence possible to detect/parse | ||
1244 | string rcn = request.IHttpClientContext.SSLCommonName; | ||
1245 | if(!string.IsNullOrWhiteSpace(rcn)) | ||
1246 | { | ||
1247 | rcn = "SSLCN:" + rcn; | ||
1248 | xmlRprcRequest.Params.Add(rcn); // Param[4] or Param[5] | ||
1249 | } | ||
1250 | |||
1101 | try | 1251 | try |
1102 | { | 1252 | { |
1103 | xmlRpcResponse = method(xmlRprcRequest, request.RemoteIPEndPoint); | 1253 | xmlRpcResponse = method(xmlRprcRequest, request.RemoteIPEndPoint); |
@@ -1263,15 +1413,12 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
1263 | //m_log.Warn("[BASE HTTP SERVER]: We've figured out it's a LLSD Request"); | 1413 | //m_log.Warn("[BASE HTTP SERVER]: We've figured out it's a LLSD Request"); |
1264 | Stream requestStream = request.InputStream; | 1414 | Stream requestStream = request.InputStream; |
1265 | 1415 | ||
1416 | string requestBody; | ||
1266 | Encoding encoding = Encoding.UTF8; | 1417 | Encoding encoding = Encoding.UTF8; |
1267 | StreamReader reader = new StreamReader(requestStream, encoding); | 1418 | using(StreamReader reader = new StreamReader(requestStream, encoding)) |
1268 | 1419 | requestBody= reader.ReadToEnd(); | |
1269 | string requestBody = reader.ReadToEnd(); | ||
1270 | reader.Close(); | ||
1271 | requestStream.Close(); | ||
1272 | 1420 | ||
1273 | //m_log.DebugFormat("[OGP]: {0}:{1}", request.RawUrl, requestBody); | 1421 | //m_log.DebugFormat("[OGP]: {0}:{1}", request.RawUrl, requestBody); |
1274 | response.KeepAlive = true; | ||
1275 | 1422 | ||
1276 | OSD llsdRequest = null; | 1423 | OSD llsdRequest = null; |
1277 | OSD llsdResponse = null; | 1424 | OSD llsdResponse = null; |
@@ -1592,15 +1739,10 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
1592 | byte[] buffer; | 1739 | byte[] buffer; |
1593 | 1740 | ||
1594 | Stream requestStream = request.InputStream; | 1741 | Stream requestStream = request.InputStream; |
1595 | 1742 | string requestBody; | |
1596 | Encoding encoding = Encoding.UTF8; | 1743 | Encoding encoding = Encoding.UTF8; |
1597 | StreamReader reader = new StreamReader(requestStream, encoding); | 1744 | using(StreamReader reader = new StreamReader(requestStream, encoding)) |
1598 | 1745 | requestBody = reader.ReadToEnd(); | |
1599 | string requestBody = reader.ReadToEnd(); | ||
1600 | // avoid warning for now | ||
1601 | reader.ReadToEnd(); | ||
1602 | reader.Close(); | ||
1603 | requestStream.Close(); | ||
1604 | 1746 | ||
1605 | Hashtable keysvals = new Hashtable(); | 1747 | Hashtable keysvals = new Hashtable(); |
1606 | Hashtable headervals = new Hashtable(); | 1748 | Hashtable headervals = new Hashtable(); |
@@ -1792,20 +1934,13 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
1792 | { | 1934 | { |
1793 | response.ProtocolVersion = (string)responsedata["http_protocol_version"]; | 1935 | response.ProtocolVersion = (string)responsedata["http_protocol_version"]; |
1794 | } | 1936 | } |
1795 | /* | 1937 | |
1796 | if (responsedata.ContainsKey("keepalive")) | 1938 | if (responsedata.ContainsKey("keepalive")) |
1797 | { | 1939 | { |
1798 | bool keepalive = (bool)responsedata["keepalive"]; | 1940 | bool keepalive = (bool)responsedata["keepalive"]; |
1799 | response.KeepAlive = keepalive; | 1941 | response.KeepAlive = keepalive; |
1800 | } | 1942 | } |
1801 | 1943 | ||
1802 | if (responsedata.ContainsKey("reusecontext")) | ||
1803 | response.ReuseContext = (bool) responsedata["reusecontext"]; | ||
1804 | */ | ||
1805 | // disable this things | ||
1806 | response.KeepAlive = false; | ||
1807 | response.ReuseContext = false; | ||
1808 | |||
1809 | // Cross-Origin Resource Sharing with simple requests | 1944 | // Cross-Origin Resource Sharing with simple requests |
1810 | if (responsedata.ContainsKey("access_control_allow_origin")) | 1945 | if (responsedata.ContainsKey("access_control_allow_origin")) |
1811 | response.AddHeader("Access-Control-Allow-Origin", (string)responsedata["access_control_allow_origin"]); | 1946 | response.AddHeader("Access-Control-Allow-Origin", (string)responsedata["access_control_allow_origin"]); |
@@ -1818,11 +1953,8 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
1818 | contentType = "text/html"; | 1953 | contentType = "text/html"; |
1819 | } | 1954 | } |
1820 | 1955 | ||
1821 | |||
1822 | |||
1823 | // The client ignores anything but 200 here for web login, so ensure that this is 200 for that | 1956 | // The client ignores anything but 200 here for web login, so ensure that this is 200 for that |
1824 | 1957 | ||
1825 | |||
1826 | response.StatusCode = responsecode; | 1958 | response.StatusCode = responsecode; |
1827 | 1959 | ||
1828 | if (responsecode == (int)OSHttpStatusCode.RedirectMovedPermanently) | 1960 | if (responsecode == (int)OSHttpStatusCode.RedirectMovedPermanently) |
@@ -1832,13 +1964,12 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
1832 | } | 1964 | } |
1833 | 1965 | ||
1834 | response.AddHeader("Content-Type", contentType); | 1966 | response.AddHeader("Content-Type", contentType); |
1835 | |||
1836 | if (responsedata.ContainsKey("headers")) | 1967 | if (responsedata.ContainsKey("headers")) |
1837 | { | 1968 | { |
1838 | Hashtable headerdata = (Hashtable)responsedata["headers"]; | 1969 | Hashtable headerdata = (Hashtable)responsedata["headers"]; |
1839 | 1970 | ||
1840 | foreach (string header in headerdata.Keys) | 1971 | foreach (string header in headerdata.Keys) |
1841 | response.AddHeader(header, (string)headerdata[header]); | 1972 | response.AddHeader(header, headerdata[header].ToString()); |
1842 | } | 1973 | } |
1843 | 1974 | ||
1844 | byte[] buffer; | 1975 | byte[] buffer; |
@@ -1906,7 +2037,7 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
1906 | 2037 | ||
1907 | public void Start() | 2038 | public void Start() |
1908 | { | 2039 | { |
1909 | Start(true); | 2040 | Start(true,true); |
1910 | } | 2041 | } |
1911 | 2042 | ||
1912 | /// <summary> | 2043 | /// <summary> |
@@ -1916,7 +2047,7 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
1916 | /// If true then poll responses are performed asynchronsly. | 2047 | /// If true then poll responses are performed asynchronsly. |
1917 | /// Option exists to allow regression tests to perform processing synchronously. | 2048 | /// Option exists to allow regression tests to perform processing synchronously. |
1918 | /// </param> | 2049 | /// </param> |
1919 | public void Start(bool performPollResponsesAsync) | 2050 | public void Start(bool performPollResponsesAsync, bool runPool) |
1920 | { | 2051 | { |
1921 | m_log.InfoFormat( | 2052 | m_log.InfoFormat( |
1922 | "[BASE HTTP SERVER]: Starting {0} server on port {1}", UseSSL ? "HTTPS" : "HTTP", Port); | 2053 | "[BASE HTTP SERVER]: Starting {0} server on port {1}", UseSSL ? "HTTPS" : "HTTP", Port); |
@@ -1945,6 +2076,8 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
1945 | //m_httpListener.Prefixes.Add("https://+:" + (m_sslport) + "/"); | 2076 | //m_httpListener.Prefixes.Add("https://+:" + (m_sslport) + "/"); |
1946 | //m_httpListener.Prefixes.Add("http://+:" + m_port + "/"); | 2077 | //m_httpListener.Prefixes.Add("http://+:" + m_port + "/"); |
1947 | m_httpListener2 = CoolHTTPListener.Create(IPAddress.Any, (int)m_port, m_cert); | 2078 | m_httpListener2 = CoolHTTPListener.Create(IPAddress.Any, (int)m_port, m_cert); |
2079 | if(m_certificateValidationCallback != null) | ||
2080 | m_httpListener2.CertificateValidationCallback = m_certificateValidationCallback; | ||
1948 | m_httpListener2.ExceptionThrown += httpServerException; | 2081 | m_httpListener2.ExceptionThrown += httpServerException; |
1949 | m_httpListener2.LogWriter = httpserverlog; | 2082 | m_httpListener2.LogWriter = httpserverlog; |
1950 | } | 2083 | } |
@@ -1954,9 +2087,11 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
1954 | m_httpListener2.Start(64); | 2087 | m_httpListener2.Start(64); |
1955 | 2088 | ||
1956 | // Long Poll Service Manager with 3 worker threads a 25 second timeout for no events | 2089 | // Long Poll Service Manager with 3 worker threads a 25 second timeout for no events |
1957 | 2090 | if(runPool) | |
1958 | PollServiceRequestManager = new PollServiceRequestManager(this, performPollResponsesAsync, 2, 25000); | 2091 | { |
1959 | PollServiceRequestManager.Start(); | 2092 | PollServiceRequestManager = new PollServiceRequestManager(this, performPollResponsesAsync, 2, 25000); |
2093 | PollServiceRequestManager.Start(); | ||
2094 | } | ||
1960 | 2095 | ||
1961 | HTTPDRunning = true; | 2096 | HTTPDRunning = true; |
1962 | 2097 | ||
@@ -1970,7 +2105,7 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
1970 | catch (Exception e) | 2105 | catch (Exception e) |
1971 | { | 2106 | { |
1972 | m_log.Error("[BASE HTTP SERVER]: Error - " + e.Message); | 2107 | m_log.Error("[BASE HTTP SERVER]: Error - " + e.Message); |
1973 | m_log.Error("[BASE HTTP SERVER]: Tip: Do you have permission to listen on port " + m_port + ", " + m_sslport + "?"); | 2108 | m_log.Error("[BASE HTTP SERVER]: Tip: Do you have permission to listen on port " + m_port + "?"); |
1974 | 2109 | ||
1975 | // We want this exception to halt the entire server since in current configurations we aren't too | 2110 | // We want this exception to halt the entire server since in current configurations we aren't too |
1976 | // useful without inbound HTTP. | 2111 | // useful without inbound HTTP. |
@@ -2028,7 +2163,8 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
2028 | 2163 | ||
2029 | try | 2164 | try |
2030 | { | 2165 | { |
2031 | PollServiceRequestManager.Stop(); | 2166 | if(PollServiceRequestManager != null) |
2167 | PollServiceRequestManager.Stop(); | ||
2032 | 2168 | ||
2033 | m_httpListener2.ExceptionThrown -= httpServerException; | 2169 | m_httpListener2.ExceptionThrown -= httpServerException; |
2034 | //m_httpListener2.DisconnectHandler = null; | 2170 | //m_httpListener2.DisconnectHandler = null; |
@@ -2135,10 +2271,9 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
2135 | string file = Path.Combine(".", "http_500.html"); | 2271 | string file = Path.Combine(".", "http_500.html"); |
2136 | if (!File.Exists(file)) | 2272 | if (!File.Exists(file)) |
2137 | return getDefaultHTTP500(); | 2273 | return getDefaultHTTP500(); |
2138 | 2274 | string result; | |
2139 | StreamReader sr = File.OpenText(file); | 2275 | using(StreamReader sr = File.OpenText(file)) |
2140 | string result = sr.ReadToEnd(); | 2276 | result = sr.ReadToEnd(); |
2141 | sr.Close(); | ||
2142 | return result; | 2277 | return result; |
2143 | } | 2278 | } |
2144 | 2279 | ||
diff --git a/OpenSim/Framework/Servers/HttpServer/Interfaces/IOSHttpResponse.cs b/OpenSim/Framework/Servers/HttpServer/Interfaces/IOSHttpResponse.cs index f61b090..d26b68a 100644 --- a/OpenSim/Framework/Servers/HttpServer/Interfaces/IOSHttpResponse.cs +++ b/OpenSim/Framework/Servers/HttpServer/Interfaces/IOSHttpResponse.cs | |||
@@ -118,7 +118,7 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
118 | /// </summary> | 118 | /// </summary> |
119 | string StatusDescription { get; set; } | 119 | string StatusDescription { get; set; } |
120 | 120 | ||
121 | bool ReuseContext { get; set; } | 121 | // bool ReuseContext { get; set; } |
122 | 122 | ||
123 | /// <summary> | 123 | /// <summary> |
124 | /// Add a header field and content to the response. | 124 | /// Add a header field and content to the response. |
diff --git a/OpenSim/Framework/Servers/HttpServer/OSHttpResponse.cs b/OpenSim/Framework/Servers/HttpServer/OSHttpResponse.cs index d7744fc..a107ced 100644 --- a/OpenSim/Framework/Servers/HttpServer/OSHttpResponse.cs +++ b/OpenSim/Framework/Servers/HttpServer/OSHttpResponse.cs | |||
@@ -257,25 +257,6 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
257 | } | 257 | } |
258 | } | 258 | } |
259 | 259 | ||
260 | public bool ReuseContext | ||
261 | { | ||
262 | get | ||
263 | { | ||
264 | if (_httpClientContext != null) | ||
265 | { | ||
266 | return !_httpClientContext.EndWhenDone; | ||
267 | } | ||
268 | return true; | ||
269 | } | ||
270 | set | ||
271 | { | ||
272 | if (_httpClientContext != null) | ||
273 | { | ||
274 | _httpClientContext.EndWhenDone = !value; | ||
275 | } | ||
276 | } | ||
277 | } | ||
278 | |||
279 | protected IHttpResponse _httpResponse; | 260 | protected IHttpResponse _httpResponse; |
280 | private IHttpClientContext _httpClientContext; | 261 | private IHttpClientContext _httpClientContext; |
281 | 262 | ||
diff --git a/OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs b/OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs index 8ace7a9..7c7d08d 100644 --- a/OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs +++ b/OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs | |||
@@ -37,6 +37,7 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
37 | public delegate Hashtable GetEventsMethod(UUID requestID, UUID pId); | 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 | public delegate void DropMethod(UUID requestID, UUID pId); | ||
40 | 41 | ||
41 | public class PollServiceEventArgs : EventArgs | 42 | public class PollServiceEventArgs : EventArgs |
42 | { | 43 | { |
@@ -44,13 +45,14 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
44 | public GetEventsMethod GetEvents; | 45 | public GetEventsMethod GetEvents; |
45 | public NoEventsMethod NoEvents; | 46 | public NoEventsMethod NoEvents; |
46 | public RequestMethod Request; | 47 | public RequestMethod Request; |
48 | public DropMethod Drop; | ||
47 | public UUID Id; | 49 | public UUID Id; |
48 | public int TimeOutms; | 50 | public int TimeOutms; |
49 | public EventType Type; | 51 | public EventType Type; |
50 | 52 | ||
51 | public enum EventType : int | 53 | public enum EventType : int |
52 | { | 54 | { |
53 | LongPoll = 0, | 55 | Poll = 0, |
54 | LslHttp = 1, | 56 | LslHttp = 1, |
55 | Inventory = 2, | 57 | Inventory = 2, |
56 | Texture = 3, | 58 | Texture = 3, |
@@ -73,16 +75,17 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
73 | RequestMethod pRequest, | 75 | RequestMethod pRequest, |
74 | string pUrl, | 76 | string pUrl, |
75 | HasEventsMethod pHasEvents, GetEventsMethod pGetEvents, NoEventsMethod pNoEvents, | 77 | HasEventsMethod pHasEvents, GetEventsMethod pGetEvents, NoEventsMethod pNoEvents, |
76 | UUID pId, int pTimeOutms) | 78 | DropMethod pDrop, UUID pId, int pTimeOutms) |
77 | { | 79 | { |
78 | Request = pRequest; | 80 | Request = pRequest; |
79 | Url = pUrl; | 81 | Url = pUrl; |
80 | HasEvents = pHasEvents; | 82 | HasEvents = pHasEvents; |
81 | GetEvents = pGetEvents; | 83 | GetEvents = pGetEvents; |
82 | NoEvents = pNoEvents; | 84 | NoEvents = pNoEvents; |
85 | Drop = pDrop; | ||
83 | Id = pId; | 86 | Id = pId; |
84 | TimeOutms = pTimeOutms; | 87 | TimeOutms = pTimeOutms; |
85 | Type = EventType.LongPoll; | 88 | Type = EventType.Poll; |
86 | } | 89 | } |
87 | } | 90 | } |
88 | } | 91 | } |
diff --git a/OpenSim/Framework/Servers/HttpServer/PollServiceHttpRequest.cs b/OpenSim/Framework/Servers/HttpServer/PollServiceHttpRequest.cs index 3eb330a..4fd69f3 100644 --- a/OpenSim/Framework/Servers/HttpServer/PollServiceHttpRequest.cs +++ b/OpenSim/Framework/Servers/HttpServer/PollServiceHttpRequest.cs | |||
@@ -47,8 +47,10 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
47 | public readonly UUID RequestID; | 47 | public readonly UUID RequestID; |
48 | public int contextHash; | 48 | public int contextHash; |
49 | 49 | ||
50 | /* | ||
50 | private void GenContextHash() | 51 | private void GenContextHash() |
51 | { | 52 | { |
53 | |||
52 | Random rnd = new Random(); | 54 | Random rnd = new Random(); |
53 | contextHash = 0; | 55 | contextHash = 0; |
54 | if (Request.Headers["remote_addr"] != null) | 56 | if (Request.Headers["remote_addr"] != null) |
@@ -62,8 +64,9 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
62 | } | 64 | } |
63 | else | 65 | else |
64 | contextHash += rnd.Next() & 0xffff; | 66 | contextHash += rnd.Next() & 0xffff; |
65 | } | ||
66 | 67 | ||
68 | } | ||
69 | */ | ||
67 | public PollServiceHttpRequest( | 70 | public PollServiceHttpRequest( |
68 | PollServiceEventArgs pPollServiceArgs, IHttpClientContext pHttpContext, IHttpRequest pRequest) | 71 | PollServiceEventArgs pPollServiceArgs, IHttpClientContext pHttpContext, IHttpRequest pRequest) |
69 | { | 72 | { |
@@ -72,7 +75,8 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
72 | Request = pRequest; | 75 | Request = pRequest; |
73 | RequestTime = System.Environment.TickCount; | 76 | RequestTime = System.Environment.TickCount; |
74 | RequestID = UUID.Random(); | 77 | RequestID = UUID.Random(); |
75 | GenContextHash(); | 78 | // GenContextHash(); |
79 | contextHash = HttpContext.contextID; | ||
76 | } | 80 | } |
77 | 81 | ||
78 | internal void DoHTTPGruntWork(BaseHttpServer server, Hashtable responsedata) | 82 | internal void DoHTTPGruntWork(BaseHttpServer server, Hashtable responsedata) |
@@ -82,10 +86,12 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
82 | 86 | ||
83 | byte[] buffer = server.DoHTTPGruntWork(responsedata, response); | 87 | byte[] buffer = server.DoHTTPGruntWork(responsedata, response); |
84 | 88 | ||
89 | if(Request.Body.CanRead) | ||
90 | Request.Body.Dispose(); | ||
91 | |||
85 | response.SendChunked = false; | 92 | response.SendChunked = false; |
86 | response.ContentLength64 = buffer.Length; | 93 | response.ContentLength64 = buffer.Length; |
87 | response.ContentEncoding = Encoding.UTF8; | 94 | response.ContentEncoding = Encoding.UTF8; |
88 | response.ReuseContext = false; | ||
89 | 95 | ||
90 | try | 96 | try |
91 | { | 97 | { |
@@ -114,10 +120,12 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
114 | OSHttpResponse response | 120 | OSHttpResponse response |
115 | = new OSHttpResponse(new HttpResponse(HttpContext, Request), HttpContext); | 121 | = new OSHttpResponse(new HttpResponse(HttpContext, Request), HttpContext); |
116 | 122 | ||
123 | if(Request.Body.CanRead) | ||
124 | Request.Body.Dispose(); | ||
125 | |||
117 | response.SendChunked = false; | 126 | response.SendChunked = false; |
118 | response.ContentLength64 = 0; | 127 | response.ContentLength64 = 0; |
119 | response.ContentEncoding = Encoding.UTF8; | 128 | response.ContentEncoding = Encoding.UTF8; |
120 | response.ReuseContext = false; | ||
121 | response.KeepAlive = false; | 129 | response.KeepAlive = false; |
122 | response.SendChunked = false; | 130 | response.SendChunked = false; |
123 | response.StatusCode = 503; | 131 | response.StatusCode = 503; |
@@ -127,7 +135,7 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
127 | response.OutputStream.Flush(); | 135 | response.OutputStream.Flush(); |
128 | response.Send(); | 136 | response.Send(); |
129 | } | 137 | } |
130 | catch (Exception e) | 138 | catch |
131 | { | 139 | { |
132 | } | 140 | } |
133 | } | 141 | } |
diff --git a/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs b/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs index 936146d..a2f6a11 100644 --- a/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs +++ b/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs | |||
@@ -30,13 +30,10 @@ using System.Collections; | |||
30 | using System.Threading; | 30 | using System.Threading; |
31 | using System.Reflection; | 31 | using System.Reflection; |
32 | using log4net; | 32 | using log4net; |
33 | using HttpServer; | ||
34 | using OpenSim.Framework; | ||
35 | using OpenSim.Framework.Monitoring; | 33 | using OpenSim.Framework.Monitoring; |
36 | using Amib.Threading; | 34 | using Amib.Threading; |
37 | using System.IO; | ||
38 | using System.Text; | ||
39 | using System.Collections.Generic; | 35 | using System.Collections.Generic; |
36 | using System.Collections.Concurrent; | ||
40 | 37 | ||
41 | namespace OpenSim.Framework.Servers.HttpServer | 38 | namespace OpenSim.Framework.Servers.HttpServer |
42 | { | 39 | { |
@@ -46,21 +43,18 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
46 | 43 | ||
47 | private readonly BaseHttpServer m_server; | 44 | private readonly BaseHttpServer m_server; |
48 | 45 | ||
49 | private Dictionary<PollServiceHttpRequest, Queue<PollServiceHttpRequest>> m_bycontext; | 46 | private Dictionary<int, Queue<PollServiceHttpRequest>> m_bycontext; |
50 | private BlockingQueue<PollServiceHttpRequest> m_requests = new BlockingQueue<PollServiceHttpRequest>(); | 47 | private BlockingCollection<PollServiceHttpRequest> m_requests = new BlockingCollection<PollServiceHttpRequest>(); |
51 | private static Queue<PollServiceHttpRequest> m_slowRequests = new Queue<PollServiceHttpRequest>(); | 48 | private static ConcurrentQueue<PollServiceHttpRequest> m_retryRequests = new ConcurrentQueue<PollServiceHttpRequest>(); |
52 | private static Queue<PollServiceHttpRequest> m_retryRequests = new Queue<PollServiceHttpRequest>(); | ||
53 | 49 | ||
54 | private uint m_WorkerThreadCount = 0; | 50 | private uint m_WorkerThreadCount = 0; |
55 | private Thread[] m_workerThreads; | 51 | private Thread[] m_workerThreads; |
56 | private Thread m_retrysThread; | 52 | private Thread m_retrysThread; |
57 | 53 | ||
58 | private bool m_running = false; | 54 | private bool m_running = false; |
59 | private int slowCount = 0; | ||
60 | 55 | ||
61 | private SmartThreadPool m_threadPool; | 56 | private SmartThreadPool m_threadPool; |
62 | 57 | ||
63 | |||
64 | public PollServiceRequestManager( | 58 | public PollServiceRequestManager( |
65 | BaseHttpServer pSrv, bool performResponsesAsync, uint pWorkerThreadCount, int pTimeout) | 59 | BaseHttpServer pSrv, bool performResponsesAsync, uint pWorkerThreadCount, int pTimeout) |
66 | { | 60 | { |
@@ -68,8 +62,7 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
68 | m_WorkerThreadCount = pWorkerThreadCount; | 62 | m_WorkerThreadCount = pWorkerThreadCount; |
69 | m_workerThreads = new Thread[m_WorkerThreadCount]; | 63 | m_workerThreads = new Thread[m_WorkerThreadCount]; |
70 | 64 | ||
71 | PollServiceHttpRequestComparer preqCp = new PollServiceHttpRequestComparer(); | 65 | m_bycontext = new Dictionary<int, Queue<PollServiceHttpRequest>>(256); |
72 | m_bycontext = new Dictionary<PollServiceHttpRequest, Queue<PollServiceHttpRequest>>(preqCp); | ||
73 | 66 | ||
74 | STPStartInfo startInfo = new STPStartInfo(); | 67 | STPStartInfo startInfo = new STPStartInfo(); |
75 | startInfo.IdleTimeout = 30000; | 68 | startInfo.IdleTimeout = 30000; |
@@ -80,7 +73,6 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
80 | startInfo.ThreadPoolName = "PoolService"; | 73 | startInfo.ThreadPoolName = "PoolService"; |
81 | 74 | ||
82 | m_threadPool = new SmartThreadPool(startInfo); | 75 | m_threadPool = new SmartThreadPool(startInfo); |
83 | |||
84 | } | 76 | } |
85 | 77 | ||
86 | public void Start() | 78 | public void Start() |
@@ -95,7 +87,7 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
95 | PoolWorkerJob, | 87 | PoolWorkerJob, |
96 | string.Format("PollServiceWorkerThread {0}:{1}", i, m_server.Port), | 88 | string.Format("PollServiceWorkerThread {0}:{1}", i, m_server.Port), |
97 | ThreadPriority.Normal, | 89 | ThreadPriority.Normal, |
98 | false, | 90 | true, |
99 | false, | 91 | false, |
100 | null, | 92 | null, |
101 | int.MaxValue); | 93 | int.MaxValue); |
@@ -105,36 +97,32 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
105 | this.CheckRetries, | 97 | this.CheckRetries, |
106 | string.Format("PollServiceWatcherThread:{0}", m_server.Port), | 98 | string.Format("PollServiceWatcherThread:{0}", m_server.Port), |
107 | ThreadPriority.Normal, | 99 | ThreadPriority.Normal, |
108 | false, | 100 | true, |
109 | true, | 101 | true, |
110 | null, | 102 | null, |
111 | 1000 * 60 * 10); | 103 | 1000 * 60 * 10); |
112 | |||
113 | |||
114 | } | 104 | } |
115 | 105 | ||
116 | private void ReQueueEvent(PollServiceHttpRequest req) | 106 | private void ReQueueEvent(PollServiceHttpRequest req) |
117 | { | 107 | { |
118 | if (m_running) | 108 | if (m_running) |
119 | { | 109 | m_retryRequests.Enqueue(req); |
120 | lock (m_retryRequests) | ||
121 | m_retryRequests.Enqueue(req); | ||
122 | } | ||
123 | } | 110 | } |
124 | 111 | ||
125 | public void Enqueue(PollServiceHttpRequest req) | 112 | public void Enqueue(PollServiceHttpRequest req) |
126 | { | 113 | { |
114 | Queue<PollServiceHttpRequest> ctxQeueue; | ||
115 | int rhash = req.contextHash; | ||
127 | lock (m_bycontext) | 116 | lock (m_bycontext) |
128 | { | 117 | { |
129 | Queue<PollServiceHttpRequest> ctxQeueue; | 118 | if (m_bycontext.TryGetValue(rhash, out ctxQeueue)) |
130 | if (m_bycontext.TryGetValue(req, out ctxQeueue)) | ||
131 | { | 119 | { |
132 | ctxQeueue.Enqueue(req); | 120 | ctxQeueue.Enqueue(req); |
133 | } | 121 | } |
134 | else | 122 | else |
135 | { | 123 | { |
136 | ctxQeueue = new Queue<PollServiceHttpRequest>(); | 124 | ctxQeueue = new Queue<PollServiceHttpRequest>(); |
137 | m_bycontext[req] = ctxQeueue; | 125 | m_bycontext[rhash] = ctxQeueue; |
138 | EnqueueInt(req); | 126 | EnqueueInt(req); |
139 | } | 127 | } |
140 | } | 128 | } |
@@ -143,9 +131,10 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
143 | public void byContextDequeue(PollServiceHttpRequest req) | 131 | public void byContextDequeue(PollServiceHttpRequest req) |
144 | { | 132 | { |
145 | Queue<PollServiceHttpRequest> ctxQeueue; | 133 | Queue<PollServiceHttpRequest> ctxQeueue; |
134 | int rhash = req.contextHash; | ||
146 | lock (m_bycontext) | 135 | lock (m_bycontext) |
147 | { | 136 | { |
148 | if (m_bycontext.TryGetValue(req, out ctxQeueue)) | 137 | if (m_bycontext.TryGetValue(rhash, out ctxQeueue)) |
149 | { | 138 | { |
150 | if (ctxQeueue.Count > 0) | 139 | if (ctxQeueue.Count > 0) |
151 | { | 140 | { |
@@ -154,51 +143,41 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
154 | } | 143 | } |
155 | else | 144 | else |
156 | { | 145 | { |
157 | m_bycontext.Remove(req); | 146 | m_bycontext.Remove(rhash); |
158 | } | 147 | } |
159 | } | 148 | } |
160 | } | 149 | } |
161 | } | 150 | } |
162 | 151 | ||
163 | public void EnqueueInt(PollServiceHttpRequest req) | 152 | public void DropByContext(PollServiceHttpRequest req) |
164 | { | 153 | { |
165 | if (m_running) | 154 | Queue<PollServiceHttpRequest> ctxQeueue; |
155 | int rhash = req.contextHash; | ||
156 | lock (m_bycontext) | ||
166 | { | 157 | { |
167 | if (req.PollServiceArgs.Type != PollServiceEventArgs.EventType.LongPoll) | 158 | if (m_bycontext.TryGetValue(rhash, out ctxQeueue)) |
168 | { | 159 | { |
169 | m_requests.Enqueue(req); | 160 | ctxQeueue.Clear(); |
170 | } | 161 | m_bycontext.Remove(rhash); |
171 | else | ||
172 | { | ||
173 | lock (m_slowRequests) | ||
174 | m_slowRequests.Enqueue(req); | ||
175 | } | 162 | } |
176 | } | 163 | } |
177 | } | 164 | } |
178 | 165 | ||
166 | public void EnqueueInt(PollServiceHttpRequest req) | ||
167 | { | ||
168 | if (m_running) | ||
169 | m_requests.Add(req); | ||
170 | } | ||
171 | |||
179 | private void CheckRetries() | 172 | private void CheckRetries() |
180 | { | 173 | { |
174 | PollServiceHttpRequest preq; | ||
181 | while (m_running) | 175 | while (m_running) |
182 | |||
183 | { | 176 | { |
184 | Thread.Sleep(100); // let the world move .. back to faster rate | 177 | Thread.Sleep(100); |
185 | Watchdog.UpdateThread(); | 178 | Watchdog.UpdateThread(); |
186 | lock (m_retryRequests) | 179 | while (m_running && m_retryRequests.TryDequeue(out preq)) |
187 | { | 180 | m_requests.Add(preq); |
188 | while (m_retryRequests.Count > 0 && m_running) | ||
189 | m_requests.Enqueue(m_retryRequests.Dequeue()); | ||
190 | } | ||
191 | slowCount++; | ||
192 | if (slowCount >= 10) | ||
193 | { | ||
194 | slowCount = 0; | ||
195 | |||
196 | lock (m_slowRequests) | ||
197 | { | ||
198 | while (m_slowRequests.Count > 0 && m_running) | ||
199 | m_requests.Enqueue(m_slowRequests.Dequeue()); | ||
200 | } | ||
201 | } | ||
202 | } | 181 | } |
203 | } | 182 | } |
204 | 183 | ||
@@ -206,117 +185,130 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
206 | { | 185 | { |
207 | m_running = false; | 186 | m_running = false; |
208 | 187 | ||
209 | Thread.Sleep(1000); // let the world move | 188 | Thread.Sleep(100); // let the world move |
210 | 189 | ||
211 | foreach (Thread t in m_workerThreads) | 190 | foreach (Thread t in m_workerThreads) |
212 | Watchdog.AbortThread(t.ManagedThreadId); | 191 | Watchdog.AbortThread(t.ManagedThreadId); |
213 | 192 | ||
193 | m_threadPool.Shutdown(); | ||
194 | |||
214 | // any entry in m_bycontext should have a active request on the other queues | 195 | // any entry in m_bycontext should have a active request on the other queues |
215 | // so just delete contents to easy GC | 196 | // so just delete contents to easy GC |
216 | foreach (Queue<PollServiceHttpRequest> qu in m_bycontext.Values) | 197 | foreach (Queue<PollServiceHttpRequest> qu in m_bycontext.Values) |
217 | qu.Clear(); | 198 | qu.Clear(); |
218 | m_bycontext.Clear(); | 199 | m_bycontext.Clear(); |
219 | 200 | ||
201 | PollServiceHttpRequest req; | ||
220 | try | 202 | try |
221 | { | 203 | { |
222 | foreach (PollServiceHttpRequest req in m_retryRequests) | 204 | while(m_retryRequests.TryDequeue(out req)) |
223 | { | ||
224 | req.DoHTTPstop(m_server); | 205 | req.DoHTTPstop(m_server); |
225 | } | ||
226 | } | 206 | } |
227 | catch | 207 | catch |
228 | { | 208 | { |
229 | } | 209 | } |
230 | 210 | ||
231 | PollServiceHttpRequest wreq; | 211 | try |
232 | m_retryRequests.Clear(); | ||
233 | |||
234 | lock (m_slowRequests) | ||
235 | { | 212 | { |
236 | while (m_slowRequests.Count > 0) | 213 | while(m_requests.TryTake(out req, 0)) |
237 | m_requests.Enqueue(m_slowRequests.Dequeue()); | 214 | req.DoHTTPstop(m_server); |
238 | |||
239 | } | 215 | } |
240 | 216 | catch | |
241 | while (m_requests.Count() > 0) | ||
242 | { | 217 | { |
243 | try | ||
244 | { | ||
245 | wreq = m_requests.Dequeue(0); | ||
246 | wreq.DoHTTPstop(m_server); | ||
247 | |||
248 | } | ||
249 | catch | ||
250 | { | ||
251 | } | ||
252 | } | 218 | } |
253 | 219 | ||
254 | m_requests.Clear(); | 220 | m_requests.Dispose(); |
221 | |||
255 | } | 222 | } |
256 | 223 | ||
257 | // work threads | 224 | // work threads |
258 | 225 | ||
259 | private void PoolWorkerJob() | 226 | private void PoolWorkerJob() |
260 | { | 227 | { |
228 | PollServiceHttpRequest req; | ||
261 | while (m_running) | 229 | while (m_running) |
262 | { | 230 | { |
263 | PollServiceHttpRequest req = m_requests.Dequeue(5000); | 231 | req = null; |
232 | if(!m_requests.TryTake(out req, 4500) || req == null) | ||
233 | { | ||
234 | Watchdog.UpdateThread(); | ||
235 | continue; | ||
236 | } | ||
264 | 237 | ||
265 | Watchdog.UpdateThread(); | 238 | Watchdog.UpdateThread(); |
266 | if (req != null) | 239 | |
240 | try | ||
267 | { | 241 | { |
268 | try | 242 | if(!req.HttpContext.CanSend()) |
243 | { | ||
244 | req.PollServiceArgs.Drop(req.RequestID, req.PollServiceArgs.Id); | ||
245 | byContextDequeue(req); | ||
246 | continue; | ||
247 | } | ||
248 | |||
249 | if(req.HttpContext.IsSending()) | ||
269 | { | 250 | { |
270 | if (req.PollServiceArgs.HasEvents(req.RequestID, req.PollServiceArgs.Id)) | 251 | if ((Environment.TickCount - req.RequestTime) > req.PollServiceArgs.TimeOutms) |
271 | { | 252 | { |
272 | Hashtable responsedata = req.PollServiceArgs.GetEvents(req.RequestID, req.PollServiceArgs.Id); | 253 | req.PollServiceArgs.Drop(req.RequestID, req.PollServiceArgs.Id); |
254 | byContextDequeue(req); | ||
255 | } | ||
256 | else | ||
257 | ReQueueEvent(req); | ||
258 | continue; | ||
259 | } | ||
273 | 260 | ||
261 | if (req.PollServiceArgs.HasEvents(req.RequestID, req.PollServiceArgs.Id)) | ||
262 | { | ||
263 | PollServiceHttpRequest nreq = req; | ||
264 | m_threadPool.QueueWorkItem(x => | ||
265 | { | ||
266 | try | ||
267 | { | ||
268 | Hashtable responsedata = nreq.PollServiceArgs.GetEvents(nreq.RequestID, nreq.PollServiceArgs.Id); | ||
269 | nreq.DoHTTPGruntWork(m_server, responsedata); | ||
270 | } | ||
271 | catch (ObjectDisposedException) { } | ||
272 | finally | ||
273 | { | ||
274 | byContextDequeue(nreq); | ||
275 | nreq = null; | ||
276 | } | ||
277 | return null; | ||
278 | }, null); | ||
279 | } | ||
280 | else | ||
281 | { | ||
282 | if ((Environment.TickCount - req.RequestTime) > req.PollServiceArgs.TimeOutms) | ||
283 | { | ||
284 | PollServiceHttpRequest nreq = req; | ||
274 | m_threadPool.QueueWorkItem(x => | 285 | m_threadPool.QueueWorkItem(x => |
275 | { | 286 | { |
276 | try | 287 | try |
277 | { | 288 | { |
278 | req.DoHTTPGruntWork(m_server, responsedata); | 289 | nreq.DoHTTPGruntWork(m_server, |
279 | byContextDequeue(req); | 290 | nreq.PollServiceArgs.NoEvents(nreq.RequestID, nreq.PollServiceArgs.Id)); |
280 | } | 291 | } |
281 | catch (ObjectDisposedException) // Browser aborted before we could read body, server closed the stream | 292 | catch (ObjectDisposedException) {} |
293 | finally | ||
282 | { | 294 | { |
283 | // Ignore it, no need to reply | 295 | byContextDequeue(nreq); |
296 | nreq = null; | ||
284 | } | 297 | } |
285 | return null; | 298 | return null; |
286 | }, null); | 299 | }, null); |
287 | } | 300 | } |
288 | else | 301 | else |
289 | { | 302 | { |
290 | if ((Environment.TickCount - req.RequestTime) > req.PollServiceArgs.TimeOutms) | 303 | ReQueueEvent(req); |
291 | { | ||
292 | m_threadPool.QueueWorkItem(x => | ||
293 | { | ||
294 | try | ||
295 | { | ||
296 | req.DoHTTPGruntWork(m_server, | ||
297 | req.PollServiceArgs.NoEvents(req.RequestID, req.PollServiceArgs.Id)); | ||
298 | byContextDequeue(req); | ||
299 | } | ||
300 | catch (ObjectDisposedException) | ||
301 | { | ||
302 | // Ignore it, no need to reply | ||
303 | } | ||
304 | return null; | ||
305 | }, null); | ||
306 | } | ||
307 | else | ||
308 | { | ||
309 | ReQueueEvent(req); | ||
310 | } | ||
311 | } | 304 | } |
312 | } | 305 | } |
313 | catch (Exception e) | 306 | } |
314 | { | 307 | catch (Exception e) |
315 | m_log.ErrorFormat("Exception in poll service thread: " + e.ToString()); | 308 | { |
316 | } | 309 | m_log.ErrorFormat("Exception in poll service thread: " + e.ToString()); |
317 | } | 310 | } |
318 | } | 311 | } |
319 | } | 312 | } |
320 | |||
321 | } | 313 | } |
322 | } | 314 | } |
diff --git a/OpenSim/Framework/Servers/HttpServer/RestStreamHandler.cs b/OpenSim/Framework/Servers/HttpServer/RestStreamHandler.cs index 0305dee..dfc2715 100644 --- a/OpenSim/Framework/Servers/HttpServer/RestStreamHandler.cs +++ b/OpenSim/Framework/Servers/HttpServer/RestStreamHandler.cs | |||
@@ -50,11 +50,10 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
50 | 50 | ||
51 | protected override byte[] ProcessRequest(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) | 51 | protected override byte[] ProcessRequest(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) |
52 | { | 52 | { |
53 | string requestBody; | ||
53 | Encoding encoding = Encoding.UTF8; | 54 | Encoding encoding = Encoding.UTF8; |
54 | StreamReader streamReader = new StreamReader(request, encoding); | 55 | using(StreamReader streamReader = new StreamReader(request,encoding)) |
55 | 56 | requestBody = streamReader.ReadToEnd(); | |
56 | string requestBody = streamReader.ReadToEnd(); | ||
57 | streamReader.Close(); | ||
58 | 57 | ||
59 | string param = GetParam(path); | 58 | string param = GetParam(path); |
60 | string responseString = m_restMethod(requestBody, path, param, httpRequest, httpResponse); | 59 | string responseString = m_restMethod(requestBody, path, param, httpRequest, httpResponse); |
diff --git a/OpenSim/Framework/Servers/MainServer.cs b/OpenSim/Framework/Servers/MainServer.cs index ea7b2b5..523ccba 100644 --- a/OpenSim/Framework/Servers/MainServer.cs +++ b/OpenSim/Framework/Servers/MainServer.cs | |||
@@ -42,6 +42,7 @@ namespace OpenSim.Framework.Servers | |||
42 | // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 42 | // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
43 | 43 | ||
44 | private static BaseHttpServer instance = null; | 44 | private static BaseHttpServer instance = null; |
45 | private static BaseHttpServer unsecureinstance = null; | ||
45 | private static Dictionary<uint, BaseHttpServer> m_Servers = new Dictionary<uint, BaseHttpServer>(); | 46 | private static Dictionary<uint, BaseHttpServer> m_Servers = new Dictionary<uint, BaseHttpServer>(); |
46 | 47 | ||
47 | /// <summary> | 48 | /// <summary> |
@@ -93,6 +94,21 @@ namespace OpenSim.Framework.Servers | |||
93 | } | 94 | } |
94 | } | 95 | } |
95 | 96 | ||
97 | |||
98 | public static BaseHttpServer UnSecureInstance | ||
99 | { | ||
100 | get { return unsecureinstance; } | ||
101 | |||
102 | set | ||
103 | { | ||
104 | lock (m_Servers) | ||
105 | if (!m_Servers.ContainsValue(value)) | ||
106 | throw new Exception("HTTP server must already have been registered to be set as the main instance"); | ||
107 | |||
108 | unsecureinstance = value; | ||
109 | } | ||
110 | } | ||
111 | |||
96 | /// <summary> | 112 | /// <summary> |
97 | /// Get all the registered servers. | 113 | /// Get all the registered servers. |
98 | /// </summary> | 114 | /// </summary> |
@@ -353,5 +369,17 @@ namespace OpenSim.Framework.Servers | |||
353 | return m_Servers[port]; | 369 | return m_Servers[port]; |
354 | } | 370 | } |
355 | } | 371 | } |
372 | |||
373 | public static void Stop() | ||
374 | { | ||
375 | lock (m_Servers) | ||
376 | { | ||
377 | foreach (BaseHttpServer httpServer in m_Servers.Values) | ||
378 | { | ||
379 | httpServer.Stop(); | ||
380 | } | ||
381 | } | ||
382 | } | ||
383 | |||
356 | } | 384 | } |
357 | } \ No newline at end of file | 385 | } \ No newline at end of file |
diff --git a/OpenSim/Framework/Servers/ServerBase.cs b/OpenSim/Framework/Servers/ServerBase.cs index f627ae6..3c2dce8 100644 --- a/OpenSim/Framework/Servers/ServerBase.cs +++ b/OpenSim/Framework/Servers/ServerBase.cs | |||
@@ -275,18 +275,6 @@ namespace OpenSim.Framework.Servers | |||
275 | (string module, string[] args) => Notice(GetThreadsReport())); | 275 | (string module, string[] args) => Notice(GetThreadsReport())); |
276 | 276 | ||
277 | m_console.Commands.AddCommand ( | 277 | m_console.Commands.AddCommand ( |
278 | "Debug", false, "debug comms set", | ||
279 | "debug comms set serialosdreq true|false", | ||
280 | "Set comms parameters. For debug purposes.", | ||
281 | HandleDebugCommsSet); | ||
282 | |||
283 | m_console.Commands.AddCommand ( | ||
284 | "Debug", false, "debug comms status", | ||
285 | "debug comms status", | ||
286 | "Show current debug comms parameters.", | ||
287 | HandleDebugCommsStatus); | ||
288 | |||
289 | m_console.Commands.AddCommand ( | ||
290 | "Debug", false, "debug threadpool set", | 278 | "Debug", false, "debug threadpool set", |
291 | "debug threadpool set worker|iocp min|max <n>", | 279 | "debug threadpool set worker|iocp min|max <n>", |
292 | "Set threadpool parameters. For debug purposes.", | 280 | "Set threadpool parameters. For debug purposes.", |
@@ -343,47 +331,13 @@ namespace OpenSim.Framework.Servers | |||
343 | 331 | ||
344 | public void RegisterCommonComponents(IConfigSource configSource) | 332 | public void RegisterCommonComponents(IConfigSource configSource) |
345 | { | 333 | { |
346 | IConfig networkConfig = configSource.Configs["Network"]; | 334 | // IConfig networkConfig = configSource.Configs["Network"]; |
347 | |||
348 | if (networkConfig != null) | ||
349 | { | ||
350 | WebUtil.SerializeOSDRequestsPerEndpoint = networkConfig.GetBoolean("SerializeOSDRequests", false); | ||
351 | } | ||
352 | 335 | ||
353 | m_serverStatsCollector = new ServerStatsCollector(); | 336 | m_serverStatsCollector = new ServerStatsCollector(); |
354 | m_serverStatsCollector.Initialise(configSource); | 337 | m_serverStatsCollector.Initialise(configSource); |
355 | m_serverStatsCollector.Start(); | 338 | m_serverStatsCollector.Start(); |
356 | } | 339 | } |
357 | 340 | ||
358 | private void HandleDebugCommsStatus(string module, string[] args) | ||
359 | { | ||
360 | Notice("serialosdreq is {0}", WebUtil.SerializeOSDRequestsPerEndpoint); | ||
361 | } | ||
362 | |||
363 | private void HandleDebugCommsSet(string module, string[] args) | ||
364 | { | ||
365 | if (args.Length != 5) | ||
366 | { | ||
367 | Notice("Usage: debug comms set serialosdreq true|false"); | ||
368 | return; | ||
369 | } | ||
370 | |||
371 | if (args[3] != "serialosdreq") | ||
372 | { | ||
373 | Notice("Usage: debug comms set serialosdreq true|false"); | ||
374 | return; | ||
375 | } | ||
376 | |||
377 | bool setSerializeOsdRequests; | ||
378 | |||
379 | if (!ConsoleUtil.TryParseConsoleBool(m_console, args[4], out setSerializeOsdRequests)) | ||
380 | return; | ||
381 | |||
382 | WebUtil.SerializeOSDRequestsPerEndpoint = setSerializeOsdRequests; | ||
383 | |||
384 | Notice("serialosdreq is now {0}", setSerializeOsdRequests); | ||
385 | } | ||
386 | |||
387 | private void HandleShowThreadpoolCallsActive(string module, string[] args) | 341 | private void HandleShowThreadpoolCallsActive(string module, string[] args) |
388 | { | 342 | { |
389 | List<KeyValuePair<string, int>> calls = Util.GetFireAndForgetCallsInProgress().ToList(); | 343 | List<KeyValuePair<string, int>> calls = Util.GetFireAndForgetCallsInProgress().ToList(); |
@@ -928,16 +882,12 @@ namespace OpenSim.Framework.Servers | |||
928 | sb.Append("\n"); | 882 | sb.Append("\n"); |
929 | } | 883 | } |
930 | 884 | ||
931 | sb.Append("\n"); | 885 | sb.Append(GetThreadPoolReport()); |
932 | 886 | ||
933 | // For some reason mono 2.6.7 returns an empty threads set! Not going to confuse people by reporting | 887 | sb.Append("\n"); |
934 | // zero active threads. | ||
935 | int totalThreads = Process.GetCurrentProcess().Threads.Count; | 888 | int totalThreads = Process.GetCurrentProcess().Threads.Count; |
936 | if (totalThreads > 0) | 889 | if (totalThreads > 0) |
937 | sb.AppendFormat("Total threads active: {0}\n\n", totalThreads); | 890 | sb.AppendFormat("Total process threads active: {0}\n\n", totalThreads); |
938 | |||
939 | sb.Append("Main threadpool (excluding script engine pools)\n"); | ||
940 | sb.Append(GetThreadPoolReport()); | ||
941 | 891 | ||
942 | return sb.ToString(); | 892 | return sb.ToString(); |
943 | } | 893 | } |
@@ -948,15 +898,46 @@ namespace OpenSim.Framework.Servers | |||
948 | /// <returns></returns> | 898 | /// <returns></returns> |
949 | public static string GetThreadPoolReport() | 899 | public static string GetThreadPoolReport() |
950 | { | 900 | { |
901 | |||
902 | StringBuilder sb = new StringBuilder(); | ||
903 | |||
904 | // framework pool is alwasy active | ||
905 | int maxWorkers; | ||
906 | int minWorkers; | ||
907 | int curWorkers; | ||
908 | int maxComp; | ||
909 | int minComp; | ||
910 | int curComp; | ||
911 | |||
912 | try | ||
913 | { | ||
914 | ThreadPool.GetMaxThreads(out maxWorkers, out maxComp); | ||
915 | ThreadPool.GetMinThreads(out minWorkers, out minComp); | ||
916 | ThreadPool.GetAvailableThreads(out curWorkers, out curComp); | ||
917 | curWorkers = maxWorkers - curWorkers; | ||
918 | curComp = maxComp - curComp; | ||
919 | |||
920 | sb.Append("\nFramework main threadpool \n"); | ||
921 | sb.AppendFormat("workers: {0} ({1} / {2})\n", curWorkers, maxWorkers, minWorkers); | ||
922 | sb.AppendFormat("Completion: {0} ({1} / {2})\n", curComp, maxComp, minComp); | ||
923 | } | ||
924 | catch { } | ||
925 | |||
926 | if ( | ||
927 | Util.FireAndForgetMethod == FireAndForgetMethod.QueueUserWorkItem | ||
928 | || Util.FireAndForgetMethod == FireAndForgetMethod.UnsafeQueueUserWorkItem) | ||
929 | { | ||
930 | sb.AppendFormat("\nThread pool used: Framework main threadpool\n"); | ||
931 | return sb.ToString(); | ||
932 | } | ||
933 | |||
951 | string threadPoolUsed = null; | 934 | string threadPoolUsed = null; |
952 | int maxThreads = 0; | 935 | int maxThreads = 0; |
953 | int minThreads = 0; | 936 | int minThreads = 0; |
954 | int allocatedThreads = 0; | 937 | int allocatedThreads = 0; |
955 | int inUseThreads = 0; | 938 | int inUseThreads = 0; |
956 | int waitingCallbacks = 0; | 939 | int waitingCallbacks = 0; |
957 | int completionPortThreads = 0; | ||
958 | 940 | ||
959 | StringBuilder sb = new StringBuilder(); | ||
960 | if (Util.FireAndForgetMethod == FireAndForgetMethod.SmartThreadPool) | 941 | if (Util.FireAndForgetMethod == FireAndForgetMethod.SmartThreadPool) |
961 | { | 942 | { |
962 | STPInfo stpi = Util.GetSmartThreadPoolInfo(); | 943 | STPInfo stpi = Util.GetSmartThreadPoolInfo(); |
@@ -972,22 +953,10 @@ namespace OpenSim.Framework.Servers | |||
972 | waitingCallbacks = stpi.WaitingCallbacks; | 953 | waitingCallbacks = stpi.WaitingCallbacks; |
973 | } | 954 | } |
974 | } | 955 | } |
975 | else if ( | 956 | |
976 | Util.FireAndForgetMethod == FireAndForgetMethod.QueueUserWorkItem | ||
977 | || Util.FireAndForgetMethod == FireAndForgetMethod.UnsafeQueueUserWorkItem) | ||
978 | { | ||
979 | threadPoolUsed = "BuiltInThreadPool"; | ||
980 | ThreadPool.GetMaxThreads(out maxThreads, out completionPortThreads); | ||
981 | ThreadPool.GetMinThreads(out minThreads, out completionPortThreads); | ||
982 | int availableThreads; | ||
983 | ThreadPool.GetAvailableThreads(out availableThreads, out completionPortThreads); | ||
984 | inUseThreads = maxThreads - availableThreads; | ||
985 | allocatedThreads = -1; | ||
986 | waitingCallbacks = -1; | ||
987 | } | ||
988 | |||
989 | if (threadPoolUsed != null) | 957 | if (threadPoolUsed != null) |
990 | { | 958 | { |
959 | sb.Append("\nThreadpool (excluding script engine pools)\n"); | ||
991 | sb.AppendFormat("Thread pool used : {0}\n", threadPoolUsed); | 960 | sb.AppendFormat("Thread pool used : {0}\n", threadPoolUsed); |
992 | sb.AppendFormat("Max threads : {0}\n", maxThreads); | 961 | sb.AppendFormat("Max threads : {0}\n", maxThreads); |
993 | sb.AppendFormat("Min threads : {0}\n", minThreads); | 962 | sb.AppendFormat("Min threads : {0}\n", minThreads); |
diff --git a/OpenSim/Framework/Servers/Tests/VersionInfoTests.cs b/OpenSim/Framework/Servers/Tests/VersionInfoTests.cs index 480f2bb..68a1c78 100644 --- a/OpenSim/Framework/Servers/Tests/VersionInfoTests.cs +++ b/OpenSim/Framework/Servers/Tests/VersionInfoTests.cs | |||
@@ -41,14 +41,5 @@ namespace OpenSim.Framework.Servers.Tests | |||
41 | { | 41 | { |
42 | Assert.AreEqual(VersionInfo.VERSIONINFO_VERSION_LENGTH, VersionInfo.Version.Length," VersionInfo.Version string not " + VersionInfo.VERSIONINFO_VERSION_LENGTH + " chars."); | 42 | Assert.AreEqual(VersionInfo.VERSIONINFO_VERSION_LENGTH, VersionInfo.Version.Length," VersionInfo.Version string not " + VersionInfo.VERSIONINFO_VERSION_LENGTH + " chars."); |
43 | } | 43 | } |
44 | |||
45 | [Test] | ||
46 | public void TestGetVersionStringLength() | ||
47 | { | ||
48 | foreach (VersionInfo.Flavour flavour in Enum.GetValues(typeof(VersionInfo.Flavour))) | ||
49 | { | ||
50 | Assert.AreEqual(VersionInfo.VERSIONINFO_VERSION_LENGTH, VersionInfo.GetVersionString("0.0.0", flavour).Length, "0.0.0/" + flavour + " failed"); | ||
51 | } | ||
52 | } | ||
53 | } | 44 | } |
54 | } | 45 | } |