aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Framework
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Framework/Console/RemoteConsole.cs2
-rw-r--r--OpenSim/Framework/NetworkServersInfo.cs4
-rw-r--r--OpenSim/Framework/Servers/BaseOpenSimServer.cs28
-rw-r--r--OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs261
-rw-r--r--OpenSim/Framework/Servers/HttpServer/Interfaces/IOSHttpResponse.cs2
-rw-r--r--OpenSim/Framework/Servers/HttpServer/OSHttpResponse.cs4
-rw-r--r--OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs5
-rw-r--r--OpenSim/Framework/Servers/HttpServer/PollServiceHttpRequest.cs17
-rw-r--r--OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs95
-rw-r--r--OpenSim/Framework/Servers/MainServer.cs16
10 files changed, 327 insertions, 107 deletions
diff --git a/OpenSim/Framework/Console/RemoteConsole.cs b/OpenSim/Framework/Console/RemoteConsole.cs
index f59c902..ddd9578 100644
--- a/OpenSim/Framework/Console/RemoteConsole.cs
+++ b/OpenSim/Framework/Console/RemoteConsole.cs
@@ -403,7 +403,7 @@ namespace OpenSim.Framework.Console
403 string uri = "/ReadResponses/" + sessionID.ToString() + "/"; 403 string uri = "/ReadResponses/" + sessionID.ToString() + "/";
404 404
405 m_Server.AddPollServiceHTTPHandler( 405 m_Server.AddPollServiceHTTPHandler(
406 uri, new PollServiceEventArgs(null, uri, HasEvents, GetEvents, NoEvents, sessionID,25000)); // 25 secs timeout 406 uri, new PollServiceEventArgs(null, uri, HasEvents, GetEvents, NoEvents, null, sessionID,25000)); // 25 secs timeout
407 407
408 // Our reply is an XML document. 408 // Our reply is an XML document.
409 // TODO: Change this to Linq.Xml 409 // TODO: Change this to Linq.Xml
diff --git a/OpenSim/Framework/NetworkServersInfo.cs b/OpenSim/Framework/NetworkServersInfo.cs
index dfe9695..d79eb0d 100644
--- a/OpenSim/Framework/NetworkServersInfo.cs
+++ b/OpenSim/Framework/NetworkServersInfo.cs
@@ -37,6 +37,8 @@ namespace OpenSim.Framework
37 public bool isSandbox; 37 public bool isSandbox;
38 public bool HttpUsesSSL = false; 38 public bool HttpUsesSSL = false;
39 public string HttpSSLCN = ""; 39 public string HttpSSLCN = "";
40 public string HttpSSLCertPath = "";
41 public string HttpSSLCNCertPass = "";
40 public uint httpSSLPort = 9001; 42 public uint httpSSLPort = 9001;
41 43
42 // "Out of band" managemnt https 44 // "Out of band" managemnt https
@@ -62,6 +64,8 @@ namespace OpenSim.Framework
62 (uint)config.Configs["Network"].GetInt("http_listener_sslport", ((int)ConfigSettings.DefaultRegionHttpPort+1)); 64 (uint)config.Configs["Network"].GetInt("http_listener_sslport", ((int)ConfigSettings.DefaultRegionHttpPort+1));
63 HttpUsesSSL = config.Configs["Network"].GetBoolean("http_listener_ssl", false); 65 HttpUsesSSL = config.Configs["Network"].GetBoolean("http_listener_ssl", false);
64 HttpSSLCN = config.Configs["Network"].GetString("http_listener_cn", "localhost"); 66 HttpSSLCN = config.Configs["Network"].GetString("http_listener_cn", "localhost");
67 HttpSSLCertPath = config.Configs["Network"].GetString("http_listener_cert_path", HttpSSLCertPath);
68 HttpSSLCNCertPass = config.Configs["Network"].GetString("http_listener_cert_pass", HttpSSLCNCertPass);
65 69
66 // "Out of band management https" 70 // "Out of band management https"
67 ssl_listener = config.Configs["Network"].GetBoolean("https_listener",false); 71 ssl_listener = config.Configs["Network"].GetBoolean("https_listener",false);
diff --git a/OpenSim/Framework/Servers/BaseOpenSimServer.cs b/OpenSim/Framework/Servers/BaseOpenSimServer.cs
index f761813..5111673 100644
--- a/OpenSim/Framework/Servers/BaseOpenSimServer.cs
+++ b/OpenSim/Framework/Servers/BaseOpenSimServer.cs
@@ -33,6 +33,9 @@ using System.Text;
33using System.Text.RegularExpressions; 33using System.Text.RegularExpressions;
34using System.Threading; 34using System.Threading;
35using System.Timers; 35using System.Timers;
36using System.Net;
37using System.Net.Security;
38using System.Security.Cryptography.X509Certificates;
36using log4net; 39using log4net;
37using log4net.Appender; 40using log4net.Appender;
38using log4net.Core; 41using 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);
diff --git a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
index fb92b92..516604a 100644
--- a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
+++ b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
@@ -32,6 +32,7 @@ using System.Collections.Specialized;
32using System.IO; 32using System.IO;
33using System.Net; 33using System.Net;
34using System.Net.Sockets; 34using System.Net.Sockets;
35using System.Net.Security;
35using System.Security.Cryptography.X509Certificates; 36using System.Security.Cryptography.X509Certificates;
36using System.Reflection; 37using System.Reflection;
37using System.Globalization; 38using System.Globalization;
@@ -43,10 +44,11 @@ using log4net;
43using Nwc.XmlRpc; 44using Nwc.XmlRpc;
44using OpenMetaverse.StructuredData; 45using OpenMetaverse.StructuredData;
45using CoolHTTPListener = HttpServer.HttpListener; 46using CoolHTTPListener = HttpServer.HttpListener;
46using HttpListener=System.Net.HttpListener; 47using HttpListener = System.Net.HttpListener;
47using LogPrio=HttpServer.LogPrio; 48using LogPrio = HttpServer.LogPrio;
48using OpenSim.Framework.Monitoring; 49using OpenSim.Framework.Monitoring;
49using System.IO.Compression; 50using System.IO.Compression;
51using System.Security.Cryptography;
50 52
51namespace OpenSim.Framework.Servers.HttpServer 53namespace 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,151 @@ 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 }
184 }
185 m_certCN = m_cert.GetNameInfo(X509NameType.SimpleName, false);
186 }
187 catch
188 {
189 throw new Exception("SSL cert load error");
190 }
154 } 191 }
155 192
156 public BaseHttpServer(uint port, bool ssl, uint sslport, string CN) : this (port, ssl) 193 public BaseHttpServer(uint port, bool ssl, string CN, string CPath, string CPass)
157 { 194 {
158 if (m_ssl) 195 m_port = port;
196 if (ssl)
159 { 197 {
160 m_sslport = sslport; 198 if(string.IsNullOrEmpty(CPath))
199 throw new Exception("invalid main http server cert path");
200
201 if(Uri.CheckHostName(CN) == UriHostNameType.Unknown)
202 throw new Exception("invalid main http server CN (ExternalHostName)");
203
204 m_certNames.Clear();
205 m_certIPs.Clear();
206 m_certCN= "";
207
208 m_ssl = true;
209 load_cert(CPath, CPass);
210
211 if(!CheckSSLCertHost(CN))
212 throw new Exception("invalid main http server CN (ExternalHostName)");
213
214 m_SSLCommonName = CN;
215
216 if(m_cert.Issuer == m_cert.Subject )
217 m_log.Warn("Self signed certificate. Clients need to allow this (some viewers debug option NoVerifySSLcert must be set to true");
161 } 218 }
219 else
220 m_ssl = false;
162 } 221 }
163 222
164 public BaseHttpServer(uint port, bool ssl, string CPath, string CPass) : this (port, ssl) 223 public BaseHttpServer(uint port, bool ssl, string CPath, string CPass)
165 { 224 {
166 if (m_ssl) 225 m_port = port;
226 if (ssl)
167 { 227 {
168 m_cert = new X509Certificate2(CPath, CPass); 228 load_cert(CPath, CPass);
229 if(m_cert.Issuer == m_cert.Subject )
230 m_log.Warn("Self signed certificate. Http clients need to allow this");
231 m_ssl = true;
232 }
233 else
234 m_ssl = false;
235 }
236
237 static bool MatchDNS (string hostname, string dns)
238 {
239 int indx = dns.IndexOf ('*');
240 if (indx == -1)
241 return (String.Compare(hostname, dns, true, CultureInfo.InvariantCulture) == 0);
242
243 int dnslen = dns.Length;
244 dnslen--;
245 if(indx == dnslen)
246 return true; // just * ?
247
248 if(indx > dnslen - 2)
249 return false; // 2 short ?
250
251 if (dns[indx + 1] != '.')
252 return false;
253
254 int indx2 = dns.IndexOf ('*', indx + 1);
255 if (indx2 != -1)
256 return false; // there can only be one;
257
258 string end = dns.Substring(indx + 1);
259 int hostlen = hostname.Length;
260 int endlen = end.Length;
261 int length = hostlen - endlen;
262 if (length <= 0)
263 return false;
264
265 if (String.Compare(hostname, length, end, 0, endlen, true, CultureInfo.InvariantCulture) != 0)
266 return false;
267
268 if (indx == 0)
269 {
270 indx2 = hostname.IndexOf ('.');
271 return ((indx2 == -1) || (indx2 >= length));
272 }
273
274 string start = dns.Substring (0, indx);
275 return (String.Compare (hostname, 0, start, 0, start.Length, true, CultureInfo.InvariantCulture) == 0);
276 }
277
278 public bool CheckSSLCertHost(string hostname)
279 {
280 UriHostNameType htype = Uri.CheckHostName(hostname);
281
282 if(htype == UriHostNameType.Unknown || htype == UriHostNameType.Basic)
283 return false;
284 if(htype == UriHostNameType.Dns)
285 {
286 foreach(string name in m_certNames)
287 {
288 if(MatchDNS(hostname, name))
289 return true;
290 }
291 if(MatchDNS(hostname, m_certCN))
292 return true;
293 }
294 else
295 {
296 foreach(string ip in m_certIPs)
297 {
298 if (String.Compare(hostname, ip, true, CultureInfo.InvariantCulture) != 0)
299 return true;
300 }
169 } 301 }
170 }
171 302
303 return false;
304 }
172 /// <summary> 305 /// <summary>
173 /// Add a stream handler to the http server. If the handler already exists, then nothing happens. 306 /// Add a stream handler to the http server. If the handler already exists, then nothing happens.
174 /// </summary> 307 /// </summary>
@@ -396,14 +529,10 @@ namespace OpenSim.Framework.Servers.HttpServer
396 if (psEvArgs.Request != null) 529 if (psEvArgs.Request != null)
397 { 530 {
398 OSHttpRequest req = new OSHttpRequest(context, request); 531 OSHttpRequest req = new OSHttpRequest(context, request);
399 532 string requestBody = String.Empty;
400 Stream requestStream = req.InputStream;
401
402 Encoding encoding = Encoding.UTF8; 533 Encoding encoding = Encoding.UTF8;
403 StreamReader reader = new StreamReader(requestStream, encoding); 534 using(StreamReader reader = new StreamReader(req.InputStream, encoding))
404 535 requestBody = reader.ReadToEnd();
405 string requestBody = reader.ReadToEnd();
406 reader.Close();
407 536
408 Hashtable keysvals = new Hashtable(); 537 Hashtable keysvals = new Hashtable();
409 Hashtable headervals = new Hashtable(); 538 Hashtable headervals = new Hashtable();
@@ -461,7 +590,7 @@ namespace OpenSim.Framework.Servers.HttpServer
461 } 590 }
462 591
463 OSHttpResponse resp = new OSHttpResponse(new HttpResponse(context, request),context); 592 OSHttpResponse resp = new OSHttpResponse(new HttpResponse(context, request),context);
464 resp.ReuseContext = true; 593// resp.ReuseContext = true;
465// resp.ReuseContext = false; 594// resp.ReuseContext = false;
466 HandleRequest(req, resp); 595 HandleRequest(req, resp);
467 596
@@ -497,6 +626,8 @@ namespace OpenSim.Framework.Servers.HttpServer
497 byte[] buffer500 = SendHTML500(response); 626 byte[] buffer500 = SendHTML500(response);
498 response.OutputStream.Write(buffer500, 0, buffer500.Length); 627 response.OutputStream.Write(buffer500, 0, buffer500.Length);
499 response.Send(); 628 response.Send();
629 if(request.InputStream.CanRead)
630 request.InputStream.Close();
500 } 631 }
501 catch 632 catch
502 { 633 {
@@ -541,7 +672,6 @@ namespace OpenSim.Framework.Servers.HttpServer
541// } 672// }
542// } 673// }
543 674
544 //response.KeepAlive = true;
545 response.SendChunked = false; 675 response.SendChunked = false;
546 676
547 string path = request.RawUrl; 677 string path = request.RawUrl;
@@ -565,15 +695,10 @@ namespace OpenSim.Framework.Servers.HttpServer
565 { 695 {
566 //m_log.Debug("[BASE HTTP SERVER]: Found Caps based HTTP Handler"); 696 //m_log.Debug("[BASE HTTP SERVER]: Found Caps based HTTP Handler");
567 IGenericHTTPHandler HTTPRequestHandler = requestHandler as IGenericHTTPHandler; 697 IGenericHTTPHandler HTTPRequestHandler = requestHandler as IGenericHTTPHandler;
568 Stream requestStream = request.InputStream; 698 string requestBody = String.Empty;
569
570 Encoding encoding = Encoding.UTF8; 699 Encoding encoding = Encoding.UTF8;
571 StreamReader reader = new StreamReader(requestStream, encoding); 700 using(StreamReader reader = new StreamReader(request.InputStream, encoding))
572 701 requestBody = reader.ReadToEnd();
573 string requestBody = reader.ReadToEnd();
574
575 reader.Close();
576 //requestStream.Close();
577 702
578 Hashtable keysvals = new Hashtable(); 703 Hashtable keysvals = new Hashtable();
579 Hashtable headervals = new Hashtable(); 704 Hashtable headervals = new Hashtable();
@@ -613,7 +738,6 @@ namespace OpenSim.Framework.Servers.HttpServer
613 else 738 else
614 { 739 {
615 IStreamHandler streamHandler = (IStreamHandler)requestHandler; 740 IStreamHandler streamHandler = (IStreamHandler)requestHandler;
616
617 using (MemoryStream memoryStream = new MemoryStream()) 741 using (MemoryStream memoryStream = new MemoryStream())
618 { 742 {
619 streamHandler.Handle(path, request.InputStream, memoryStream, request, response); 743 streamHandler.Handle(path, request.InputStream, memoryStream, request, response);
@@ -690,8 +814,6 @@ namespace OpenSim.Framework.Servers.HttpServer
690 } 814 }
691 } 815 }
692 816
693 request.InputStream.Close();
694
695 if (buffer != null) 817 if (buffer != null)
696 { 818 {
697 if (WebUtil.DebugLevel >= 5) 819 if (WebUtil.DebugLevel >= 5)
@@ -723,10 +845,6 @@ namespace OpenSim.Framework.Servers.HttpServer
723 requestEndTick = Environment.TickCount; 845 requestEndTick = Environment.TickCount;
724 846
725 response.Send(); 847 response.Send();
726
727 //response.OutputStream.Close();
728
729 //response.FreeContext();
730 } 848 }
731 catch (SocketException e) 849 catch (SocketException e)
732 { 850 {
@@ -758,6 +876,9 @@ namespace OpenSim.Framework.Servers.HttpServer
758 } 876 }
759 finally 877 finally
760 { 878 {
879 if(request.InputStream.CanRead)
880 request.InputStream.Close();
881
761 // Every month or so this will wrap and give bad numbers, not really a problem 882 // Every month or so this will wrap and give bad numbers, not really a problem
762 // since its just for reporting 883 // since its just for reporting
763 int tickdiff = requestEndTick - requestStartTick; 884 int tickdiff = requestEndTick - requestStartTick;
@@ -1015,9 +1136,10 @@ namespace OpenSim.Framework.Servers.HttpServer
1015 } 1136 }
1016 finally 1137 finally
1017 { 1138 {
1018 if (innerStream != null) 1139 if (innerStream != null && innerStream.CanRead)
1019 innerStream.Dispose(); 1140 innerStream.Dispose();
1020 requestStream.Dispose(); 1141 if (requestStream.CanRead)
1142 requestStream.Dispose();
1021 } 1143 }
1022 1144
1023 //m_log.Debug(requestBody); 1145 //m_log.Debug(requestBody);
@@ -1098,6 +1220,17 @@ namespace OpenSim.Framework.Servers.HttpServer
1098 1220
1099 if (gridproxy) 1221 if (gridproxy)
1100 xmlRprcRequest.Params.Add("gridproxy"); // Param[4] 1222 xmlRprcRequest.Params.Add("gridproxy"); // Param[4]
1223
1224 // reserve this for
1225 // ... by Fumi.Iseki for DTLNSLMoneyServer
1226 // BUT make its presence possible to detect/parse
1227 string rcn = request.IHttpClientContext.SSLCommonName;
1228 if(!string.IsNullOrWhiteSpace(rcn))
1229 {
1230 rcn = "SSLCN:" + rcn;
1231 xmlRprcRequest.Params.Add(rcn); // Param[4] or Param[5]
1232 }
1233
1101 try 1234 try
1102 { 1235 {
1103 xmlRpcResponse = method(xmlRprcRequest, request.RemoteIPEndPoint); 1236 xmlRpcResponse = method(xmlRprcRequest, request.RemoteIPEndPoint);
@@ -1263,15 +1396,15 @@ namespace OpenSim.Framework.Servers.HttpServer
1263 //m_log.Warn("[BASE HTTP SERVER]: We've figured out it's a LLSD Request"); 1396 //m_log.Warn("[BASE HTTP SERVER]: We've figured out it's a LLSD Request");
1264 Stream requestStream = request.InputStream; 1397 Stream requestStream = request.InputStream;
1265 1398
1399 string requestBody = string.Empty;
1266 Encoding encoding = Encoding.UTF8; 1400 Encoding encoding = Encoding.UTF8;
1267 StreamReader reader = new StreamReader(requestStream, encoding); 1401 using(StreamReader reader = new StreamReader(requestStream,encoding))
1402 requestBody = reader.ReadToEnd();
1268 1403
1269 string requestBody = reader.ReadToEnd(); 1404 if(requestStream.CanRead)
1270 reader.Close(); 1405 requestStream.Close();
1271 requestStream.Close();
1272 1406
1273 //m_log.DebugFormat("[OGP]: {0}:{1}", request.RawUrl, requestBody); 1407 //m_log.DebugFormat("[OGP]: {0}:{1}", request.RawUrl, requestBody);
1274 response.KeepAlive = true;
1275 1408
1276 OSD llsdRequest = null; 1409 OSD llsdRequest = null;
1277 OSD llsdResponse = null; 1410 OSD llsdResponse = null;
@@ -1592,15 +1725,12 @@ namespace OpenSim.Framework.Servers.HttpServer
1592 byte[] buffer; 1725 byte[] buffer;
1593 1726
1594 Stream requestStream = request.InputStream; 1727 Stream requestStream = request.InputStream;
1595 1728 string requestBody = string.Empty;
1596 Encoding encoding = Encoding.UTF8; 1729 Encoding encoding = Encoding.UTF8;
1597 StreamReader reader = new StreamReader(requestStream, encoding); 1730 using(StreamReader reader = new StreamReader(requestStream,encoding))
1598 1731 requestBody = reader.ReadToEnd();
1599 string requestBody = reader.ReadToEnd(); 1732 if(requestStream.CanRead)
1600 // avoid warning for now 1733 requestStream.Close();
1601 reader.ReadToEnd();
1602 reader.Close();
1603 requestStream.Close();
1604 1734
1605 Hashtable keysvals = new Hashtable(); 1735 Hashtable keysvals = new Hashtable();
1606 Hashtable headervals = new Hashtable(); 1736 Hashtable headervals = new Hashtable();
@@ -1804,7 +1934,7 @@ namespace OpenSim.Framework.Servers.HttpServer
1804*/ 1934*/
1805 // disable this things 1935 // disable this things
1806 response.KeepAlive = false; 1936 response.KeepAlive = false;
1807 response.ReuseContext = false; 1937 // response.ReuseContext = false;
1808 1938
1809 // Cross-Origin Resource Sharing with simple requests 1939 // Cross-Origin Resource Sharing with simple requests
1810 if (responsedata.ContainsKey("access_control_allow_origin")) 1940 if (responsedata.ContainsKey("access_control_allow_origin"))
@@ -1906,7 +2036,7 @@ namespace OpenSim.Framework.Servers.HttpServer
1906 2036
1907 public void Start() 2037 public void Start()
1908 { 2038 {
1909 Start(true); 2039 Start(true,true);
1910 } 2040 }
1911 2041
1912 /// <summary> 2042 /// <summary>
@@ -1916,7 +2046,7 @@ namespace OpenSim.Framework.Servers.HttpServer
1916 /// If true then poll responses are performed asynchronsly. 2046 /// If true then poll responses are performed asynchronsly.
1917 /// Option exists to allow regression tests to perform processing synchronously. 2047 /// Option exists to allow regression tests to perform processing synchronously.
1918 /// </param> 2048 /// </param>
1919 public void Start(bool performPollResponsesAsync) 2049 public void Start(bool performPollResponsesAsync, bool runPool)
1920 { 2050 {
1921 m_log.InfoFormat( 2051 m_log.InfoFormat(
1922 "[BASE HTTP SERVER]: Starting {0} server on port {1}", UseSSL ? "HTTPS" : "HTTP", Port); 2052 "[BASE HTTP SERVER]: Starting {0} server on port {1}", UseSSL ? "HTTPS" : "HTTP", Port);
@@ -1945,6 +2075,8 @@ namespace OpenSim.Framework.Servers.HttpServer
1945 //m_httpListener.Prefixes.Add("https://+:" + (m_sslport) + "/"); 2075 //m_httpListener.Prefixes.Add("https://+:" + (m_sslport) + "/");
1946 //m_httpListener.Prefixes.Add("http://+:" + m_port + "/"); 2076 //m_httpListener.Prefixes.Add("http://+:" + m_port + "/");
1947 m_httpListener2 = CoolHTTPListener.Create(IPAddress.Any, (int)m_port, m_cert); 2077 m_httpListener2 = CoolHTTPListener.Create(IPAddress.Any, (int)m_port, m_cert);
2078 if(m_certificateValidationCallback != null)
2079 m_httpListener2.CertificateValidationCallback = m_certificateValidationCallback;
1948 m_httpListener2.ExceptionThrown += httpServerException; 2080 m_httpListener2.ExceptionThrown += httpServerException;
1949 m_httpListener2.LogWriter = httpserverlog; 2081 m_httpListener2.LogWriter = httpserverlog;
1950 } 2082 }
@@ -1954,9 +2086,11 @@ namespace OpenSim.Framework.Servers.HttpServer
1954 m_httpListener2.Start(64); 2086 m_httpListener2.Start(64);
1955 2087
1956 // Long Poll Service Manager with 3 worker threads a 25 second timeout for no events 2088 // Long Poll Service Manager with 3 worker threads a 25 second timeout for no events
1957 2089 if(runPool)
1958 PollServiceRequestManager = new PollServiceRequestManager(this, performPollResponsesAsync, 2, 25000); 2090 {
1959 PollServiceRequestManager.Start(); 2091 PollServiceRequestManager = new PollServiceRequestManager(this, performPollResponsesAsync, 2, 25000);
2092 PollServiceRequestManager.Start();
2093 }
1960 2094
1961 HTTPDRunning = true; 2095 HTTPDRunning = true;
1962 2096
@@ -1970,7 +2104,7 @@ namespace OpenSim.Framework.Servers.HttpServer
1970 catch (Exception e) 2104 catch (Exception e)
1971 { 2105 {
1972 m_log.Error("[BASE HTTP SERVER]: Error - " + e.Message); 2106 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 + "?"); 2107 m_log.Error("[BASE HTTP SERVER]: Tip: Do you have permission to listen on port " + m_port + "?");
1974 2108
1975 // We want this exception to halt the entire server since in current configurations we aren't too 2109 // We want this exception to halt the entire server since in current configurations we aren't too
1976 // useful without inbound HTTP. 2110 // useful without inbound HTTP.
@@ -2135,10 +2269,9 @@ namespace OpenSim.Framework.Servers.HttpServer
2135 string file = Path.Combine(".", "http_500.html"); 2269 string file = Path.Combine(".", "http_500.html");
2136 if (!File.Exists(file)) 2270 if (!File.Exists(file))
2137 return getDefaultHTTP500(); 2271 return getDefaultHTTP500();
2138 2272 string result = string.Empty;
2139 StreamReader sr = File.OpenText(file); 2273 using(StreamReader sr = File.OpenText(file))
2140 string result = sr.ReadToEnd(); 2274 result = sr.ReadToEnd();
2141 sr.Close();
2142 return result; 2275 return result;
2143 } 2276 }
2144 2277
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..8e1b545 100644
--- a/OpenSim/Framework/Servers/HttpServer/OSHttpResponse.cs
+++ b/OpenSim/Framework/Servers/HttpServer/OSHttpResponse.cs
@@ -256,7 +256,7 @@ namespace OpenSim.Framework.Servers.HttpServer
256 _httpResponse.Reason = value; 256 _httpResponse.Reason = value;
257 } 257 }
258 } 258 }
259 259/*
260 public bool ReuseContext 260 public bool ReuseContext
261 { 261 {
262 get 262 get
@@ -275,7 +275,7 @@ namespace OpenSim.Framework.Servers.HttpServer
275 } 275 }
276 } 276 }
277 } 277 }
278 278*/
279 protected IHttpResponse _httpResponse; 279 protected IHttpResponse _httpResponse;
280 private IHttpClientContext _httpClientContext; 280 private IHttpClientContext _httpClientContext;
281 281
diff --git a/OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs b/OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs
index 8ace7a9..a1bc27b 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,6 +45,7 @@ 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;
@@ -73,13 +75,14 @@ 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.LongPoll;
diff --git a/OpenSim/Framework/Servers/HttpServer/PollServiceHttpRequest.cs b/OpenSim/Framework/Servers/HttpServer/PollServiceHttpRequest.cs
index 0e4a941..6537f64 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)
@@ -85,7 +89,7 @@ namespace OpenSim.Framework.Servers.HttpServer
85 response.SendChunked = false; 89 response.SendChunked = false;
86 response.ContentLength64 = buffer.Length; 90 response.ContentLength64 = buffer.Length;
87 response.ContentEncoding = Encoding.UTF8; 91 response.ContentEncoding = Encoding.UTF8;
88 response.ReuseContext = false; 92// response.ReuseContext = false;
89 93
90 try 94 try
91 { 95 {
@@ -110,7 +114,7 @@ namespace OpenSim.Framework.Servers.HttpServer
110 response.SendChunked = false; 114 response.SendChunked = false;
111 response.ContentLength64 = 0; 115 response.ContentLength64 = 0;
112 response.ContentEncoding = Encoding.UTF8; 116 response.ContentEncoding = Encoding.UTF8;
113 response.ReuseContext = false; 117// response.ReuseContext = false;
114 response.KeepAlive = false; 118 response.KeepAlive = false;
115 response.SendChunked = false; 119 response.SendChunked = false;
116 response.StatusCode = 503; 120 response.StatusCode = 503;
@@ -132,8 +136,9 @@ namespace OpenSim.Framework.Servers.HttpServer
132 { 136 {
133 if (b1.contextHash != b2.contextHash) 137 if (b1.contextHash != b2.contextHash)
134 return false; 138 return false;
135 bool b = Object.ReferenceEquals(b1.HttpContext, b2.HttpContext); 139// bool b = Object.ReferenceEquals(b1.HttpContext, b2.HttpContext);
136 return b; 140// return b;
141 return true;
137 } 142 }
138 143
139 public int GetHashCode(PollServiceHttpRequest b2) 144 public int GetHashCode(PollServiceHttpRequest b2)
diff --git a/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs b/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs
index 936146d..82c7727 100644
--- a/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs
+++ b/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs
@@ -160,6 +160,19 @@ namespace OpenSim.Framework.Servers.HttpServer
160 } 160 }
161 } 161 }
162 162
163 public void DropByContext(PollServiceHttpRequest req)
164 {
165 Queue<PollServiceHttpRequest> ctxQeueue;
166 lock (m_bycontext)
167 {
168 if (m_bycontext.TryGetValue(req, out ctxQeueue))
169 {
170 ctxQeueue.Clear();
171 m_bycontext.Remove(req);
172 }
173 }
174 }
175
163 public void EnqueueInt(PollServiceHttpRequest req) 176 public void EnqueueInt(PollServiceHttpRequest req)
164 { 177 {
165 if (m_running) 178 if (m_running)
@@ -263,22 +276,61 @@ namespace OpenSim.Framework.Servers.HttpServer
263 PollServiceHttpRequest req = m_requests.Dequeue(5000); 276 PollServiceHttpRequest req = m_requests.Dequeue(5000);
264 277
265 Watchdog.UpdateThread(); 278 Watchdog.UpdateThread();
266 if (req != null) 279 if(req == null)
280 continue;
281
282 try
267 { 283 {
268 try 284 if(!req.HttpContext.CanSend())
269 { 285 {
270 if (req.PollServiceArgs.HasEvents(req.RequestID, req.PollServiceArgs.Id)) 286 req.PollServiceArgs.Drop(req.RequestID, req.PollServiceArgs.Id);
287 byContextDequeue(req);
288 continue;
289 }
290
291 if(req.HttpContext.IsSending())
292 {
293 if ((Environment.TickCount - req.RequestTime) > req.PollServiceArgs.TimeOutms)
271 { 294 {
272 Hashtable responsedata = req.PollServiceArgs.GetEvents(req.RequestID, req.PollServiceArgs.Id); 295 req.PollServiceArgs.Drop(req.RequestID, req.PollServiceArgs.Id);
296 byContextDequeue(req);
297 }
298 else
299 ReQueueEvent(req);
300 continue;
301 }
273 302
303 if (req.PollServiceArgs.HasEvents(req.RequestID, req.PollServiceArgs.Id))
304 {
305 Hashtable responsedata = req.PollServiceArgs.GetEvents(req.RequestID, req.PollServiceArgs.Id);
306
307 m_threadPool.QueueWorkItem(x =>
308 {
309 try
310 {
311 req.DoHTTPGruntWork(m_server, responsedata);
312 byContextDequeue(req);
313 }
314 catch (ObjectDisposedException) // Browser aborted before we could read body, server closed the stream
315 {
316 // Ignore it, no need to reply
317 }
318 return null;
319 }, null);
320 }
321 else
322 {
323 if ((Environment.TickCount - req.RequestTime) > req.PollServiceArgs.TimeOutms)
324 {
274 m_threadPool.QueueWorkItem(x => 325 m_threadPool.QueueWorkItem(x =>
275 { 326 {
276 try 327 try
277 { 328 {
278 req.DoHTTPGruntWork(m_server, responsedata); 329 req.DoHTTPGruntWork(m_server,
330 req.PollServiceArgs.NoEvents(req.RequestID, req.PollServiceArgs.Id));
279 byContextDequeue(req); 331 byContextDequeue(req);
280 } 332 }
281 catch (ObjectDisposedException) // Browser aborted before we could read body, server closed the stream 333 catch (ObjectDisposedException)
282 { 334 {
283 // Ignore it, no need to reply 335 // Ignore it, no need to reply
284 } 336 }
@@ -287,36 +339,15 @@ namespace OpenSim.Framework.Servers.HttpServer
287 } 339 }
288 else 340 else
289 { 341 {
290 if ((Environment.TickCount - req.RequestTime) > req.PollServiceArgs.TimeOutms) 342 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 } 343 }
312 } 344 }
313 catch (Exception e) 345 }
314 { 346 catch (Exception e)
315 m_log.ErrorFormat("Exception in poll service thread: " + e.ToString()); 347 {
316 } 348 m_log.ErrorFormat("Exception in poll service thread: " + e.ToString());
317 } 349 }
318 } 350 }
319 } 351 }
320
321 } 352 }
322} 353}
diff --git a/OpenSim/Framework/Servers/MainServer.cs b/OpenSim/Framework/Servers/MainServer.cs
index ea7b2b5..29308a9 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 ÚnSecureInstance
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>