aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Framework/Servers
diff options
context:
space:
mode:
authoronefang2019-05-19 21:24:15 +1000
committeronefang2019-05-19 21:24:15 +1000
commit5e4d6cab00cb29cd088ab7b62ab13aff103b64cb (patch)
treea9fbc62df9eb2d1d9ba2698d8552eae71eca20d8 /OpenSim/Framework/Servers
parentAdd a build script. (diff)
downloadopensim-SC_OLD-5e4d6cab00cb29cd088ab7b62ab13aff103b64cb.zip
opensim-SC_OLD-5e4d6cab00cb29cd088ab7b62ab13aff103b64cb.tar.gz
opensim-SC_OLD-5e4d6cab00cb29cd088ab7b62ab13aff103b64cb.tar.bz2
opensim-SC_OLD-5e4d6cab00cb29cd088ab7b62ab13aff103b64cb.tar.xz
Dump OpenSim 0.9.0.1 into it's own branch.
Diffstat (limited to 'OpenSim/Framework/Servers')
-rw-r--r--OpenSim/Framework/Servers/BaseOpenSimServer.cs73
-rw-r--r--OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs204
-rw-r--r--OpenSim/Framework/Servers/HttpServer/BaseRequestHandler.cs14
-rw-r--r--OpenSim/Framework/Servers/HttpServer/BaseStreamHandler.cs4
-rw-r--r--OpenSim/Framework/Servers/HttpServer/BaseStreamHandlerBasicDOSProtector.cs8
-rw-r--r--OpenSim/Framework/Servers/HttpServer/GenericHTTPBasicDOSProtector.cs6
-rw-r--r--OpenSim/Framework/Servers/HttpServer/Interfaces/IHttpServer.cs34
-rw-r--r--OpenSim/Framework/Servers/HttpServer/Interfaces/IStreamHandler.cs2
-rw-r--r--OpenSim/Framework/Servers/HttpServer/JsonRpcRequestManager.cs7
-rw-r--r--OpenSim/Framework/Servers/HttpServer/JsonRpcResponse.cs2
-rw-r--r--OpenSim/Framework/Servers/HttpServer/OSHttpRequest.cs12
-rw-r--r--OpenSim/Framework/Servers/HttpServer/OSHttpResponse.cs4
-rw-r--r--OpenSim/Framework/Servers/HttpServer/OSHttpStatusCodes.cs2
-rw-r--r--OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs10
-rw-r--r--OpenSim/Framework/Servers/HttpServer/PollServiceHttpRequest.cs85
-rw-r--r--OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs327
-rw-r--r--OpenSim/Framework/Servers/HttpServer/Properties/AssemblyInfo.cs10
-rw-r--r--OpenSim/Framework/Servers/HttpServer/RestDeserialiseHandler.cs2
-rw-r--r--OpenSim/Framework/Servers/HttpServer/RestSessionService.cs6
-rw-r--r--OpenSim/Framework/Servers/HttpServer/RestStreamHandler.cs7
-rw-r--r--OpenSim/Framework/Servers/HttpServer/WebsocketServerHandler.cs82
-rw-r--r--OpenSim/Framework/Servers/HttpServer/XmlRpcBasicDOSProtector.cs6
-rw-r--r--OpenSim/Framework/Servers/MainServer.cs26
-rw-r--r--OpenSim/Framework/Servers/Properties/AssemblyInfo.cs8
-rw-r--r--OpenSim/Framework/Servers/ServerBase.cs180
-rw-r--r--OpenSim/Framework/Servers/Tests/OSHttpTests.cs341
-rw-r--r--OpenSim/Framework/Servers/Tests/VersionInfoTests.cs2
27 files changed, 951 insertions, 513 deletions
diff --git a/OpenSim/Framework/Servers/BaseOpenSimServer.cs b/OpenSim/Framework/Servers/BaseOpenSimServer.cs
index 5ce978e..81dd357 100644
--- a/OpenSim/Framework/Servers/BaseOpenSimServer.cs
+++ b/OpenSim/Framework/Servers/BaseOpenSimServer.cs
@@ -65,11 +65,12 @@ namespace OpenSim.Framework.Servers
65 /// This will control a periodic log printout of the current 'show stats' (if they are active) for this 65 /// This will control a periodic log printout of the current 'show stats' (if they are active) for this
66 /// server. 66 /// server.
67 /// </summary> 67 /// </summary>
68
68 private int m_periodDiagnosticTimerMS = 60 * 60 * 1000; 69 private int m_periodDiagnosticTimerMS = 60 * 60 * 1000;
69 private Timer m_periodicDiagnosticsTimer = new Timer(60 * 60 * 1000); 70 private Timer m_periodicDiagnosticsTimer = new Timer(60 * 60 * 1000);
70 71
71 /// <summary> 72 /// <summary>
72 /// Random uuid for private data 73 /// Random uuid for private data
73 /// </summary> 74 /// </summary>
74 protected string m_osSecret = String.Empty; 75 protected string m_osSecret = String.Empty;
75 76
@@ -83,9 +84,8 @@ namespace OpenSim.Framework.Servers
83 { 84 {
84 // Random uuid for private data 85 // Random uuid for private data
85 m_osSecret = UUID.Random().ToString(); 86 m_osSecret = UUID.Random().ToString();
86
87 } 87 }
88 88
89 /// <summary> 89 /// <summary>
90 /// Must be overriden by child classes for their own server specific startup behaviour. 90 /// Must be overriden by child classes for their own server specific startup behaviour.
91 /// </summary> 91 /// </summary>
@@ -104,26 +104,33 @@ namespace OpenSim.Framework.Servers
104 m_periodicDiagnosticsTimer.Interval = m_periodDiagnosticTimerMS; 104 m_periodicDiagnosticsTimer.Interval = m_periodDiagnosticTimerMS;
105 m_periodicDiagnosticsTimer.Enabled = true; 105 m_periodicDiagnosticsTimer.Enabled = true;
106 } 106 }
107 } 107 }
108 108
109 protected override void ShutdownSpecific() 109 protected override void ShutdownSpecific()
110 { 110 {
111 m_log.Info("[SHUTDOWN]: Shutdown processing on main thread complete. Exiting..."); 111 Watchdog.Enabled = false;
112 base.ShutdownSpecific();
113
114 MainServer.Stop();
115
116 Thread.Sleep(5000);
117 Util.StopThreadPool();
118 WorkManager.Stop();
112 119
120 Thread.Sleep(1000);
113 RemovePIDFile(); 121 RemovePIDFile();
114 122
115 base.ShutdownSpecific(); 123 m_log.Info("[SHUTDOWN]: Shutdown processing on main thread complete. Exiting...");
116 124
117 if (!SuppressExit) 125 if (!SuppressExit)
118 System.Diagnostics.Process.GetCurrentProcess().Kill(); 126 Environment.Exit(0);
119//// Environment.Exit(0);
120 } 127 }
121 128
122 /// <summary> 129 /// <summary>
123 /// Provides a list of help topics that are available. Overriding classes should append their topics to the 130 /// Provides a list of help topics that are available. Overriding classes should append their topics to the
124 /// information returned when the base method is called. 131 /// information returned when the base method is called.
125 /// </summary> 132 /// </summary>
126 /// 133 ///
127 /// <returns> 134 /// <returns>
128 /// A list of strings that represent different help topics on which more information is available 135 /// A list of strings that represent different help topics on which more information is available
129 /// </returns> 136 /// </returns>
@@ -147,20 +154,38 @@ namespace OpenSim.Framework.Servers
147 /// Performs initialisation of the scene, such as loading configuration from disk. 154 /// Performs initialisation of the scene, such as loading configuration from disk.
148 /// </summary> 155 /// </summary>
149 public virtual void Startup() 156 public virtual void Startup()
150 { 157 {
151 StartupSpecific(); 158 m_log.Info("[STARTUP]: Beginning startup processing");
152 159
160 m_log.Info("[STARTUP]: version: " + m_version + Environment.NewLine);
161 // clr version potentially is more confusing than helpful, since it doesn't tell us if we're running under Mono/MS .NET and
162 // the clr version number doesn't match the project version number under Mono.
163 //m_log.Info("[STARTUP]: Virtual machine runtime version: " + Environment.Version + Environment.NewLine);
164 m_log.InfoFormat(
165 "[STARTUP]: Operating system version: {0}, .NET platform {1}, {2}-bit\n",
166 Environment.OSVersion, Environment.OSVersion.Platform, Util.Is64BitProcess() ? "64" : "32");
167
168 try
169 {
170 StartupSpecific();
171 }
172 catch(Exception e)
173 {
174 m_log.Fatal("Fatal error: " + e.ToString());
175 Environment.Exit(1);
176 }
177
153 TimeSpan timeTaken = DateTime.Now - m_startuptime; 178 TimeSpan timeTaken = DateTime.Now - m_startuptime;
154 179
155 MainConsole.Instance.OutputFormat( 180// MainConsole.Instance.OutputFormat(
156 "PLEASE WAIT FOR LOGINS TO BE ENABLED ON REGIONS ONCE SCRIPTS HAVE STARTED. Non-script portion of startup took {0}m {1}s.", 181// "PLEASE WAIT FOR LOGINS TO BE ENABLED ON REGIONS ONCE SCRIPTS HAVE STARTED. Non-script portion of startup took {0}m {1}s.",
157 timeTaken.Minutes, timeTaken.Seconds); 182// timeTaken.Minutes, timeTaken.Seconds);
158 } 183 }
159 184
160 public string osSecret 185 public string osSecret
161 { 186 {
162 // Secret uuid for the simulator 187 // Secret uuid for the simulator
163 get { return m_osSecret; } 188 get { return m_osSecret; }
164 } 189 }
165 190
166 public string StatReport(IOSHttpRequest httpRequest) 191 public string StatReport(IOSHttpRequest httpRequest)
@@ -169,8 +194,8 @@ namespace OpenSim.Framework.Servers
169 if (httpRequest.Query.ContainsKey("callback")) 194 if (httpRequest.Query.ContainsKey("callback"))
170 { 195 {
171 return httpRequest.Query["callback"].ToString() + "(" + StatsManager.SimExtraStats.XReport((DateTime.Now - m_startuptime).ToString() , m_version) + ");"; 196 return httpRequest.Query["callback"].ToString() + "(" + StatsManager.SimExtraStats.XReport((DateTime.Now - m_startuptime).ToString() , m_version) + ");";
172 } 197 }
173 else 198 else
174 { 199 {
175 return StatsManager.SimExtraStats.XReport((DateTime.Now - m_startuptime).ToString() , m_version); 200 return StatsManager.SimExtraStats.XReport((DateTime.Now - m_startuptime).ToString() , m_version);
176 } 201 }
diff --git a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
index f252bd5..f4ba02f 100644
--- a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
+++ b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
@@ -58,7 +58,7 @@ namespace OpenSim.Framework.Servers.HttpServer
58 58
59 /// <summary> 59 /// <summary>
60 /// This is a pending websocket request before it got an sucessful upgrade response. 60 /// This is a pending websocket request before it got an sucessful upgrade response.
61 /// The consumer must call handler.HandshakeAndUpgrade() to signal to the handler to 61 /// The consumer must call handler.HandshakeAndUpgrade() to signal to the handler to
62 /// start the connection and optionally provide an origin authentication method. 62 /// start the connection and optionally provide an origin authentication method.
63 /// </summary> 63 /// </summary>
64 /// <param name="servicepath"></param> 64 /// <param name="servicepath"></param>
@@ -104,7 +104,7 @@ namespace OpenSim.Framework.Servers.HttpServer
104 new Dictionary<string, PollServiceEventArgs>(); 104 new Dictionary<string, PollServiceEventArgs>();
105 105
106 protected Dictionary<string, WebSocketRequestDelegate> m_WebSocketHandlers = 106 protected Dictionary<string, WebSocketRequestDelegate> m_WebSocketHandlers =
107 new Dictionary<string, WebSocketRequestDelegate>(); 107 new Dictionary<string, WebSocketRequestDelegate>();
108 108
109 protected uint m_port; 109 protected uint m_port;
110 protected uint m_sslport; 110 protected uint m_sslport;
@@ -253,7 +253,7 @@ namespace OpenSim.Framework.Servers.HttpServer
253 return new List<string>(m_rpcHandlers.Keys); 253 return new List<string>(m_rpcHandlers.Keys);
254 } 254 }
255 255
256 // JsonRPC 256 // JsonRPC
257 public bool AddJsonRPCHandler(string method, JsonRPCMethod handler) 257 public bool AddJsonRPCHandler(string method, JsonRPCMethod handler)
258 { 258 {
259 lock(jsonRpcHandlers) 259 lock(jsonRpcHandlers)
@@ -399,10 +399,10 @@ namespace OpenSim.Framework.Servers.HttpServer
399 399
400 Stream requestStream = req.InputStream; 400 Stream requestStream = req.InputStream;
401 401
402 string requestBody;
402 Encoding encoding = Encoding.UTF8; 403 Encoding encoding = Encoding.UTF8;
403 StreamReader reader = new StreamReader(requestStream, encoding); 404 using(StreamReader reader = new StreamReader(requestStream, encoding))
404 405 requestBody = reader.ReadToEnd();
405 string requestBody = reader.ReadToEnd();
406 406
407 Hashtable keysvals = new Hashtable(); 407 Hashtable keysvals = new Hashtable();
408 Hashtable headervals = new Hashtable(); 408 Hashtable headervals = new Hashtable();
@@ -458,10 +458,11 @@ namespace OpenSim.Framework.Servers.HttpServer
458 dWebSocketRequestDelegate(req.Url.AbsolutePath, new WebSocketHttpServerHandler(req, context, 8192)); 458 dWebSocketRequestDelegate(req.Url.AbsolutePath, new WebSocketHttpServerHandler(req, context, 8192));
459 return; 459 return;
460 } 460 }
461 461
462 OSHttpResponse resp = new OSHttpResponse(new HttpResponse(context, request),context); 462 OSHttpResponse resp = new OSHttpResponse(new HttpResponse(context, request),context);
463 resp.ReuseContext = true; 463 resp.ReuseContext = true;
464 HandleRequest(req, resp); 464// resp.ReuseContext = false;
465 HandleRequest(req, resp);
465 466
466 // !!!HACK ALERT!!! 467 // !!!HACK ALERT!!!
467 // There seems to be a bug in the underlying http code that makes subsequent requests 468 // There seems to be a bug in the underlying http code that makes subsequent requests
@@ -552,7 +553,7 @@ namespace OpenSim.Framework.Servers.HttpServer
552 LogIncomingToStreamHandler(request, requestHandler); 553 LogIncomingToStreamHandler(request, requestHandler);
553 554
554 response.ContentType = requestHandler.ContentType; // Lets do this defaulting before in case handler has varying content type. 555 response.ContentType = requestHandler.ContentType; // Lets do this defaulting before in case handler has varying content type.
555 556
556 if (requestHandler is IStreamedRequestHandler) 557 if (requestHandler is IStreamedRequestHandler)
557 { 558 {
558 IStreamedRequestHandler streamedRequestHandler = requestHandler as IStreamedRequestHandler; 559 IStreamedRequestHandler streamedRequestHandler = requestHandler as IStreamedRequestHandler;
@@ -565,13 +566,10 @@ namespace OpenSim.Framework.Servers.HttpServer
565 IGenericHTTPHandler HTTPRequestHandler = requestHandler as IGenericHTTPHandler; 566 IGenericHTTPHandler HTTPRequestHandler = requestHandler as IGenericHTTPHandler;
566 Stream requestStream = request.InputStream; 567 Stream requestStream = request.InputStream;
567 568
569 string requestBody;
568 Encoding encoding = Encoding.UTF8; 570 Encoding encoding = Encoding.UTF8;
569 StreamReader reader = new StreamReader(requestStream, encoding); 571 using(StreamReader reader = new StreamReader(requestStream, encoding))
570 572 requestBody = reader.ReadToEnd();
571 string requestBody = reader.ReadToEnd();
572
573 reader.Close();
574 //requestStream.Close();
575 573
576 Hashtable keysvals = new Hashtable(); 574 Hashtable keysvals = new Hashtable();
577 Hashtable headervals = new Hashtable(); 575 Hashtable headervals = new Hashtable();
@@ -628,16 +626,16 @@ namespace OpenSim.Framework.Servers.HttpServer
628 case "text/html": 626 case "text/html":
629 if (DebugLevel >= 3) 627 if (DebugLevel >= 3)
630 LogIncomingToContentTypeHandler(request); 628 LogIncomingToContentTypeHandler(request);
631 629
632 buffer = HandleHTTPRequest(request, response); 630 buffer = HandleHTTPRequest(request, response);
633 break; 631 break;
634 632
635 case "application/llsd+xml": 633 case "application/llsd+xml":
636 case "application/xml+llsd": 634 case "application/xml+llsd":
637 case "application/llsd+json": 635 case "application/llsd+json":
638 if (DebugLevel >= 3) 636 if (DebugLevel >= 3)
639 LogIncomingToContentTypeHandler(request); 637 LogIncomingToContentTypeHandler(request);
640 638
641 buffer = HandleLLSDRequests(request, response); 639 buffer = HandleLLSDRequests(request, response);
642 break; 640 break;
643 641
@@ -647,7 +645,7 @@ namespace OpenSim.Framework.Servers.HttpServer
647 645
648 buffer = HandleJsonRpcRequests(request, response); 646 buffer = HandleJsonRpcRequests(request, response);
649 break; 647 break;
650 648
651 case "text/xml": 649 case "text/xml":
652 case "application/xml": 650 case "application/xml":
653 case "application/json": 651 case "application/json":
@@ -664,7 +662,7 @@ namespace OpenSim.Framework.Servers.HttpServer
664 { 662 {
665 if (DebugLevel >= 3) 663 if (DebugLevel >= 3)
666 LogIncomingToContentTypeHandler(request); 664 LogIncomingToContentTypeHandler(request);
667 665
668 buffer = HandleLLSDRequests(request, response); 666 buffer = HandleLLSDRequests(request, response);
669 } 667 }
670 // m_log.DebugFormat("[BASE HTTP SERVER]: Checking for HTTP Handler for request {0}", request.RawUrl); 668 // m_log.DebugFormat("[BASE HTTP SERVER]: Checking for HTTP Handler for request {0}", request.RawUrl);
@@ -672,23 +670,24 @@ namespace OpenSim.Framework.Servers.HttpServer
672 { 670 {
673 if (DebugLevel >= 3) 671 if (DebugLevel >= 3)
674 LogIncomingToContentTypeHandler(request); 672 LogIncomingToContentTypeHandler(request);
675 673
676 buffer = HandleHTTPRequest(request, response); 674 buffer = HandleHTTPRequest(request, response);
677 } 675 }
678 else 676 else
679 { 677 {
680 if (DebugLevel >= 3) 678 if (DebugLevel >= 3)
681 LogIncomingToXmlRpcHandler(request); 679 LogIncomingToXmlRpcHandler(request);
682 680
683 // generic login request. 681 // generic login request.
684 buffer = HandleXmlRpcRequests(request, response); 682 buffer = HandleXmlRpcRequests(request, response);
685 } 683 }
686 684
687 break; 685 break;
688 } 686 }
689 } 687 }
690 688
691 request.InputStream.Close(); 689 if(request.InputStream.CanRead)
690 request.InputStream.Dispose();
692 691
693 if (buffer != null) 692 if (buffer != null)
694 { 693 {
@@ -759,7 +758,7 @@ namespace OpenSim.Framework.Servers.HttpServer
759 // Every month or so this will wrap and give bad numbers, not really a problem 758 // Every month or so this will wrap and give bad numbers, not really a problem
760 // since its just for reporting 759 // since its just for reporting
761 int tickdiff = requestEndTick - requestStartTick; 760 int tickdiff = requestEndTick - requestStartTick;
762 if (tickdiff > 3000 && requestHandler != null && requestHandler.Name != "GetTexture") 761 if (tickdiff > 3000 && (requestHandler == null || requestHandler.Name == null || requestHandler.Name != "GetTexture"))
763 { 762 {
764 m_log.InfoFormat( 763 m_log.InfoFormat(
765 "[LOGHTTP] Slow handling of {0} {1} {2} {3} {4} from {5} took {6}ms", 764 "[LOGHTTP] Slow handling of {0} {1} {2} {3} {4} from {5} took {6}ms",
@@ -970,7 +969,7 @@ namespace OpenSim.Framework.Servers.HttpServer
970// private bool TryGetAgentHandler(OSHttpRequest request, OSHttpResponse response, out IHttpAgentHandler agentHandler) 969// private bool TryGetAgentHandler(OSHttpRequest request, OSHttpResponse response, out IHttpAgentHandler agentHandler)
971// { 970// {
972// agentHandler = null; 971// agentHandler = null;
973// 972//
974// lock (m_agentHandlers) 973// lock (m_agentHandlers)
975// { 974// {
976// foreach (IHttpAgentHandler handler in m_agentHandlers.Values) 975// foreach (IHttpAgentHandler handler in m_agentHandlers.Values)
@@ -996,7 +995,7 @@ namespace OpenSim.Framework.Servers.HttpServer
996 { 995 {
997 String requestBody; 996 String requestBody;
998 997
999 Stream requestStream = request.InputStream; 998 Stream requestStream = Util.Copy(request.InputStream);
1000 Stream innerStream = null; 999 Stream innerStream = null;
1001 try 1000 try
1002 { 1001 {
@@ -1007,9 +1006,8 @@ namespace OpenSim.Framework.Servers.HttpServer
1007 } 1006 }
1008 1007
1009 using (StreamReader reader = new StreamReader(requestStream, Encoding.UTF8)) 1008 using (StreamReader reader = new StreamReader(requestStream, Encoding.UTF8))
1010 {
1011 requestBody = reader.ReadToEnd(); 1009 requestBody = reader.ReadToEnd();
1012 } 1010
1013 } 1011 }
1014 finally 1012 finally
1015 { 1013 {
@@ -1024,6 +1022,19 @@ namespace OpenSim.Framework.Servers.HttpServer
1024 string responseString = String.Empty; 1022 string responseString = String.Empty;
1025 XmlRpcRequest xmlRprcRequest = null; 1023 XmlRpcRequest xmlRprcRequest = null;
1026 1024
1025 bool gridproxy = false;
1026 if (requestBody.Contains("encoding=\"utf-8"))
1027 {
1028 int channelindx = -1;
1029 int optionsindx = requestBody.IndexOf(">options<");
1030 if(optionsindx >0)
1031 {
1032 channelindx = requestBody.IndexOf(">channel<");
1033 if (optionsindx < channelindx)
1034 gridproxy = true;
1035 }
1036 }
1037
1027 try 1038 try
1028 { 1039 {
1029 xmlRprcRequest = (XmlRpcRequest) (new XmlRpcRequestDeserializer()).Deserialize(requestBody); 1040 xmlRprcRequest = (XmlRpcRequest) (new XmlRpcRequestDeserializer()).Deserialize(requestBody);
@@ -1081,6 +1092,8 @@ namespace OpenSim.Framework.Servers.HttpServer
1081 } 1092 }
1082 xmlRprcRequest.Params.Add(request.Headers.Get(xff)); // Param[3] 1093 xmlRprcRequest.Params.Add(request.Headers.Get(xff)); // Param[3]
1083 1094
1095 if (gridproxy)
1096 xmlRprcRequest.Params.Add("gridproxy"); // Param[4]
1084 try 1097 try
1085 { 1098 {
1086 xmlRpcResponse = method(xmlRprcRequest, request.RemoteIPEndPoint); 1099 xmlRpcResponse = method(xmlRprcRequest, request.RemoteIPEndPoint);
@@ -1154,7 +1167,7 @@ namespace OpenSim.Framework.Servers.HttpServer
1154 return buffer; 1167 return buffer;
1155 } 1168 }
1156 1169
1157 // JsonRpc (v2.0 only) 1170 // JsonRpc (v2.0 only)
1158 // Batch requests not yet supported 1171 // Batch requests not yet supported
1159 private byte[] HandleJsonRpcRequests(OSHttpRequest request, OSHttpResponse response) 1172 private byte[] HandleJsonRpcRequests(OSHttpRequest request, OSHttpResponse response)
1160 { 1173 {
@@ -1171,7 +1184,7 @@ namespace OpenSim.Framework.Servers.HttpServer
1171 jsonRpcResponse.Error.Code = ErrorCode.InternalError; 1184 jsonRpcResponse.Error.Code = ErrorCode.InternalError;
1172 jsonRpcResponse.Error.Message = e.Message; 1185 jsonRpcResponse.Error.Message = e.Message;
1173 } 1186 }
1174 1187
1175 requestStream.Close(); 1188 requestStream.Close();
1176 1189
1177 if (jsonRpcRequest != null) 1190 if (jsonRpcRequest != null)
@@ -1236,7 +1249,7 @@ namespace OpenSim.Framework.Servers.HttpServer
1236 string responseData = string.Empty; 1249 string responseData = string.Empty;
1237 1250
1238 responseData = jsonRpcResponse.Serialize(); 1251 responseData = jsonRpcResponse.Serialize();
1239 1252
1240 byte[] buffer = Encoding.UTF8.GetBytes(responseData); 1253 byte[] buffer = Encoding.UTF8.GetBytes(responseData);
1241 return buffer; 1254 return buffer;
1242 } 1255 }
@@ -1246,12 +1259,10 @@ namespace OpenSim.Framework.Servers.HttpServer
1246 //m_log.Warn("[BASE HTTP SERVER]: We've figured out it's a LLSD Request"); 1259 //m_log.Warn("[BASE HTTP SERVER]: We've figured out it's a LLSD Request");
1247 Stream requestStream = request.InputStream; 1260 Stream requestStream = request.InputStream;
1248 1261
1262 string requestBody;
1249 Encoding encoding = Encoding.UTF8; 1263 Encoding encoding = Encoding.UTF8;
1250 StreamReader reader = new StreamReader(requestStream, encoding); 1264 using(StreamReader reader = new StreamReader(requestStream, encoding))
1251 1265 requestBody= reader.ReadToEnd();
1252 string requestBody = reader.ReadToEnd();
1253 reader.Close();
1254 requestStream.Close();
1255 1266
1256 //m_log.DebugFormat("[OGP]: {0}:{1}", request.RawUrl, requestBody); 1267 //m_log.DebugFormat("[OGP]: {0}:{1}", request.RawUrl, requestBody);
1257 response.KeepAlive = true; 1268 response.KeepAlive = true;
@@ -1516,7 +1527,7 @@ namespace OpenSim.Framework.Servers.HttpServer
1516 } 1527 }
1517 } 1528 }
1518 } 1529 }
1519 1530
1520 if (String.IsNullOrEmpty(bestMatch)) 1531 if (String.IsNullOrEmpty(bestMatch))
1521 { 1532 {
1522 llsdHandler = null; 1533 llsdHandler = null;
@@ -1575,15 +1586,10 @@ namespace OpenSim.Framework.Servers.HttpServer
1575 byte[] buffer; 1586 byte[] buffer;
1576 1587
1577 Stream requestStream = request.InputStream; 1588 Stream requestStream = request.InputStream;
1578 1589 string requestBody;
1579 Encoding encoding = Encoding.UTF8; 1590 Encoding encoding = Encoding.UTF8;
1580 StreamReader reader = new StreamReader(requestStream, encoding); 1591 using(StreamReader reader = new StreamReader(requestStream, encoding))
1581 1592 requestBody = reader.ReadToEnd();
1582 string requestBody = reader.ReadToEnd();
1583 // avoid warning for now
1584 reader.ReadToEnd();
1585 reader.Close();
1586 requestStream.Close();
1587 1593
1588 Hashtable keysvals = new Hashtable(); 1594 Hashtable keysvals = new Hashtable();
1589 Hashtable headervals = new Hashtable(); 1595 Hashtable headervals = new Hashtable();
@@ -1732,10 +1738,40 @@ namespace OpenSim.Framework.Servers.HttpServer
1732 1738
1733 internal byte[] DoHTTPGruntWork(Hashtable responsedata, OSHttpResponse response) 1739 internal byte[] DoHTTPGruntWork(Hashtable responsedata, OSHttpResponse response)
1734 { 1740 {
1735 //m_log.Info("[BASE HTTP SERVER]: Doing HTTP Grunt work with response"); 1741 int responsecode;
1736 int responsecode = (int)responsedata["int_response_code"]; 1742 string responseString = String.Empty;
1737 string responseString = (string)responsedata["str_response_string"]; 1743 byte[] responseData = null;
1738 string contentType = (string)responsedata["content_type"]; 1744 string contentType;
1745
1746 if (responsedata == null)
1747 {
1748 responsecode = 500;
1749 responseString = "No response could be obtained";
1750 contentType = "text/plain";
1751 responsedata = new Hashtable();
1752 }
1753 else
1754 {
1755 try
1756 {
1757 //m_log.Info("[BASE HTTP SERVER]: Doing HTTP Grunt work with response");
1758 responsecode = (int)responsedata["int_response_code"];
1759 if (responsedata["bin_response_data"] != null)
1760 responseData = (byte[])responsedata["bin_response_data"];
1761 else
1762 responseString = (string)responsedata["str_response_string"];
1763 contentType = (string)responsedata["content_type"];
1764 if (responseString == null)
1765 responseString = String.Empty;
1766 }
1767 catch
1768 {
1769 responsecode = 500;
1770 responseString = "No response could be obtained";
1771 contentType = "text/plain";
1772 responsedata = new Hashtable();
1773 }
1774 }
1739 1775
1740 if (responsedata.ContainsKey("error_status_text")) 1776 if (responsedata.ContainsKey("error_status_text"))
1741 { 1777 {
@@ -1745,16 +1781,19 @@ namespace OpenSim.Framework.Servers.HttpServer
1745 { 1781 {
1746 response.ProtocolVersion = (string)responsedata["http_protocol_version"]; 1782 response.ProtocolVersion = (string)responsedata["http_protocol_version"];
1747 } 1783 }
1748 1784/*
1749 if (responsedata.ContainsKey("keepalive")) 1785 if (responsedata.ContainsKey("keepalive"))
1750 { 1786 {
1751 bool keepalive = (bool)responsedata["keepalive"]; 1787 bool keepalive = (bool)responsedata["keepalive"];
1752 response.KeepAlive = keepalive; 1788 response.KeepAlive = keepalive;
1753
1754 } 1789 }
1755 1790
1756 if (responsedata.ContainsKey("reusecontext")) 1791 if (responsedata.ContainsKey("reusecontext"))
1757 response.ReuseContext = (bool) responsedata["reusecontext"]; 1792 response.ReuseContext = (bool) responsedata["reusecontext"];
1793*/
1794 // disable this things
1795 response.KeepAlive = false;
1796 response.ReuseContext = false;
1758 1797
1759 // Cross-Origin Resource Sharing with simple requests 1798 // Cross-Origin Resource Sharing with simple requests
1760 if (responsedata.ContainsKey("access_control_allow_origin")) 1799 if (responsedata.ContainsKey("access_control_allow_origin"))
@@ -1768,8 +1807,11 @@ namespace OpenSim.Framework.Servers.HttpServer
1768 contentType = "text/html"; 1807 contentType = "text/html";
1769 } 1808 }
1770 1809
1810
1811
1771 // The client ignores anything but 200 here for web login, so ensure that this is 200 for that 1812 // The client ignores anything but 200 here for web login, so ensure that this is 200 for that
1772 1813
1814
1773 response.StatusCode = responsecode; 1815 response.StatusCode = responsecode;
1774 1816
1775 if (responsecode == (int)OSHttpStatusCode.RedirectMovedPermanently) 1817 if (responsecode == (int)OSHttpStatusCode.RedirectMovedPermanently)
@@ -1780,25 +1822,40 @@ namespace OpenSim.Framework.Servers.HttpServer
1780 1822
1781 response.AddHeader("Content-Type", contentType); 1823 response.AddHeader("Content-Type", contentType);
1782 1824
1825 if (responsedata.ContainsKey("headers"))
1826 {
1827 Hashtable headerdata = (Hashtable)responsedata["headers"];
1828
1829 foreach (string header in headerdata.Keys)
1830 response.AddHeader(header, headerdata[header].ToString());
1831 }
1832
1783 byte[] buffer; 1833 byte[] buffer;
1784 1834
1785 if (!(contentType.Contains("image") 1835 if (responseData != null)
1786 || contentType.Contains("x-shockwave-flash")
1787 || contentType.Contains("application/x-oar")
1788 || contentType.Contains("application/vnd.ll.mesh")))
1789 { 1836 {
1790 // Text 1837 buffer = responseData;
1791 buffer = Encoding.UTF8.GetBytes(responseString);
1792 } 1838 }
1793 else 1839 else
1794 { 1840 {
1795 // Binary! 1841 if (!(contentType.Contains("image")
1796 buffer = Convert.FromBase64String(responseString); 1842 || contentType.Contains("x-shockwave-flash")
1797 } 1843 || contentType.Contains("application/x-oar")
1844 || contentType.Contains("application/vnd.ll.mesh")))
1845 {
1846 // Text
1847 buffer = Encoding.UTF8.GetBytes(responseString);
1848 }
1849 else
1850 {
1851 // Binary!
1852 buffer = Convert.FromBase64String(responseString);
1853 }
1798 1854
1799 response.SendChunked = false; 1855 response.SendChunked = false;
1800 response.ContentLength64 = buffer.Length; 1856 response.ContentLength64 = buffer.Length;
1801 response.ContentEncoding = Encoding.UTF8; 1857 response.ContentEncoding = Encoding.UTF8;
1858 }
1802 1859
1803 return buffer; 1860 return buffer;
1804 } 1861 }
@@ -1831,8 +1888,8 @@ namespace OpenSim.Framework.Servers.HttpServer
1831 response.SendChunked = false; 1888 response.SendChunked = false;
1832 response.ContentLength64 = buffer.Length; 1889 response.ContentLength64 = buffer.Length;
1833 response.ContentEncoding = Encoding.UTF8; 1890 response.ContentEncoding = Encoding.UTF8;
1834 1891
1835 1892
1836 return buffer; 1893 return buffer;
1837 } 1894 }
1838 1895
@@ -1886,7 +1943,8 @@ namespace OpenSim.Framework.Servers.HttpServer
1886 m_httpListener2.Start(64); 1943 m_httpListener2.Start(64);
1887 1944
1888 // Long Poll Service Manager with 3 worker threads a 25 second timeout for no events 1945 // Long Poll Service Manager with 3 worker threads a 25 second timeout for no events
1889 PollServiceRequestManager = new PollServiceRequestManager(this, performPollResponsesAsync, 3, 25000); 1946
1947 PollServiceRequestManager = new PollServiceRequestManager(this, performPollResponsesAsync, 2, 25000);
1890 PollServiceRequestManager.Start(); 1948 PollServiceRequestManager.Start();
1891 1949
1892 HTTPDRunning = true; 1950 HTTPDRunning = true;
@@ -1908,7 +1966,7 @@ namespace OpenSim.Framework.Servers.HttpServer
1908 throw e; 1966 throw e;
1909 } 1967 }
1910 1968
1911 m_requestsProcessedStat 1969 m_requestsProcessedStat
1912 = new Stat( 1970 = new Stat(
1913 "HTTPRequestsServed", 1971 "HTTPRequestsServed",
1914 "Number of inbound HTTP requests processed", 1972 "Number of inbound HTTP requests processed",
@@ -1920,7 +1978,7 @@ namespace OpenSim.Framework.Servers.HttpServer
1920 MeasuresOfInterest.AverageChangeOverTime, 1978 MeasuresOfInterest.AverageChangeOverTime,
1921 stat => stat.Value = RequestNumber, 1979 stat => stat.Value = RequestNumber,
1922 StatVerbosity.Debug); 1980 StatVerbosity.Debug);
1923 1981
1924 StatsManager.RegisterStat(m_requestsProcessedStat); 1982 StatsManager.RegisterStat(m_requestsProcessedStat);
1925 } 1983 }
1926 1984
@@ -1937,7 +1995,9 @@ namespace OpenSim.Framework.Servers.HttpServer
1937 1995
1938 public void httpServerException(object source, Exception exception) 1996 public void httpServerException(object source, Exception exception)
1939 { 1997 {
1940 m_log.Error(String.Format("[BASE HTTP SERVER]: {0} had an exception: {1} ", source.ToString(), exception.Message), exception); 1998 if (source.ToString() == "HttpServer.HttpListener" && exception.ToString().StartsWith("Mono.Security.Protocol.Tls.TlsException"))
1999 return;
2000 m_log.ErrorFormat("[BASE HTTP SERVER]: {0} had an exception {1}", source.ToString(), exception.ToString());
1941 /* 2001 /*
1942 if (HTTPDRunning)// && NotSocketErrors > 5) 2002 if (HTTPDRunning)// && NotSocketErrors > 5)
1943 { 2003 {
@@ -1957,7 +2017,8 @@ namespace OpenSim.Framework.Servers.HttpServer
1957 2017
1958 try 2018 try
1959 { 2019 {
1960 PollServiceRequestManager.Stop(); 2020 if(PollServiceRequestManager != null)
2021 PollServiceRequestManager.Stop();
1961 2022
1962 m_httpListener2.ExceptionThrown -= httpServerException; 2023 m_httpListener2.ExceptionThrown -= httpServerException;
1963 //m_httpListener2.DisconnectHandler = null; 2024 //m_httpListener2.DisconnectHandler = null;
@@ -1984,6 +2045,7 @@ namespace OpenSim.Framework.Servers.HttpServer
1984 2045
1985 public void RemoveHTTPHandler(string httpMethod, string path) 2046 public void RemoveHTTPHandler(string httpMethod, string path)
1986 { 2047 {
2048 if (path == null) return; // Caps module isn't loaded, tries to remove handler where path = null
1987 lock (m_HTTPHandlers) 2049 lock (m_HTTPHandlers)
1988 { 2050 {
1989 if (httpMethod != null && httpMethod.Length == 0) 2051 if (httpMethod != null && httpMethod.Length == 0)
diff --git a/OpenSim/Framework/Servers/HttpServer/BaseRequestHandler.cs b/OpenSim/Framework/Servers/HttpServer/BaseRequestHandler.cs
index d4a1ec3..01d95e9 100644
--- a/OpenSim/Framework/Servers/HttpServer/BaseRequestHandler.cs
+++ b/OpenSim/Framework/Servers/HttpServer/BaseRequestHandler.cs
@@ -69,13 +69,13 @@ namespace OpenSim.Framework.Servers.HttpServer
69 { 69 {
70 StatsManager.RegisterStat( 70 StatsManager.RegisterStat(
71 new Stat( 71 new Stat(
72 "requests", 72 "requests",
73 "requests", 73 "requests",
74 "Number of requests received by this service endpoint", 74 "Number of requests received by this service endpoint",
75 "requests", 75 "requests",
76 "service", 76 "service",
77 string.Format("{0}:{1}", httpMethod, path), 77 string.Format("{0}:{1}", httpMethod, path),
78 StatType.Pull, 78 StatType.Pull,
79 MeasuresOfInterest.AverageChangeOverTime, 79 MeasuresOfInterest.AverageChangeOverTime,
80 s => s.Value = RequestsReceived, 80 s => s.Value = RequestsReceived,
81 StatVerbosity.Debug)); 81 StatVerbosity.Debug));
diff --git a/OpenSim/Framework/Servers/HttpServer/BaseStreamHandler.cs b/OpenSim/Framework/Servers/HttpServer/BaseStreamHandler.cs
index 41aa19b..7fc9f0b 100644
--- a/OpenSim/Framework/Servers/HttpServer/BaseStreamHandler.cs
+++ b/OpenSim/Framework/Servers/HttpServer/BaseStreamHandler.cs
@@ -47,7 +47,7 @@ namespace OpenSim.Framework.Servers.HttpServer
47 : base(httpMethod, path, name, description) {} 47 : base(httpMethod, path, name, description) {}
48 48
49 protected BaseStreamHandler(string httpMethod, string path, IServiceAuth auth) 49 protected BaseStreamHandler(string httpMethod, string path, IServiceAuth auth)
50 : base(httpMethod, path, null, null) 50 : base(httpMethod, path, null, null)
51 { 51 {
52 m_Auth = auth; 52 m_Auth = auth;
53 } 53 }
@@ -62,7 +62,7 @@ namespace OpenSim.Framework.Servers.HttpServer
62 HttpStatusCode statusCode; 62 HttpStatusCode statusCode;
63 63
64 if (!m_Auth.Authenticate(httpRequest.Headers, httpResponse.AddHeader, out statusCode)) 64 if (!m_Auth.Authenticate(httpRequest.Headers, httpResponse.AddHeader, out statusCode))
65 { 65 {
66 httpResponse.StatusCode = (int)statusCode; 66 httpResponse.StatusCode = (int)statusCode;
67 httpResponse.ContentType = "text/plain"; 67 httpResponse.ContentType = "text/plain";
68 return new byte[0]; 68 return new byte[0];
diff --git a/OpenSim/Framework/Servers/HttpServer/BaseStreamHandlerBasicDOSProtector.cs b/OpenSim/Framework/Servers/HttpServer/BaseStreamHandlerBasicDOSProtector.cs
index 1b88545..9619e03 100644
--- a/OpenSim/Framework/Servers/HttpServer/BaseStreamHandlerBasicDOSProtector.cs
+++ b/OpenSim/Framework/Servers/HttpServer/BaseStreamHandlerBasicDOSProtector.cs
@@ -37,7 +37,7 @@ namespace OpenSim.Framework.Servers.HttpServer
37 /// </remarks> 37 /// </remarks>
38 public abstract class BaseStreamHandlerBasicDOSProtector : BaseRequestHandler, IStreamedRequestHandler 38 public abstract class BaseStreamHandlerBasicDOSProtector : BaseRequestHandler, IStreamedRequestHandler
39 { 39 {
40 40
41 private readonly BasicDosProtectorOptions _options; 41 private readonly BasicDosProtectorOptions _options;
42 private readonly BasicDOSProtector _dosProtector; 42 private readonly BasicDOSProtector _dosProtector;
43 43
@@ -63,7 +63,7 @@ namespace OpenSim.Framework.Servers.HttpServer
63 result = ThrottledRequest(path, request, httpRequest, httpResponse); 63 result = ThrottledRequest(path, request, httpRequest, httpResponse);
64 if (_options.MaxConcurrentSessions > 0) 64 if (_options.MaxConcurrentSessions > 0)
65 _dosProtector.ProcessEnd(clientstring, endpoint); 65 _dosProtector.ProcessEnd(clientstring, endpoint);
66 66
67 RequestsHandled++; 67 RequestsHandled++;
68 68
69 return result; 69 return result;
@@ -81,7 +81,7 @@ namespace OpenSim.Framework.Servers.HttpServer
81 return new byte[0]; 81 return new byte[0];
82 } 82 }
83 83
84 84
85 private string GetRemoteAddr(IOSHttpRequest httpRequest) 85 private string GetRemoteAddr(IOSHttpRequest httpRequest)
86 { 86 {
87 string remoteaddr = string.Empty; 87 string remoteaddr = string.Empty;
@@ -101,7 +101,7 @@ namespace OpenSim.Framework.Servers.HttpServer
101 clientstring = GetRemoteAddr(httpRequest); 101 clientstring = GetRemoteAddr(httpRequest);
102 102
103 return clientstring; 103 return clientstring;
104 104
105 } 105 }
106 } 106 }
107} 107}
diff --git a/OpenSim/Framework/Servers/HttpServer/GenericHTTPBasicDOSProtector.cs b/OpenSim/Framework/Servers/HttpServer/GenericHTTPBasicDOSProtector.cs
index cd4b8ff..98d33e4 100644
--- a/OpenSim/Framework/Servers/HttpServer/GenericHTTPBasicDOSProtector.cs
+++ b/OpenSim/Framework/Servers/HttpServer/GenericHTTPBasicDOSProtector.cs
@@ -33,7 +33,7 @@ namespace OpenSim.Framework.Servers.HttpServer
33 { 33 {
34 private readonly GenericHTTPMethod _normalMethod; 34 private readonly GenericHTTPMethod _normalMethod;
35 private readonly GenericHTTPMethod _throttledMethod; 35 private readonly GenericHTTPMethod _throttledMethod;
36 36
37 private readonly BasicDosProtectorOptions _options; 37 private readonly BasicDosProtectorOptions _options;
38 private readonly BasicDOSProtector _dosProtector; 38 private readonly BasicDOSProtector _dosProtector;
39 39
@@ -41,7 +41,7 @@ namespace OpenSim.Framework.Servers.HttpServer
41 { 41 {
42 _normalMethod = normalMethod; 42 _normalMethod = normalMethod;
43 _throttledMethod = throttledMethod; 43 _throttledMethod = throttledMethod;
44 44
45 _options = options; 45 _options = options;
46 _dosProtector = new BasicDOSProtector(_options); 46 _dosProtector = new BasicDOSProtector(_options);
47 } 47 }
@@ -60,7 +60,7 @@ namespace OpenSim.Framework.Servers.HttpServer
60 60
61 return process; 61 return process;
62 } 62 }
63 63
64 private string GetRemoteAddr(Hashtable request) 64 private string GetRemoteAddr(Hashtable request)
65 { 65 {
66 string remoteaddr = ""; 66 string remoteaddr = "";
diff --git a/OpenSim/Framework/Servers/HttpServer/Interfaces/IHttpServer.cs b/OpenSim/Framework/Servers/HttpServer/Interfaces/IHttpServer.cs
index d162bc1..3a04074 100644
--- a/OpenSim/Framework/Servers/HttpServer/Interfaces/IHttpServer.cs
+++ b/OpenSim/Framework/Servers/HttpServer/Interfaces/IHttpServer.cs
@@ -45,26 +45,26 @@ namespace OpenSim.Framework.Servers.HttpServer
45// // the handlers - it is NOT required to be an actual agent header 45// // the handlers - it is NOT required to be an actual agent header
46// // value. 46// // value.
47// bool AddAgentHandler(string agent, IHttpAgentHandler handler); 47// bool AddAgentHandler(string agent, IHttpAgentHandler handler);
48 48
49 /// <summary> 49 /// <summary>
50 /// Add a handler for an HTTP request. 50 /// Add a handler for an HTTP request.
51 /// </summary> 51 /// </summary>
52 /// <remarks> 52 /// <remarks>
53 /// This handler can actually be invoked either as 53 /// This handler can actually be invoked either as
54 /// 54 ///
55 /// http://<hostname>:<port>/?method=<methodName> 55 /// http://<hostname>:<port>/?method=<methodName>
56 /// 56 ///
57 /// or 57 /// or
58 /// 58 ///
59 /// http://<hostname>:<port><method> 59 /// http://<hostname>:<port><method>
60 /// 60 ///
61 /// if the method name starts with a slash. For example, AddHTTPHandler("/object/", ...) on a standalone region 61 /// if the method name starts with a slash. For example, AddHTTPHandler("/object/", ...) on a standalone region
62 /// server will register a handler that can be invoked with either 62 /// server will register a handler that can be invoked with either
63 /// 63 ///
64 /// http://localhost:9000/?method=/object/ 64 /// http://localhost:9000/?method=/object/
65 /// 65 ///
66 /// or 66 /// or
67 /// 67 ///
68 /// http://localhost:9000/object/ 68 /// http://localhost:9000/object/
69 /// 69 ///
70 /// In addition, the handler invoked by the HTTP server for any request is the one when best matches the request 70 /// In addition, the handler invoked by the HTTP server for any request is the one when best matches the request
@@ -87,7 +87,7 @@ namespace OpenSim.Framework.Servers.HttpServer
87 /// <param name="handler">handle the LLSD response</param> 87 /// <param name="handler">handle the LLSD response</param>
88 /// <returns></returns> 88 /// <returns></returns>
89 bool AddLLSDHandler(string path, LLSDMethod handler); 89 bool AddLLSDHandler(string path, LLSDMethod handler);
90 90
91 /// <summary> 91 /// <summary>
92 /// Add a stream handler to the http server. If the handler already exists, then nothing happens. 92 /// Add a stream handler to the http server. If the handler already exists, then nothing happens.
93 /// </summary> 93 /// </summary>
@@ -98,7 +98,7 @@ namespace OpenSim.Framework.Servers.HttpServer
98 bool AddXmlRPCHandler(string method, XmlRpcMethod handler, bool keepAlive); 98 bool AddXmlRPCHandler(string method, XmlRpcMethod handler, bool keepAlive);
99 99
100 bool AddJsonRPCHandler(string method, JsonRPCMethod handler); 100 bool AddJsonRPCHandler(string method, JsonRPCMethod handler);
101 101
102 /// <summary> 102 /// <summary>
103 /// Websocket HTTP server handlers. 103 /// Websocket HTTP server handlers.
104 /// </summary> 104 /// </summary>
@@ -108,7 +108,7 @@ namespace OpenSim.Framework.Servers.HttpServer
108 108
109 109
110 void RemoveWebSocketHandler(string servicepath); 110 void RemoveWebSocketHandler(string servicepath);
111 111
112 /// <summary> 112 /// <summary>
113 /// Gets the XML RPC handler for given method name 113 /// Gets the XML RPC handler for given method name
114 /// </summary> 114 /// </summary>
@@ -125,7 +125,7 @@ namespace OpenSim.Framework.Servers.HttpServer
125// /// <param name="handler"></param> 125// /// <param name="handler"></param>
126// /// <returns></returns> 126// /// <returns></returns>
127// bool RemoveAgentHandler(string agent, IHttpAgentHandler handler); 127// bool RemoveAgentHandler(string agent, IHttpAgentHandler handler);
128 128
129 /// <summary> 129 /// <summary>
130 /// Remove an HTTP handler 130 /// Remove an HTTP handler
131 /// </summary> 131 /// </summary>
@@ -134,15 +134,15 @@ namespace OpenSim.Framework.Servers.HttpServer
134 void RemoveHTTPHandler(string httpMethod, string path); 134 void RemoveHTTPHandler(string httpMethod, string path);
135 135
136 void RemovePollServiceHTTPHandler(string httpMethod, string path); 136 void RemovePollServiceHTTPHandler(string httpMethod, string path);
137 137
138 bool RemoveLLSDHandler(string path, LLSDMethod handler); 138 bool RemoveLLSDHandler(string path, LLSDMethod handler);
139 139
140 void RemoveStreamHandler(string httpMethod, string path); 140 void RemoveStreamHandler(string httpMethod, string path);
141 141
142 void RemoveXmlRPCHandler(string method); 142 void RemoveXmlRPCHandler(string method);
143 143
144 void RemoveJsonRPCHandler(string method); 144 void RemoveJsonRPCHandler(string method);
145 145
146 string GetHTTP404(string host); 146 string GetHTTP404(string host);
147 147
148 string GetHTTP500(); 148 string GetHTTP500();
diff --git a/OpenSim/Framework/Servers/HttpServer/Interfaces/IStreamHandler.cs b/OpenSim/Framework/Servers/HttpServer/Interfaces/IStreamHandler.cs
index b8541cb..62d92fb 100644
--- a/OpenSim/Framework/Servers/HttpServer/Interfaces/IStreamHandler.cs
+++ b/OpenSim/Framework/Servers/HttpServer/Interfaces/IStreamHandler.cs
@@ -83,7 +83,7 @@ namespace OpenSim.Framework.Servers.HttpServer
83 { 83 {
84 void Handle(string path, Stream request, Stream response, IOSHttpRequest httpReqbuest, IOSHttpResponse httpResponse); 84 void Handle(string path, Stream request, Stream response, IOSHttpRequest httpReqbuest, IOSHttpResponse httpResponse);
85 } 85 }
86 86
87 public interface IGenericHTTPHandler : IRequestHandler 87 public interface IGenericHTTPHandler : IRequestHandler
88 { 88 {
89 Hashtable Handle(string path, Hashtable request); 89 Hashtable Handle(string path, Hashtable request);
diff --git a/OpenSim/Framework/Servers/HttpServer/JsonRpcRequestManager.cs b/OpenSim/Framework/Servers/HttpServer/JsonRpcRequestManager.cs
index 2fe1a7d..411ee31 100644
--- a/OpenSim/Framework/Servers/HttpServer/JsonRpcRequestManager.cs
+++ b/OpenSim/Framework/Servers/HttpServer/JsonRpcRequestManager.cs
@@ -43,7 +43,7 @@ namespace OpenSim.Framework.Servers.HttpServer
43 public class JsonRpcRequestManager 43 public class JsonRpcRequestManager
44 { 44 {
45 static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 45 static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
46 46
47 public JsonRpcRequestManager() 47 public JsonRpcRequestManager()
48 { 48 {
49 } 49 }
@@ -77,6 +77,9 @@ namespace OpenSim.Framework.Servers.HttpServer
77 if (parameters == null) 77 if (parameters == null)
78 throw new ArgumentNullException("parameters"); 78 throw new ArgumentNullException("parameters");
79 79
80 if(string.IsNullOrWhiteSpace(uri))
81 return false;
82
80 OSDMap request = new OSDMap(); 83 OSDMap request = new OSDMap();
81 request.Add("jsonrpc", OSD.FromString("2.0")); 84 request.Add("jsonrpc", OSD.FromString("2.0"));
82 request.Add("id", OSD.FromString(jsonId)); 85 request.Add("id", OSD.FromString(jsonId));
@@ -185,6 +188,6 @@ namespace OpenSim.Framework.Servers.HttpServer
185 188
186 return true; 189 return true;
187 } 190 }
188 191
189 } 192 }
190} 193}
diff --git a/OpenSim/Framework/Servers/HttpServer/JsonRpcResponse.cs b/OpenSim/Framework/Servers/HttpServer/JsonRpcResponse.cs
index 2c50587..91d284b 100644
--- a/OpenSim/Framework/Servers/HttpServer/JsonRpcResponse.cs
+++ b/OpenSim/Framework/Servers/HttpServer/JsonRpcResponse.cs
@@ -144,7 +144,7 @@ namespace OpenSim.Framework.Servers.HttpServer
144 { 144 {
145 145
146 } 146 }
147 return result; 147 return result;
148 } 148 }
149 } 149 }
150} 150}
diff --git a/OpenSim/Framework/Servers/HttpServer/OSHttpRequest.cs b/OpenSim/Framework/Servers/HttpServer/OSHttpRequest.cs
index 05ec6dc..1a6b8cf 100644
--- a/OpenSim/Framework/Servers/HttpServer/OSHttpRequest.cs
+++ b/OpenSim/Framework/Servers/HttpServer/OSHttpRequest.cs
@@ -155,11 +155,11 @@ namespace OpenSim.Framework.Servers.HttpServer
155 private string _userAgent; 155 private string _userAgent;
156 156
157 internal IHttpRequest IHttpRequest 157 internal IHttpRequest IHttpRequest
158 { 158 {
159 get { return _request; } 159 get { return _request; }
160 } 160 }
161 161
162 internal IHttpClientContext IHttpClientContext 162 internal IHttpClientContext IHttpClientContext
163 { 163 {
164 get { return _context; } 164 get { return _context; }
165 } 165 }
@@ -192,19 +192,19 @@ namespace OpenSim.Framework.Servers.HttpServer
192 // ignore 192 // ignore
193 } 193 }
194 } 194 }
195 195
196 if (null != req.Headers["content-type"]) 196 if (null != req.Headers["content-type"])
197 _contentType = _request.Headers["content-type"]; 197 _contentType = _request.Headers["content-type"];
198 if (null != req.Headers["user-agent"]) 198 if (null != req.Headers["user-agent"])
199 _userAgent = req.Headers["user-agent"]; 199 _userAgent = req.Headers["user-agent"];
200 200
201 if (null != req.Headers["remote_addr"]) 201 if (null != req.Headers["remote_addr"])
202 { 202 {
203 try 203 try
204 { 204 {
205 IPAddress addr = IPAddress.Parse(req.Headers["remote_addr"]); 205 IPAddress addr = IPAddress.Parse(req.Headers["remote_addr"]);
206 // sometimes req.Headers["remote_port"] returns a comma separated list, so use 206 // sometimes req.Headers["remote_port"] returns a comma separated list, so use
207 // the first one in the list and log it 207 // the first one in the list and log it
208 string[] strPorts = req.Headers["remote_port"].Split(new char[] { ',' }); 208 string[] strPorts = req.Headers["remote_port"].Split(new char[] { ',' });
209 if (strPorts.Length > 1) 209 if (strPorts.Length > 1)
210 { 210 {
@@ -216,7 +216,7 @@ namespace OpenSim.Framework.Servers.HttpServer
216 } 216 }
217 catch (FormatException) 217 catch (FormatException)
218 { 218 {
219 _log.ErrorFormat("[OSHttpRequest]: format exception on addr/port {0}:{1}, ignoring", 219 _log.ErrorFormat("[OSHttpRequest]: format exception on addr/port {0}:{1}, ignoring",
220 req.Headers["remote_addr"], req.Headers["remote_port"]); 220 req.Headers["remote_addr"], req.Headers["remote_port"]);
221 } 221 }
222 } 222 }
diff --git a/OpenSim/Framework/Servers/HttpServer/OSHttpResponse.cs b/OpenSim/Framework/Servers/HttpServer/OSHttpResponse.cs
index 89fb5d4..d7744fc 100644
--- a/OpenSim/Framework/Servers/HttpServer/OSHttpResponse.cs
+++ b/OpenSim/Framework/Servers/HttpServer/OSHttpResponse.cs
@@ -115,7 +115,7 @@ namespace OpenSim.Framework.Servers.HttpServer
115 115
116 public bool KeepAlive 116 public bool KeepAlive
117 { 117 {
118 get 118 get
119 { 119 {
120 return _httpResponse.Connection == ConnectionType.KeepAlive; 120 return _httpResponse.Connection == ConnectionType.KeepAlive;
121 } 121 }
@@ -148,6 +148,7 @@ namespace OpenSim.Framework.Servers.HttpServer
148 _httpResponse.Connection = ConnectionType.Close; 148 _httpResponse.Connection = ConnectionType.Close;
149 _httpResponse.KeepAlive = 0; 149 _httpResponse.KeepAlive = 0;
150 } 150 }
151
151 else 152 else
152 { 153 {
153 _httpResponse.Connection = ConnectionType.KeepAlive; 154 _httpResponse.Connection = ConnectionType.KeepAlive;
@@ -320,6 +321,7 @@ namespace OpenSim.Framework.Servers.HttpServer
320 public void Send() 321 public void Send()
321 { 322 {
322 _httpResponse.Body.Flush(); 323 _httpResponse.Body.Flush();
324
323 _httpResponse.Send(); 325 _httpResponse.Send();
324 } 326 }
325 327
diff --git a/OpenSim/Framework/Servers/HttpServer/OSHttpStatusCodes.cs b/OpenSim/Framework/Servers/HttpServer/OSHttpStatusCodes.cs
index a736c8b..88e3068 100644
--- a/OpenSim/Framework/Servers/HttpServer/OSHttpStatusCodes.cs
+++ b/OpenSim/Framework/Servers/HttpServer/OSHttpStatusCodes.cs
@@ -91,7 +91,7 @@ namespace OpenSim.Framework.Servers.HttpServer
91 /// 300 Redirect: different presentation forms available, take a pick 91 /// 300 Redirect: different presentation forms available, take a pick
92 /// </summary> 92 /// </summary>
93 RedirectMultipleChoices = 300, 93 RedirectMultipleChoices = 300,
94 94
95 /// <summary> 95 /// <summary>
96 /// 301 Redirect: requested resource has moved and now lives somewhere else 96 /// 301 Redirect: requested resource has moved and now lives somewhere else
97 /// </summary> 97 /// </summary>
diff --git a/OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs b/OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs
index 9477100..7150aad 100644
--- a/OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs
+++ b/OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs
@@ -46,13 +46,15 @@ namespace OpenSim.Framework.Servers.HttpServer
46 public RequestMethod Request; 46 public RequestMethod Request;
47 public UUID Id; 47 public UUID Id;
48 public int TimeOutms; 48 public int TimeOutms;
49 public EventType Type; 49 public EventType Type;
50 50
51 public enum EventType : int 51 public enum EventType : int
52 { 52 {
53 LongPoll = 0, 53 Poll = 0,
54 LslHttp = 1, 54 LslHttp = 1,
55 Inventory = 2 55 Inventory = 2,
56 Texture = 3,
57 Mesh = 4
56 } 58 }
57 59
58 public string Url { get; set; } 60 public string Url { get; set; }
@@ -80,7 +82,7 @@ namespace OpenSim.Framework.Servers.HttpServer
80 NoEvents = pNoEvents; 82 NoEvents = pNoEvents;
81 Id = pId; 83 Id = pId;
82 TimeOutms = pTimeOutms; 84 TimeOutms = pTimeOutms;
83 Type = EventType.LongPoll; 85 Type = EventType.Poll;
84 } 86 }
85 } 87 }
86} 88}
diff --git a/OpenSim/Framework/Servers/HttpServer/PollServiceHttpRequest.cs b/OpenSim/Framework/Servers/HttpServer/PollServiceHttpRequest.cs
index caf0e98..fefcb20 100644
--- a/OpenSim/Framework/Servers/HttpServer/PollServiceHttpRequest.cs
+++ b/OpenSim/Framework/Servers/HttpServer/PollServiceHttpRequest.cs
@@ -27,6 +27,7 @@
27 27
28using System; 28using System;
29using System.Collections; 29using System.Collections;
30using System.Collections.Generic;
30using System.Reflection; 31using System.Reflection;
31using System.Text; 32using System.Text;
32using HttpServer; 33using HttpServer;
@@ -44,6 +45,24 @@ namespace OpenSim.Framework.Servers.HttpServer
44 public readonly IHttpRequest Request; 45 public readonly IHttpRequest Request;
45 public readonly int RequestTime; 46 public readonly int RequestTime;
46 public readonly UUID RequestID; 47 public readonly UUID RequestID;
48 public int contextHash;
49
50 private void GenContextHash()
51 {
52 Random rnd = new Random();
53 contextHash = 0;
54 if (Request.Headers["remote_addr"] != null)
55 contextHash = (Request.Headers["remote_addr"]).GetHashCode() << 16;
56 else
57 contextHash = rnd.Next() << 16;
58 if (Request.Headers["remote_port"] != null)
59 {
60 string[] strPorts = Request.Headers["remote_port"].Split(new char[] { ',' });
61 contextHash += Int32.Parse(strPorts[0]);
62 }
63 else
64 contextHash += rnd.Next() & 0xffff;
65 }
47 66
48 public PollServiceHttpRequest( 67 public PollServiceHttpRequest(
49 PollServiceEventArgs pPollServiceArgs, IHttpClientContext pHttpContext, IHttpRequest pRequest) 68 PollServiceEventArgs pPollServiceArgs, IHttpClientContext pHttpContext, IHttpRequest pRequest)
@@ -53,6 +72,7 @@ namespace OpenSim.Framework.Servers.HttpServer
53 Request = pRequest; 72 Request = pRequest;
54 RequestTime = System.Environment.TickCount; 73 RequestTime = System.Environment.TickCount;
55 RequestID = UUID.Random(); 74 RequestID = UUID.Random();
75 GenContextHash();
56 } 76 }
57 77
58 internal void DoHTTPGruntWork(BaseHttpServer server, Hashtable responsedata) 78 internal void DoHTTPGruntWork(BaseHttpServer server, Hashtable responsedata)
@@ -62,36 +82,69 @@ namespace OpenSim.Framework.Servers.HttpServer
62 82
63 byte[] buffer = server.DoHTTPGruntWork(responsedata, response); 83 byte[] buffer = server.DoHTTPGruntWork(responsedata, response);
64 84
85 if(Request.Body.CanRead)
86 Request.Body.Dispose();
87
65 response.SendChunked = false; 88 response.SendChunked = false;
66 response.ContentLength64 = buffer.Length; 89 response.ContentLength64 = buffer.Length;
67 response.ContentEncoding = Encoding.UTF8; 90 response.ContentEncoding = Encoding.UTF8;
91 response.ReuseContext = false;
68 92
69 try 93 try
70 { 94 {
71 response.OutputStream.Write(buffer, 0, buffer.Length); 95 response.OutputStream.Write(buffer, 0, buffer.Length);
96 response.OutputStream.Flush();
97 response.Send();
98 buffer = null;
72 } 99 }
73 catch (Exception ex) 100 catch (Exception ex)
74 { 101 {
75 m_log.Warn("[POLL SERVICE WORKER THREAD]: Error ", ex); 102 m_log.Warn("[POLL SERVICE WORKER THREAD]: Error ", ex);
76 } 103 }
77 finally 104
105 PollServiceArgs.RequestsHandled++;
106 }
107
108 internal void DoHTTPstop(BaseHttpServer server)
109 {
110 OSHttpResponse response
111 = new OSHttpResponse(new HttpResponse(HttpContext, Request), HttpContext);
112
113 if(Request.Body.CanRead)
114 Request.Body.Dispose();
115
116 response.SendChunked = false;
117 response.ContentLength64 = 0;
118 response.ContentEncoding = Encoding.UTF8;
119 response.ReuseContext = false;
120 response.KeepAlive = false;
121 response.SendChunked = false;
122 response.StatusCode = 503;
123
124 try
78 { 125 {
79 //response.OutputStream.Close(); 126 response.OutputStream.Flush();
80 try 127 response.Send();
81 {
82 response.OutputStream.Flush();
83 response.Send();
84
85 //if (!response.KeepAlive && response.ReuseContext)
86 // response.FreeContext();
87 }
88 catch (Exception e)
89 {
90 m_log.Warn("[POLL SERVICE WORKER THREAD]: Error ", e);
91 }
92
93 PollServiceArgs.RequestsHandled++;
94 } 128 }
129 catch (Exception e)
130 {
131 }
132 }
133 }
134
135 class PollServiceHttpRequestComparer : IEqualityComparer<PollServiceHttpRequest>
136 {
137 public bool Equals(PollServiceHttpRequest b1, PollServiceHttpRequest b2)
138 {
139 if (b1.contextHash != b2.contextHash)
140 return false;
141 bool b = Object.ReferenceEquals(b1.HttpContext, b2.HttpContext);
142 return b;
143 }
144
145 public int GetHashCode(PollServiceHttpRequest b2)
146 {
147 return (int)b2.contextHash;
95 } 148 }
96 } 149 }
97} \ No newline at end of file 150} \ No newline at end of file
diff --git a/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs b/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs
index 28bba70..c6a3e65 100644
--- a/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs
+++ b/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs
@@ -44,200 +44,183 @@ namespace OpenSim.Framework.Servers.HttpServer
44 { 44 {
45 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 45 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
46 46
47 /// <summary>
48 /// Is the poll service request manager running?
49 /// </summary>
50 /// <remarks>
51 /// Can be running either synchronously or asynchronously
52 /// </remarks>
53 public bool IsRunning { get; private set; }
54
55 /// <summary>
56 /// Is the poll service performing responses asynchronously (with its own threads) or synchronously (via
57 /// external calls)?
58 /// </summary>
59 public bool PerformResponsesAsync { get; private set; }
60
61 /// <summary>
62 /// Number of responses actually processed and sent to viewer (or aborted due to error).
63 /// </summary>
64 public int ResponsesProcessed { get; private set; }
65
66 private readonly BaseHttpServer m_server; 47 private readonly BaseHttpServer m_server;
67 48
49 private Dictionary<PollServiceHttpRequest, Queue<PollServiceHttpRequest>> m_bycontext;
68 private BlockingQueue<PollServiceHttpRequest> m_requests = new BlockingQueue<PollServiceHttpRequest>(); 50 private BlockingQueue<PollServiceHttpRequest> m_requests = new BlockingQueue<PollServiceHttpRequest>();
69 private static List<PollServiceHttpRequest> m_longPollRequests = new List<PollServiceHttpRequest>(); 51 private static Queue<PollServiceHttpRequest> m_retryRequests = new Queue<PollServiceHttpRequest>();
70 52
71 private uint m_WorkerThreadCount = 0; 53 private uint m_WorkerThreadCount = 0;
72 private Thread[] m_workerThreads; 54 private Thread[] m_workerThreads;
55 private Thread m_retrysThread;
73 56
74 private SmartThreadPool m_threadPool = new SmartThreadPool(20000, 12, 2); 57 private bool m_running = false;
75 58
76// private int m_timeout = 1000; // increase timeout 250; now use the event one 59 private SmartThreadPool m_threadPool;
77 60
78 public PollServiceRequestManager( 61 public PollServiceRequestManager(
79 BaseHttpServer pSrv, bool performResponsesAsync, uint pWorkerThreadCount, int pTimeout) 62 BaseHttpServer pSrv, bool performResponsesAsync, uint pWorkerThreadCount, int pTimeout)
80 { 63 {
81 m_server = pSrv; 64 m_server = pSrv;
82 PerformResponsesAsync = performResponsesAsync;
83 m_WorkerThreadCount = pWorkerThreadCount; 65 m_WorkerThreadCount = pWorkerThreadCount;
84 m_workerThreads = new Thread[m_WorkerThreadCount]; 66 m_workerThreads = new Thread[m_WorkerThreadCount];
85 67
86 StatsManager.RegisterStat( 68 PollServiceHttpRequestComparer preqCp = new PollServiceHttpRequestComparer();
87 new Stat( 69 m_bycontext = new Dictionary<PollServiceHttpRequest, Queue<PollServiceHttpRequest>>(preqCp);
88 "QueuedPollResponses", 70
89 "Number of poll responses queued for processing.", 71 STPStartInfo startInfo = new STPStartInfo();
90 "", 72 startInfo.IdleTimeout = 30000;
91 "", 73 startInfo.MaxWorkerThreads = 20;
92 "httpserver", 74 startInfo.MinWorkerThreads = 1;
93 m_server.Port.ToString(), 75 startInfo.ThreadPriority = ThreadPriority.Normal;
94 StatType.Pull, 76 startInfo.StartSuspended = true;
95 MeasuresOfInterest.AverageChangeOverTime, 77 startInfo.ThreadPoolName = "PoolService";
96 stat => stat.Value = m_requests.Count(), 78
97 StatVerbosity.Debug)); 79 m_threadPool = new SmartThreadPool(startInfo);
98
99 StatsManager.RegisterStat(
100 new Stat(
101 "ProcessedPollResponses",
102 "Number of poll responses processed.",
103 "",
104 "",
105 "httpserver",
106 m_server.Port.ToString(),
107 StatType.Pull,
108 MeasuresOfInterest.AverageChangeOverTime,
109 stat => stat.Value = ResponsesProcessed,
110 StatVerbosity.Debug));
111 } 80 }
112 81
113 public void Start() 82 public void Start()
114 { 83 {
115 IsRunning = true; 84 m_running = true;
116 85 m_threadPool.Start();
117 if (PerformResponsesAsync) 86 //startup worker threads
87 for (uint i = 0; i < m_WorkerThreadCount; i++)
118 { 88 {
119 //startup worker threads 89 m_workerThreads[i]
120 for (uint i = 0; i < m_WorkerThreadCount; i++) 90 = WorkManager.StartThread(
121 { 91 PoolWorkerJob,
122 m_workerThreads[i] 92 string.Format("PollServiceWorkerThread {0}:{1}", i, m_server.Port),
123 = WorkManager.StartThread( 93 ThreadPriority.Normal,
124 PoolWorkerJob, 94 true,
125 string.Format("PollServiceWorkerThread{0}:{1}", i, m_server.Port), 95 false,
126 ThreadPriority.Normal, 96 null,
127 false, 97 int.MaxValue);
128 false,
129 null,
130 int.MaxValue);
131 }
132
133 WorkManager.StartThread(
134 this.CheckLongPollThreads,
135 string.Format("LongPollServiceWatcherThread:{0}", m_server.Port),
136 ThreadPriority.Normal,
137 false,
138 true,
139 null,
140 1000 * 60 * 10);
141 } 98 }
99
100 m_retrysThread = WorkManager.StartThread(
101 this.CheckRetries,
102 string.Format("PollServiceWatcherThread:{0}", m_server.Port),
103 ThreadPriority.Normal,
104 true,
105 true,
106 null,
107 1000 * 60 * 10);
108
109
142 } 110 }
143 111
144 private void ReQueueEvent(PollServiceHttpRequest req) 112 private void ReQueueEvent(PollServiceHttpRequest req)
145 { 113 {
146 if (IsRunning) 114 if (m_running)
147 { 115 {
148 // delay the enqueueing for 100ms. There's no need to have the event 116 lock (m_retryRequests)
149 // actively on the queue 117 m_retryRequests.Enqueue(req);
150 Timer t = new Timer(self => {
151 ((Timer)self).Dispose();
152 m_requests.Enqueue(req);
153 });
154
155 t.Change(100, Timeout.Infinite);
156
157 } 118 }
158 } 119 }
159 120
160 public void Enqueue(PollServiceHttpRequest req) 121 public void Enqueue(PollServiceHttpRequest req)
161 { 122 {
162 if (IsRunning) 123 lock (m_bycontext)
163 { 124 {
164 if (req.PollServiceArgs.Type == PollServiceEventArgs.EventType.LongPoll) 125 Queue<PollServiceHttpRequest> ctxQeueue;
126 if (m_bycontext.TryGetValue(req, out ctxQeueue))
165 { 127 {
166 lock (m_longPollRequests) 128 ctxQeueue.Enqueue(req);
167 m_longPollRequests.Add(req);
168 } 129 }
169 else 130 else
170 m_requests.Enqueue(req); 131 {
132 ctxQeueue = new Queue<PollServiceHttpRequest>();
133 m_bycontext[req] = ctxQeueue;
134 EnqueueInt(req);
135 }
171 } 136 }
172 } 137 }
173 138
174 private void CheckLongPollThreads() 139 public void byContextDequeue(PollServiceHttpRequest req)
175 { 140 {
176 // The only purpose of this thread is to check the EQs for events. 141 Queue<PollServiceHttpRequest> ctxQeueue;
177 // If there are events, that thread will be placed in the "ready-to-serve" queue, m_requests. 142 lock (m_bycontext)
178 // If there are no events, that thread will be back to its "waiting" queue, m_longPollRequests.
179 // All other types of tasks (Inventory handlers, http-in, etc) don't have the long-poll nature,
180 // so if they aren't ready to be served by a worker thread (no events), they are placed
181 // directly back in the "ready-to-serve" queue by the worker thread.
182 while (IsRunning)
183 { 143 {
184 Thread.Sleep(500); 144 if (m_bycontext.TryGetValue(req, out ctxQeueue))
185 Watchdog.UpdateThread();
186
187// List<PollServiceHttpRequest> not_ready = new List<PollServiceHttpRequest>();
188 lock (m_longPollRequests)
189 { 145 {
190 if (m_longPollRequests.Count > 0 && IsRunning) 146 if (ctxQeueue.Count > 0)
147 {
148 PollServiceHttpRequest newreq = ctxQeueue.Dequeue();
149 EnqueueInt(newreq);
150 }
151 else
191 { 152 {
192 List<PollServiceHttpRequest> ready = m_longPollRequests.FindAll(req => 153 m_bycontext.Remove(req);
193 (req.PollServiceArgs.HasEvents(req.RequestID, req.PollServiceArgs.Id) || // there are events in this EQ 154 }
194 (Environment.TickCount - req.RequestTime) > req.PollServiceArgs.TimeOutms) // no events, but timeout 155 }
195 ); 156 }
157 }
196 158
197 ready.ForEach(req => 159 public void EnqueueInt(PollServiceHttpRequest req)
198 { 160 {
199 m_requests.Enqueue(req); 161 if (m_running)
200 m_longPollRequests.Remove(req); 162 m_requests.Enqueue(req);
201 }); 163 }
202 164
203 } 165 private void CheckRetries()
166 {
167 while (m_running)
204 168
169 {
170 Thread.Sleep(100); // let the world move .. back to faster rate
171 Watchdog.UpdateThread();
172 lock (m_retryRequests)
173 {
174 while (m_retryRequests.Count > 0 && m_running)
175 m_requests.Enqueue(m_retryRequests.Dequeue());
205 } 176 }
206 } 177 }
207 } 178 }
208 179
209 public void Stop() 180 public void Stop()
210 { 181 {
211 IsRunning = false; 182 m_running = false;
212// m_timeout = -10000; // cause all to expire 183
213 Thread.Sleep(1000); // let the world move 184 Thread.Sleep(100); // let the world move
214 185
215 foreach (Thread t in m_workerThreads) 186 foreach (Thread t in m_workerThreads)
216 Watchdog.AbortThread(t.ManagedThreadId); 187 Watchdog.AbortThread(t.ManagedThreadId);
217 188
218 PollServiceHttpRequest wreq; 189 m_threadPool.Shutdown();
190
191 // any entry in m_bycontext should have a active request on the other queues
192 // so just delete contents to easy GC
193 foreach (Queue<PollServiceHttpRequest> qu in m_bycontext.Values)
194 qu.Clear();
195 m_bycontext.Clear();
219 196
220 lock (m_longPollRequests) 197 try
198 {
199 foreach (PollServiceHttpRequest req in m_retryRequests)
200 {
201 req.DoHTTPstop(m_server);
202 }
203 }
204 catch
221 { 205 {
222 if (m_longPollRequests.Count > 0 && IsRunning)
223 m_longPollRequests.ForEach(req => m_requests.Enqueue(req));
224 } 206 }
225 207
208 PollServiceHttpRequest wreq;
209
210 m_retryRequests.Clear();
211
226 while (m_requests.Count() > 0) 212 while (m_requests.Count() > 0)
227 { 213 {
228 try 214 try
229 { 215 {
230 wreq = m_requests.Dequeue(0); 216 wreq = m_requests.Dequeue(0);
231 ResponsesProcessed++; 217 wreq.DoHTTPstop(m_server);
232 wreq.DoHTTPGruntWork(
233 m_server, wreq.PollServiceArgs.NoEvents(wreq.RequestID, wreq.PollServiceArgs.Id));
234 } 218 }
235 catch 219 catch
236 { 220 {
237 } 221 }
238 } 222 }
239 223
240 m_longPollRequests.Clear();
241 m_requests.Clear(); 224 m_requests.Clear();
242 } 225 }
243 226
@@ -245,87 +228,69 @@ namespace OpenSim.Framework.Servers.HttpServer
245 228
246 private void PoolWorkerJob() 229 private void PoolWorkerJob()
247 { 230 {
248 while (IsRunning) 231 while (m_running)
249 { 232 {
233 PollServiceHttpRequest req = m_requests.Dequeue(4500);
250 Watchdog.UpdateThread(); 234 Watchdog.UpdateThread();
251 WaitPerformResponse(); 235 if (req != null)
252 }
253 }
254
255 public void WaitPerformResponse()
256 {
257 PollServiceHttpRequest req = m_requests.Dequeue(5000);
258// m_log.DebugFormat("[YYY]: Dequeued {0}", (req == null ? "null" : req.PollServiceArgs.Type.ToString()));
259
260 if (req != null)
261 {
262 try
263 { 236 {
264 if (req.PollServiceArgs.HasEvents(req.RequestID, req.PollServiceArgs.Id)) 237 try
265 { 238 {
266 Hashtable responsedata = req.PollServiceArgs.GetEvents(req.RequestID, req.PollServiceArgs.Id); 239 if (req.PollServiceArgs.HasEvents(req.RequestID, req.PollServiceArgs.Id))
267
268 if (responsedata == null)
269 return;
270
271 // This is the event queue.
272 // Even if we're not running we can still perform responses by explicit request.
273 if (req.PollServiceArgs.Type == PollServiceEventArgs.EventType.LongPoll
274 || !PerformResponsesAsync)
275 {
276 try
277 {
278 ResponsesProcessed++;
279 req.DoHTTPGruntWork(m_server, responsedata);
280 }
281 catch (ObjectDisposedException e) // Browser aborted before we could read body, server closed the stream
282 {
283 // Ignore it, no need to reply
284 m_log.Error(e);
285 }
286 }
287 else
288 { 240 {
241 Hashtable responsedata = req.PollServiceArgs.GetEvents(req.RequestID, req.PollServiceArgs.Id);
242
289 m_threadPool.QueueWorkItem(x => 243 m_threadPool.QueueWorkItem(x =>
290 { 244 {
291 try 245 try
292 { 246 {
293 ResponsesProcessed++;
294 req.DoHTTPGruntWork(m_server, responsedata); 247 req.DoHTTPGruntWork(m_server, responsedata);
295 } 248 }
296 catch (ObjectDisposedException e) // Browser aborted before we could read body, server closed the stream 249 catch (ObjectDisposedException)
297 { 250 {
298 // Ignore it, no need to reply
299 m_log.Error(e);
300 } 251 }
301 catch (Exception e) 252 finally
302 { 253 {
303 m_log.Error(e); 254 byContextDequeue(req);
304 } 255 }
305
306 return null; 256 return null;
307 }, null); 257 }, null);
308 } 258 }
309 }
310 else
311 {
312 if ((Environment.TickCount - req.RequestTime) > req.PollServiceArgs.TimeOutms)
313 {
314 ResponsesProcessed++;
315 req.DoHTTPGruntWork(
316 m_server, req.PollServiceArgs.NoEvents(req.RequestID, req.PollServiceArgs.Id));
317 }
318 else 259 else
319 { 260 {
320 ReQueueEvent(req); 261 if ((Environment.TickCount - req.RequestTime) > req.PollServiceArgs.TimeOutms)
262 {
263 m_threadPool.QueueWorkItem(x =>
264 {
265 try
266 {
267 req.DoHTTPGruntWork(m_server,
268 req.PollServiceArgs.NoEvents(req.RequestID, req.PollServiceArgs.Id));
269 }
270 catch (ObjectDisposedException)
271 {
272 // Ignore it, no need to reply
273 }
274 finally
275 {
276 byContextDequeue(req);
277 }
278 return null;
279 }, null);
280 }
281 else
282 {
283 ReQueueEvent(req);
284 }
321 } 285 }
322 } 286 }
323 } 287 catch (Exception e)
324 catch (Exception e) 288 {
325 { 289 m_log.ErrorFormat("Exception in poll service thread: " + e.ToString());
326 m_log.ErrorFormat("Exception in poll service thread: " + e.ToString()); 290 }
327 } 291 }
328 } 292 }
329 } 293 }
294
330 } 295 }
331} \ No newline at end of file 296}
diff --git a/OpenSim/Framework/Servers/HttpServer/Properties/AssemblyInfo.cs b/OpenSim/Framework/Servers/HttpServer/Properties/AssemblyInfo.cs
index 5e630dc..9b663ba 100644
--- a/OpenSim/Framework/Servers/HttpServer/Properties/AssemblyInfo.cs
+++ b/OpenSim/Framework/Servers/HttpServer/Properties/AssemblyInfo.cs
@@ -2,7 +2,7 @@
2using System.Runtime.CompilerServices; 2using System.Runtime.CompilerServices;
3using System.Runtime.InteropServices; 3using System.Runtime.InteropServices;
4 4
5// General Information about an assembly is controlled through the following 5// General Information about an assembly is controlled through the following
6// set of attributes. Change these attribute values to modify the information 6// set of attributes. Change these attribute values to modify the information
7// associated with an assembly. 7// associated with an assembly.
8[assembly: AssemblyTitle("OpenSim.Framework.Servers.HttpServer")] 8[assembly: AssemblyTitle("OpenSim.Framework.Servers.HttpServer")]
@@ -14,8 +14,8 @@ using System.Runtime.InteropServices;
14[assembly: AssemblyTrademark("")] 14[assembly: AssemblyTrademark("")]
15[assembly: AssemblyCulture("")] 15[assembly: AssemblyCulture("")]
16 16
17// Setting ComVisible to false makes the types in this assembly not visible 17// Setting ComVisible to false makes the types in this assembly not visible
18// to COM components. If you need to access a type in this assembly from 18// to COM components. If you need to access a type in this assembly from
19// COM, set the ComVisible attribute to true on that type. 19// COM, set the ComVisible attribute to true on that type.
20[assembly: ComVisible(false)] 20[assembly: ComVisible(false)]
21 21
@@ -25,9 +25,9 @@ using System.Runtime.InteropServices;
25// Version information for an assembly consists of the following four values: 25// Version information for an assembly consists of the following four values:
26// 26//
27// Major Version 27// Major Version
28// Minor Version 28// Minor Version
29// Build Number 29// Build Number
30// Revision 30// Revision
31// 31//
32[assembly: AssemblyVersion("0.8.3.*")] 32[assembly: AssemblyVersion(OpenSim.VersionInfo.AssemblyVersionNumber)]
33 33
diff --git a/OpenSim/Framework/Servers/HttpServer/RestDeserialiseHandler.cs b/OpenSim/Framework/Servers/HttpServer/RestDeserialiseHandler.cs
index bd55657..67fc14e 100644
--- a/OpenSim/Framework/Servers/HttpServer/RestDeserialiseHandler.cs
+++ b/OpenSim/Framework/Servers/HttpServer/RestDeserialiseHandler.cs
@@ -54,6 +54,8 @@ namespace OpenSim.Framework.Servers.HttpServer
54 TRequest deserial; 54 TRequest deserial;
55 using (XmlTextReader xmlReader = new XmlTextReader(request)) 55 using (XmlTextReader xmlReader = new XmlTextReader(request))
56 { 56 {
57 xmlReader.ProhibitDtd = true;
58
57 XmlSerializer deserializer = new XmlSerializer(typeof (TRequest)); 59 XmlSerializer deserializer = new XmlSerializer(typeof (TRequest));
58 deserial = (TRequest) deserializer.Deserialize(xmlReader); 60 deserial = (TRequest) deserializer.Deserialize(xmlReader);
59 } 61 }
diff --git a/OpenSim/Framework/Servers/HttpServer/RestSessionService.cs b/OpenSim/Framework/Servers/HttpServer/RestSessionService.cs
index ad69cd2..158befa 100644
--- a/OpenSim/Framework/Servers/HttpServer/RestSessionService.cs
+++ b/OpenSim/Framework/Servers/HttpServer/RestSessionService.cs
@@ -210,6 +210,8 @@ namespace OpenSim.Framework.Servers.HttpServer
210 { 210 {
211 try 211 try
212 { 212 {
213 xmlReader.ProhibitDtd = true;
214
213 XmlSerializer deserializer = new XmlSerializer(typeof(RestSessionObject<TRequest>)); 215 XmlSerializer deserializer = new XmlSerializer(typeof(RestSessionObject<TRequest>));
214 deserial = (RestSessionObject<TRequest>)deserializer.Deserialize(xmlReader); 216 deserial = (RestSessionObject<TRequest>)deserializer.Deserialize(xmlReader);
215 } 217 }
@@ -269,6 +271,8 @@ namespace OpenSim.Framework.Servers.HttpServer
269 { 271 {
270 try 272 try
271 { 273 {
274 xmlReader.ProhibitDtd = true;
275
272 XmlSerializer deserializer = new XmlSerializer(typeof(TRequest)); 276 XmlSerializer deserializer = new XmlSerializer(typeof(TRequest));
273 deserial = (TRequest)deserializer.Deserialize(xmlReader); 277 deserial = (TRequest)deserializer.Deserialize(xmlReader);
274 } 278 }
@@ -291,5 +295,5 @@ namespace OpenSim.Framework.Servers.HttpServer
291 serializer.Serialize(xmlWriter, response); 295 serializer.Serialize(xmlWriter, response);
292 } 296 }
293 } 297 }
294 } 298 }
295} \ No newline at end of file 299} \ No newline at end of file
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/HttpServer/WebsocketServerHandler.cs b/OpenSim/Framework/Servers/HttpServer/WebsocketServerHandler.cs
index c2925e3..c8af90f 100644
--- a/OpenSim/Framework/Servers/HttpServer/WebsocketServerHandler.cs
+++ b/OpenSim/Framework/Servers/HttpServer/WebsocketServerHandler.cs
@@ -75,7 +75,7 @@ namespace OpenSim.Framework.Servers.HttpServer
75 public event PongDelegate OnPong; 75 public event PongDelegate OnPong;
76 76
77 /// <summary> 77 /// <summary>
78 /// This is a regular HTTP Request... This may be removed in the future. 78 /// This is a regular HTTP Request... This may be removed in the future.
79 /// </summary> 79 /// </summary>
80// public event RegularHttpRequestDelegate OnRegularHttpRequest; 80// public event RegularHttpRequestDelegate OnRegularHttpRequest;
81 81
@@ -93,9 +93,9 @@ namespace OpenSim.Framework.Servers.HttpServer
93 /// When the websocket is closed, this will be fired. 93 /// When the websocket is closed, this will be fired.
94 /// </summary> 94 /// </summary>
95 public event CloseDelegate OnClose; 95 public event CloseDelegate OnClose;
96 96
97 /// <summary> 97 /// <summary>
98 /// Set this delegate to allow your module to validate the origin of the 98 /// Set this delegate to allow your module to validate the origin of the
99 /// Websocket request. Primary line of defense against cross site scripting 99 /// Websocket request. Primary line of defense against cross site scripting
100 /// </summary> 100 /// </summary>
101 public ValidateHandshake HandshakeValidateMethodOverride = null; 101 public ValidateHandshake HandshakeValidateMethodOverride = null;
@@ -181,7 +181,7 @@ namespace OpenSim.Framework.Servers.HttpServer
181 { 181 {
182 throw new InvalidOperationException("The socket has been shutdown"); 182 throw new InvalidOperationException("The socket has been shutdown");
183 } 183 }
184 } 184 }
185 set 185 set
186 { 186 {
187 if (_networkContext != null && _networkContext.Socket != null) 187 if (_networkContext != null && _networkContext.Socket != null)
@@ -194,8 +194,8 @@ namespace OpenSim.Framework.Servers.HttpServer
194 } 194 }
195 195
196 /// <summary> 196 /// <summary>
197 /// This triggers the websocket to start the upgrade process... 197 /// This triggers the websocket to start the upgrade process...
198 /// This is a Generalized Networking 'common sense' helper method. Some people expect to call Start() instead 198 /// This is a Generalized Networking 'common sense' helper method. Some people expect to call Start() instead
199 /// of the more context appropriate HandshakeAndUpgrade() 199 /// of the more context appropriate HandshakeAndUpgrade()
200 /// </summary> 200 /// </summary>
201 public void Start() 201 public void Start()
@@ -261,7 +261,7 @@ namespace OpenSim.Framework.Servers.HttpServer
261 acceptKey = GenerateAcceptKey(websocketKey); 261 acceptKey = GenerateAcceptKey(websocketKey);
262 string rawaccept = string.Format(HandshakeAcceptText, acceptKey); 262 string rawaccept = string.Format(HandshakeAcceptText, acceptKey);
263 SendUpgradeSuccess(rawaccept); 263 SendUpgradeSuccess(rawaccept);
264 264
265 265
266 } 266 }
267 else 267 else
@@ -282,7 +282,7 @@ namespace OpenSim.Framework.Servers.HttpServer
282 } 282 }
283 283
284 /// <summary> 284 /// <summary>
285 /// Generates a handshake response key string based on the client's 285 /// Generates a handshake response key string based on the client's
286 /// provided key to prove to the client that we're allowing the Websocket 286 /// provided key to prove to the client that we're allowing the Websocket
287 /// upgrade of our own free will and we were not coerced into doing it. 287 /// upgrade of our own free will and we were not coerced into doing it.
288 /// </summary> 288 /// </summary>
@@ -298,7 +298,7 @@ namespace OpenSim.Framework.Servers.HttpServer
298 SHA1 hashobj = SHA1.Create(); 298 SHA1 hashobj = SHA1.Create();
299 string ret = Convert.ToBase64String(hashobj.ComputeHash(Encoding.UTF8.GetBytes(acceptkey))); 299 string ret = Convert.ToBase64String(hashobj.ComputeHash(Encoding.UTF8.GetBytes(acceptkey)));
300 hashobj.Clear(); 300 hashobj.Clear();
301 301
302 return ret; 302 return ret;
303 } 303 }
304 304
@@ -310,11 +310,11 @@ namespace OpenSim.Framework.Servers.HttpServer
310 { 310 {
311 // Create a new websocket state so we can keep track of data in between network reads. 311 // Create a new websocket state so we can keep track of data in between network reads.
312 WebSocketState socketState = new WebSocketState() { ReceivedBytes = new List<byte>(), Header = WebsocketFrameHeader.HeaderDefault(), FrameComplete = true}; 312 WebSocketState socketState = new WebSocketState() { ReceivedBytes = new List<byte>(), Header = WebsocketFrameHeader.HeaderDefault(), FrameComplete = true};
313 313
314 byte[] bhandshakeResponse = Encoding.UTF8.GetBytes(pHandshakeResponse); 314 byte[] bhandshakeResponse = Encoding.UTF8.GetBytes(pHandshakeResponse);
315 315
316 316
317 317
318 318
319 try 319 try
320 { 320 {
@@ -324,7 +324,7 @@ namespace OpenSim.Framework.Servers.HttpServer
324 } 324 }
325 // Begin reading the TCP stream before writing the Upgrade success message to the other side of the stream. 325 // Begin reading the TCP stream before writing the Upgrade success message to the other side of the stream.
326 _networkContext.Stream.BeginRead(_buffer, 0, _bufferLength, OnReceive, socketState); 326 _networkContext.Stream.BeginRead(_buffer, 0, _bufferLength, OnReceive, socketState);
327 327
328 // Write the upgrade handshake success message 328 // Write the upgrade handshake success message
329 _networkContext.Stream.Write(bhandshakeResponse, 0, bhandshakeResponse.Length); 329 _networkContext.Stream.Write(bhandshakeResponse, 0, bhandshakeResponse.Length);
330 _networkContext.Stream.Flush(); 330 _networkContext.Stream.Flush();
@@ -345,7 +345,7 @@ namespace OpenSim.Framework.Servers.HttpServer
345 catch (ObjectDisposedException) 345 catch (ObjectDisposedException)
346 { 346 {
347 Close(string.Empty); 347 Close(string.Empty);
348 } 348 }
349 } 349 }
350 350
351 /// <summary> 351 /// <summary>
@@ -369,7 +369,7 @@ namespace OpenSim.Framework.Servers.HttpServer
369 369
370 /// <summary> 370 /// <summary>
371 /// This is our ugly Async OnReceive event handler. 371 /// This is our ugly Async OnReceive event handler.
372 /// This chunks the input stream based on the length of the provided buffer and processes out 372 /// This chunks the input stream based on the length of the provided buffer and processes out
373 /// as many frames as it can. It then moves the unprocessed data to the beginning of the buffer. 373 /// as many frames as it can. It then moves the unprocessed data to the beginning of the buffer.
374 /// </summary> 374 /// </summary>
375 /// <param name="ar">Our Async State from beginread</param> 375 /// <param name="ar">Our Async State from beginread</param>
@@ -390,7 +390,7 @@ namespace OpenSim.Framework.Servers.HttpServer
390 390
391 if (_bufferPosition > _bufferLength) 391 if (_bufferPosition > _bufferLength)
392 { 392 {
393 // Message too big for chunksize.. not sure how this happened... 393 // Message too big for chunksize.. not sure how this happened...
394 //Close(string.Empty); 394 //Close(string.Empty);
395 } 395 }
396 396
@@ -413,7 +413,7 @@ namespace OpenSim.Framework.Servers.HttpServer
413 if (pheader.PayloadLen > (ulong) _maxPayloadBytes) 413 if (pheader.PayloadLen > (ulong) _maxPayloadBytes)
414 { 414 {
415 Close("Invalid Payload size"); 415 Close("Invalid Payload size");
416 416
417 return; 417 return;
418 } 418 }
419 if (pheader.PayloadLen > 0) 419 if (pheader.PayloadLen > 0)
@@ -487,7 +487,7 @@ namespace OpenSim.Framework.Servers.HttpServer
487 _socketState.ReceivedBytes.Clear(); 487 _socketState.ReceivedBytes.Clear();
488 _socketState.ExpectedBytes = 0; 488 _socketState.ExpectedBytes = 0;
489 // do some processing 489 // do some processing
490 } 490 }
491 } 491 }
492 } 492 }
493 if (offset > 0) 493 if (offset > 0)
@@ -504,7 +504,7 @@ namespace OpenSim.Framework.Servers.HttpServer
504 } 504 }
505 else 505 else
506 { 506 {
507 // We can't read the stream anymore... 507 // We can't read the stream anymore...
508 } 508 }
509 } 509 }
510 catch (IOException) 510 catch (IOException)
@@ -533,7 +533,7 @@ namespace OpenSim.Framework.Servers.HttpServer
533 textMessageFrame.Header.Opcode = WebSocketReader.OpCode.Text; 533 textMessageFrame.Header.Opcode = WebSocketReader.OpCode.Text;
534 textMessageFrame.Header.IsEnd = true; 534 textMessageFrame.Header.IsEnd = true;
535 SendSocket(textMessageFrame.ToBytes()); 535 SendSocket(textMessageFrame.ToBytes());
536 536
537 } 537 }
538 538
539 public void SendData(byte[] data) 539 public void SendData(byte[] data)
@@ -657,7 +657,7 @@ namespace OpenSim.Framework.Servers.HttpServer
657 SendSocket(pongFrame.ToBytes()); 657 SendSocket(pongFrame.ToBytes());
658 break; 658 break;
659 case WebSocketReader.OpCode.Pong: 659 case WebSocketReader.OpCode.Pong:
660 660
661 PongDelegate pongD = OnPong; 661 PongDelegate pongD = OnPong;
662 if (pongD != null) 662 if (pongD != null)
663 { 663 {
@@ -701,7 +701,7 @@ namespace OpenSim.Framework.Servers.HttpServer
701 { 701 {
702 textD(this, new WebsocketTextEventArgs() { Data = Encoding.UTF8.GetString(psocketState.ReceivedBytes.ToArray()) }); 702 textD(this, new WebsocketTextEventArgs() { Data = Encoding.UTF8.GetString(psocketState.ReceivedBytes.ToArray()) });
703 } 703 }
704 704
705 // Send Done Event! 705 // Send Done Event!
706 } 706 }
707 break; 707 break;
@@ -719,7 +719,7 @@ namespace OpenSim.Framework.Servers.HttpServer
719 { 719 {
720 if (psocketState.ContinuationFrame.Header.Opcode == WebSocketReader.OpCode.Text) 720 if (psocketState.ContinuationFrame.Header.Opcode == WebSocketReader.OpCode.Text)
721 { 721 {
722 // Send Done event 722 // Send Done event
723 TextDelegate textD = OnText; 723 TextDelegate textD = OnText;
724 if (textD != null) 724 if (textD != null)
725 { 725 {
@@ -744,9 +744,9 @@ namespace OpenSim.Framework.Servers.HttpServer
744 break; 744 break;
745 case WebSocketReader.OpCode.Close: 745 case WebSocketReader.OpCode.Close:
746 Close(string.Empty); 746 Close(string.Empty);
747 747
748 break; 748 break;
749 749
750 } 750 }
751 psocketState.Header.SetDefault(); 751 psocketState.Header.SetDefault();
752 psocketState.ReceivedBytes.Clear(); 752 psocketState.ReceivedBytes.Clear();
@@ -837,12 +837,12 @@ namespace OpenSim.Framework.Servers.HttpServer
837 } 837 }
838 838
839 /// <summary> 839 /// <summary>
840 /// Attempts to read a header off the provided buffer. Returns true, exports a WebSocketFrameheader, 840 /// Attempts to read a header off the provided buffer. Returns true, exports a WebSocketFrameheader,
841 /// and an int to move the buffer forward when it reads a header. False when it can't read a header 841 /// and an int to move the buffer forward when it reads a header. False when it can't read a header
842 /// </summary> 842 /// </summary>
843 /// <param name="pBuffer">Bytes read from the stream</param> 843 /// <param name="pBuffer">Bytes read from the stream</param>
844 /// <param name="pOffset">Starting place in the stream to begin trying to read from</param> 844 /// <param name="pOffset">Starting place in the stream to begin trying to read from</param>
845 /// <param name="length">Lenth in the stream to try and read from. Provided for cases where the 845 /// <param name="length">Lenth in the stream to try and read from. Provided for cases where the
846 /// buffer's length is larger then the data in it</param> 846 /// buffer's length is larger then the data in it</param>
847 /// <param name="oHeader">Outputs the read WebSocket frame header</param> 847 /// <param name="oHeader">Outputs the read WebSocket frame header</param>
848 /// <param name="moveBuffer">Informs the calling stream to move the buffer forward</param> 848 /// <param name="moveBuffer">Informs the calling stream to move the buffer forward</param>
@@ -897,7 +897,7 @@ namespace OpenSim.Framework.Servers.HttpServer
897 oHeader.PayloadLen = BitConverter.ToUInt16(pBuffer, pOffset + index); 897 oHeader.PayloadLen = BitConverter.ToUInt16(pBuffer, pOffset + index);
898 index += 2; 898 index += 2;
899 break; 899 break;
900 case 127: // we got more this is a bigger frame 900 case 127: // we got more this is a bigger frame
901 // 8 bytes - uint64 - most significant bit 0 network byte order 901 // 8 bytes - uint64 - most significant bit 0 network byte order
902 minumheadersize += 8; 902 minumheadersize += 8;
903 if (length < minumheadersize) 903 if (length < minumheadersize)
@@ -909,7 +909,7 @@ namespace OpenSim.Framework.Servers.HttpServer
909 oHeader.PayloadLen = BitConverter.ToUInt64(pBuffer, pOffset + index); 909 oHeader.PayloadLen = BitConverter.ToUInt64(pBuffer, pOffset + index);
910 index += 8; 910 index += 8;
911 break; 911 break;
912 912
913 } 913 }
914 //oHeader.PayloadLeft = oHeader.PayloadLen; // Start the count in case it's chunked over the network. This is different then frame fragmentation 914 //oHeader.PayloadLeft = oHeader.PayloadLen; // Start the count in case it's chunked over the network. This is different then frame fragmentation
915 if (oHeader.IsMasked) 915 if (oHeader.IsMasked)
@@ -937,9 +937,9 @@ namespace OpenSim.Framework.Servers.HttpServer
937 /* 937 /*
938 * RFC6455 938 * RFC6455
939nib 0 1 2 3 4 5 6 7 939nib 0 1 2 3 4 5 6 7
940byt 0 1 2 3 940byt 0 1 2 3
941dec 0 1 2 3 941dec 0 1 2 3
942 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 942 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
943 +-+-+-+-+-------+-+-------------+-------------------------------+ 943 +-+-+-+-+-------+-+-------------+-------------------------------+
944 |F|R|R|R| opcode|M| Payload len | Extended payload length | 944 |F|R|R|R| opcode|M| Payload len | Extended payload length |
945 |I|S|S|S| (4) |A| (7) | (16/64) + 945 |I|S|S|S| (4) |A| (7) | (16/64) +
@@ -963,7 +963,7 @@ dec 0 1 2 3
963 public static readonly WebSocketFrame DefaultFrame = new WebSocketFrame(){Header = new WebsocketFrameHeader(),WebSocketPayload = new byte[0]}; 963 public static readonly WebSocketFrame DefaultFrame = new WebSocketFrame(){Header = new WebsocketFrameHeader(),WebSocketPayload = new byte[0]};
964 public WebsocketFrameHeader Header; 964 public WebsocketFrameHeader Header;
965 public byte[] WebSocketPayload; 965 public byte[] WebSocketPayload;
966 966
967 public byte[] ToBytes() 967 public byte[] ToBytes()
968 { 968 {
969 Header.PayloadLen = (ulong)WebSocketPayload.Length; 969 Header.PayloadLen = (ulong)WebSocketPayload.Length;
@@ -991,7 +991,7 @@ dec 0 1 2 3
991 public int Mask; 991 public int Mask;
992 /* 992 /*
993byt 0 1 2 3 993byt 0 1 2 3
994 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 994 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
995 +---------------+---------------+---------------+---------------+ 995 +---------------+---------------+---------------+---------------+
996 | Octal 1 | Octal 2 | Octal 3 | Octal 4 | 996 | Octal 1 | Octal 2 | Octal 3 | Octal 4 |
997 +---------------+---------------+---------------+---------------+ 997 +---------------+---------------+---------------+---------------+
@@ -1002,11 +1002,11 @@ byt 0 1 2 3
1002 1002
1003 public UInt64 PayloadLen; 1003 public UInt64 PayloadLen;
1004 //public UInt64 PayloadLeft; 1004 //public UInt64 PayloadLeft;
1005 // Payload is X + Y 1005 // Payload is X + Y
1006 //public UInt64 ExtensionDataLength; 1006 //public UInt64 ExtensionDataLength;
1007 //public UInt64 ApplicationDataLength; 1007 //public UInt64 ApplicationDataLength;
1008 public static readonly WebsocketFrameHeader ZeroHeader = WebsocketFrameHeader.HeaderDefault(); 1008 public static readonly WebsocketFrameHeader ZeroHeader = WebsocketFrameHeader.HeaderDefault();
1009 1009
1010 public void SetDefault() 1010 public void SetDefault()
1011 { 1011 {
1012 1012
@@ -1025,16 +1025,16 @@ byt 0 1 2 3
1025 /// <summary> 1025 /// <summary>
1026 /// Returns a byte array representing the Frame header 1026 /// Returns a byte array representing the Frame header
1027 /// </summary> 1027 /// </summary>
1028 /// <param name="payload">This is the frame data payload. The header describes the size of the payload. 1028 /// <param name="payload">This is the frame data payload. The header describes the size of the payload.
1029 /// If payload is null, a Zero sized payload is assumed</param> 1029 /// If payload is null, a Zero sized payload is assumed</param>
1030 /// <returns>Returns a byte array representing the frame header</returns> 1030 /// <returns>Returns a byte array representing the frame header</returns>
1031 public byte[] ToBytes(byte[] payload) 1031 public byte[] ToBytes(byte[] payload)
1032 { 1032 {
1033 List<byte> result = new List<byte>(); 1033 List<byte> result = new List<byte>();
1034 1034
1035 // Squeeze in our opcode and our ending bit. 1035 // Squeeze in our opcode and our ending bit.
1036 result.Add((byte)((byte)Opcode | (IsEnd?0x80:0x00) )); 1036 result.Add((byte)((byte)Opcode | (IsEnd?0x80:0x00) ));
1037 1037
1038 // Again with the three different byte interpretations of size.. 1038 // Again with the three different byte interpretations of size..
1039 1039
1040 //bytesize 1040 //bytesize
@@ -1056,7 +1056,7 @@ byt 0 1 2 3
1056 Array.Reverse(payloadLengthByte); 1056 Array.Reverse(payloadLengthByte);
1057 result.AddRange(payloadLengthByte); 1057 result.AddRange(payloadLengthByte);
1058 } 1058 }
1059 1059
1060 // Only add a payload if it's not null 1060 // Only add a payload if it's not null
1061 if (payload != null) 1061 if (payload != null)
1062 { 1062 {
@@ -1155,5 +1155,5 @@ byt 0 1 2 3
1155 1155
1156 } 1156 }
1157 1157
1158 1158
1159} 1159}
diff --git a/OpenSim/Framework/Servers/HttpServer/XmlRpcBasicDOSProtector.cs b/OpenSim/Framework/Servers/HttpServer/XmlRpcBasicDOSProtector.cs
index f212208..6b2c0ab 100644
--- a/OpenSim/Framework/Servers/HttpServer/XmlRpcBasicDOSProtector.cs
+++ b/OpenSim/Framework/Servers/HttpServer/XmlRpcBasicDOSProtector.cs
@@ -36,7 +36,7 @@ namespace OpenSim.Framework.Servers.HttpServer
36 { 36 {
37 private readonly XmlRpcMethod _normalMethod; 37 private readonly XmlRpcMethod _normalMethod;
38 private readonly XmlRpcMethod _throttledMethod; 38 private readonly XmlRpcMethod _throttledMethod;
39 39
40 private readonly BasicDosProtectorOptions _options; 40 private readonly BasicDosProtectorOptions _options;
41 private readonly BasicDOSProtector _dosProtector; 41 private readonly BasicDOSProtector _dosProtector;
42 42
@@ -44,7 +44,7 @@ namespace OpenSim.Framework.Servers.HttpServer
44 { 44 {
45 _normalMethod = normalMethod; 45 _normalMethod = normalMethod;
46 _throttledMethod = throttledMethod; 46 _throttledMethod = throttledMethod;
47 47
48 _options = options; 48 _options = options;
49 _dosProtector = new BasicDOSProtector(_options); 49 _dosProtector = new BasicDOSProtector(_options);
50 50
@@ -87,5 +87,5 @@ namespace OpenSim.Framework.Servers.HttpServer
87 87
88 } 88 }
89 89
90 90
91} 91}
diff --git a/OpenSim/Framework/Servers/MainServer.cs b/OpenSim/Framework/Servers/MainServer.cs
index 57931d4..9b1d906 100644
--- a/OpenSim/Framework/Servers/MainServer.cs
+++ b/OpenSim/Framework/Servers/MainServer.cs
@@ -223,11 +223,11 @@ namespace OpenSim.Framework.Servers
223 { 223 {
224 handlers.AppendFormat( 224 handlers.AppendFormat(
225 "Registered HTTP Handlers for server at {0}:{1}\n", httpServer.ListenIPAddress, httpServer.Port); 225 "Registered HTTP Handlers for server at {0}:{1}\n", httpServer.ListenIPAddress, httpServer.Port);
226 226
227 handlers.AppendFormat("* XMLRPC:\n"); 227 handlers.AppendFormat("* XMLRPC:\n");
228 foreach (String s in httpServer.GetXmlRpcHandlerKeys()) 228 foreach (String s in httpServer.GetXmlRpcHandlerKeys())
229 handlers.AppendFormat("\t{0}\n", s); 229 handlers.AppendFormat("\t{0}\n", s);
230 230
231 handlers.AppendFormat("* HTTP:\n"); 231 handlers.AppendFormat("* HTTP:\n");
232 foreach (String s in httpServer.GetHTTPHandlerKeys()) 232 foreach (String s in httpServer.GetHTTPHandlerKeys())
233 handlers.AppendFormat("\t{0}\n", s); 233 handlers.AppendFormat("\t{0}\n", s);
@@ -235,19 +235,19 @@ namespace OpenSim.Framework.Servers
235 handlers.AppendFormat("* HTTP (poll):\n"); 235 handlers.AppendFormat("* HTTP (poll):\n");
236 foreach (String s in httpServer.GetPollServiceHandlerKeys()) 236 foreach (String s in httpServer.GetPollServiceHandlerKeys())
237 handlers.AppendFormat("\t{0}\n", s); 237 handlers.AppendFormat("\t{0}\n", s);
238 238
239 handlers.AppendFormat("* JSONRPC:\n"); 239 handlers.AppendFormat("* JSONRPC:\n");
240 foreach (String s in httpServer.GetJsonRpcHandlerKeys()) 240 foreach (String s in httpServer.GetJsonRpcHandlerKeys())
241 handlers.AppendFormat("\t{0}\n", s); 241 handlers.AppendFormat("\t{0}\n", s);
242 242
243// handlers.AppendFormat("* Agent:\n"); 243// handlers.AppendFormat("* Agent:\n");
244// foreach (String s in httpServer.GetAgentHandlerKeys()) 244// foreach (String s in httpServer.GetAgentHandlerKeys())
245// handlers.AppendFormat("\t{0}\n", s); 245// handlers.AppendFormat("\t{0}\n", s);
246 246
247 handlers.AppendFormat("* LLSD:\n"); 247 handlers.AppendFormat("* LLSD:\n");
248 foreach (String s in httpServer.GetLLSDHandlerKeys()) 248 foreach (String s in httpServer.GetLLSDHandlerKeys())
249 handlers.AppendFormat("\t{0}\n", s); 249 handlers.AppendFormat("\t{0}\n", s);
250 250
251 handlers.AppendFormat("* StreamHandlers ({0}):\n", httpServer.GetStreamHandlerKeys().Count); 251 handlers.AppendFormat("* StreamHandlers ({0}):\n", httpServer.GetStreamHandlerKeys().Count);
252 foreach (String s in httpServer.GetStreamHandlerKeys()) 252 foreach (String s in httpServer.GetStreamHandlerKeys())
253 handlers.AppendFormat("\t{0}\n", s); 253 handlers.AppendFormat("\t{0}\n", s);
@@ -334,7 +334,7 @@ namespace OpenSim.Framework.Servers
334 { 334 {
335 if (port == 0) 335 if (port == 0)
336 return Instance; 336 return Instance;
337 337
338 if (instance != null && port == Instance.Port) 338 if (instance != null && port == Instance.Port)
339 return Instance; 339 return Instance;
340 340
@@ -353,5 +353,17 @@ namespace OpenSim.Framework.Servers
353 return m_Servers[port]; 353 return m_Servers[port];
354 } 354 }
355 } 355 }
356
357 public static void Stop()
358 {
359 lock (m_Servers)
360 {
361 foreach (BaseHttpServer httpServer in m_Servers.Values)
362 {
363 httpServer.Stop();
364 }
365 }
366 }
367
356 } 368 }
357} \ No newline at end of file 369} \ No newline at end of file
diff --git a/OpenSim/Framework/Servers/Properties/AssemblyInfo.cs b/OpenSim/Framework/Servers/Properties/AssemblyInfo.cs
index 792c62e..4469e7c 100644
--- a/OpenSim/Framework/Servers/Properties/AssemblyInfo.cs
+++ b/OpenSim/Framework/Servers/Properties/AssemblyInfo.cs
@@ -2,7 +2,7 @@
2using System.Runtime.CompilerServices; 2using System.Runtime.CompilerServices;
3using System.Runtime.InteropServices; 3using System.Runtime.InteropServices;
4 4
5// General Information about an assembly is controlled through the following 5// General Information about an assembly is controlled through the following
6// set of attributes. Change these attribute values to modify the information 6// set of attributes. Change these attribute values to modify the information
7// associated with an assembly. 7// associated with an assembly.
8[assembly: AssemblyTitle("OpenSim.Framework.Servers")] 8[assembly: AssemblyTitle("OpenSim.Framework.Servers")]
@@ -14,8 +14,8 @@ using System.Runtime.InteropServices;
14[assembly: AssemblyTrademark("")] 14[assembly: AssemblyTrademark("")]
15[assembly: AssemblyCulture("")] 15[assembly: AssemblyCulture("")]
16 16
17// Setting ComVisible to false makes the types in this assembly not visible 17// Setting ComVisible to false makes the types in this assembly not visible
18// to COM components. If you need to access a type in this assembly from 18// to COM components. If you need to access a type in this assembly from
19// COM, set the ComVisible attribute to true on that type. 19// COM, set the ComVisible attribute to true on that type.
20[assembly: ComVisible(false)] 20[assembly: ComVisible(false)]
21 21
@@ -25,7 +25,7 @@ using System.Runtime.InteropServices;
25// Version information for an assembly consists of the following four values: 25// Version information for an assembly consists of the following four values:
26// 26//
27// Major Version 27// Major Version
28// Minor Version 28// Minor Version
29// Build Number 29// Build Number
30// Revision 30// Revision
31// 31//
diff --git a/OpenSim/Framework/Servers/ServerBase.cs b/OpenSim/Framework/Servers/ServerBase.cs
index 07a09e6..3c2dce8 100644
--- a/OpenSim/Framework/Servers/ServerBase.cs
+++ b/OpenSim/Framework/Servers/ServerBase.cs
@@ -56,7 +56,8 @@ namespace OpenSim.Framework.Servers
56 protected ICommandConsole m_console; 56 protected ICommandConsole m_console;
57 57
58 protected OpenSimAppender m_consoleAppender; 58 protected OpenSimAppender m_consoleAppender;
59 protected FileAppender m_logFileAppender; 59 protected FileAppender m_logFileAppender;
60 protected FileAppender m_statsLogFileAppender;
60 61
61 protected DateTime m_startuptime; 62 protected DateTime m_startuptime;
62 protected string m_startupDirectory = Environment.CurrentDirectory; 63 protected string m_startupDirectory = Environment.CurrentDirectory;
@@ -81,7 +82,7 @@ namespace OpenSim.Framework.Servers
81 { 82 {
82 if (File.Exists(path)) 83 if (File.Exists(path))
83 m_log.ErrorFormat( 84 m_log.ErrorFormat(
84 "[SERVER BASE]: Previous pid file {0} still exists on startup. Possibly previously unclean shutdown.", 85 "[SERVER BASE]: Previous pid file {0} still exists on startup. Possibly previously unclean shutdown.",
85 path); 86 path);
86 87
87 try 88 try
@@ -103,7 +104,7 @@ namespace OpenSim.Framework.Servers
103 m_log.Warn(string.Format("[SERVER BASE]: Could not create PID file at {0} ", path), e); 104 m_log.Warn(string.Format("[SERVER BASE]: Could not create PID file at {0} ", path), e);
104 } 105 }
105 } 106 }
106 107
107 protected void RemovePIDFile() 108 protected void RemovePIDFile()
108 { 109 {
109 if (m_pidFile != String.Empty) 110 if (m_pidFile != String.Empty)
@@ -156,6 +157,10 @@ namespace OpenSim.Framework.Servers
156 { 157 {
157 m_logFileAppender = (FileAppender)appender; 158 m_logFileAppender = (FileAppender)appender;
158 } 159 }
160 else if (appender.Name == "StatsLogFileAppender")
161 {
162 m_statsLogFileAppender = (FileAppender)appender;
163 }
159 } 164 }
160 165
161 if (null == m_consoleAppender) 166 if (null == m_consoleAppender)
@@ -166,11 +171,11 @@ namespace OpenSim.Framework.Servers
166 { 171 {
167 // FIXME: This should be done through an interface rather than casting. 172 // FIXME: This should be done through an interface rather than casting.
168 m_consoleAppender.Console = (ConsoleBase)m_console; 173 m_consoleAppender.Console = (ConsoleBase)m_console;
169 174
170 // If there is no threshold set then the threshold is effectively everything. 175 // If there is no threshold set then the threshold is effectively everything.
171 if (null == m_consoleAppender.Threshold) 176 if (null == m_consoleAppender.Threshold)
172 m_consoleAppender.Threshold = Level.All; 177 m_consoleAppender.Threshold = Level.All;
173 178
174 Notice(String.Format("Console log level is {0}", m_consoleAppender.Threshold)); 179 Notice(String.Format("Console log level is {0}", m_consoleAppender.Threshold));
175 } 180 }
176 181
@@ -185,6 +190,18 @@ namespace OpenSim.Framework.Servers
185 190
186 m_log.InfoFormat("[SERVER BASE]: Logging started to file {0}", m_logFileAppender.File); 191 m_log.InfoFormat("[SERVER BASE]: Logging started to file {0}", m_logFileAppender.File);
187 } 192 }
193
194 if (m_statsLogFileAppender != null && startupConfig != null)
195 {
196 string cfgStatsFileName = startupConfig.GetString("StatsLogFile", null);
197 if (cfgStatsFileName != null)
198 {
199 m_statsLogFileAppender.File = cfgStatsFileName;
200 m_statsLogFileAppender.ActivateOptions();
201 }
202
203 m_log.InfoFormat("[SERVER BASE]: Stats Logging started to file {0}", m_statsLogFileAppender.File);
204 }
188 } 205 }
189 206
190 /// <summary> 207 /// <summary>
@@ -205,11 +222,11 @@ namespace OpenSim.Framework.Servers
205 "General", false, "show uptime", "show uptime", "Show server uptime", HandleShow); 222 "General", false, "show uptime", "show uptime", "Show server uptime", HandleShow);
206 223
207 m_console.Commands.AddCommand( 224 m_console.Commands.AddCommand(
208 "General", false, "get log level", "get log level", "Get the current console logging level", 225 "General", false, "get log level", "get log level", "Get the current console logging level",
209 (mod, cmd) => ShowLogLevel()); 226 (mod, cmd) => ShowLogLevel());
210 227
211 m_console.Commands.AddCommand( 228 m_console.Commands.AddCommand(
212 "General", false, "set log level", "set log level <level>", 229 "General", false, "set log level", "set log level <level>",
213 "Set the console logging level for this session.", HandleSetLogLevel); 230 "Set the console logging level for this session.", HandleSetLogLevel);
214 231
215 m_console.Commands.AddCommand( 232 m_console.Commands.AddCommand(
@@ -222,14 +239,14 @@ namespace OpenSim.Framework.Servers
222 "config get [<section>] [<key>]", 239 "config get [<section>] [<key>]",
223 "Synonym for config show", 240 "Synonym for config show",
224 HandleConfig); 241 HandleConfig);
225 242
226 m_console.Commands.AddCommand( 243 m_console.Commands.AddCommand(
227 "General", false, "config show", 244 "General", false, "config show",
228 "config show [<section>] [<key>]", 245 "config show [<section>] [<key>]",
229 "Show config information", 246 "Show config information",
230 "If neither section nor field are specified, then the whole current configuration is printed." + Environment.NewLine 247 "If neither section nor field are specified, then the whole current configuration is printed." + Environment.NewLine
231 + "If a section is given but not a field, then all fields in that section are printed.", 248 + "If a section is given but not a field, then all fields in that section are printed.",
232 HandleConfig); 249 HandleConfig);
233 250
234 m_console.Commands.AddCommand( 251 m_console.Commands.AddCommand(
235 "General", false, "config save", 252 "General", false, "config save",
@@ -258,18 +275,6 @@ namespace OpenSim.Framework.Servers
258 (string module, string[] args) => Notice(GetThreadsReport())); 275 (string module, string[] args) => Notice(GetThreadsReport()));
259 276
260 m_console.Commands.AddCommand ( 277 m_console.Commands.AddCommand (
261 "Debug", false, "debug comms set",
262 "debug comms set serialosdreq true|false",
263 "Set comms parameters. For debug purposes.",
264 HandleDebugCommsSet);
265
266 m_console.Commands.AddCommand (
267 "Debug", false, "debug comms status",
268 "debug comms status",
269 "Show current debug comms parameters.",
270 HandleDebugCommsStatus);
271
272 m_console.Commands.AddCommand (
273 "Debug", false, "debug threadpool set", 278 "Debug", false, "debug threadpool set",
274 "debug threadpool set worker|iocp min|max <n>", 279 "debug threadpool set worker|iocp min|max <n>",
275 "Set threadpool parameters. For debug purposes.", 280 "Set threadpool parameters. For debug purposes.",
@@ -280,7 +285,7 @@ namespace OpenSim.Framework.Servers
280 "debug threadpool status", 285 "debug threadpool status",
281 "Show current debug threadpool parameters.", 286 "Show current debug threadpool parameters.",
282 HandleDebugThreadpoolStatus); 287 HandleDebugThreadpoolStatus);
283 288
284 m_console.Commands.AddCommand( 289 m_console.Commands.AddCommand(
285 "Debug", false, "debug threadpool level", 290 "Debug", false, "debug threadpool level",
286 "debug threadpool level 0.." + Util.MAX_THREADPOOL_LEVEL, 291 "debug threadpool level 0.." + Util.MAX_THREADPOOL_LEVEL,
@@ -326,47 +331,13 @@ namespace OpenSim.Framework.Servers
326 331
327 public void RegisterCommonComponents(IConfigSource configSource) 332 public void RegisterCommonComponents(IConfigSource configSource)
328 { 333 {
329 IConfig networkConfig = configSource.Configs["Network"]; 334// IConfig networkConfig = configSource.Configs["Network"];
330 335
331 if (networkConfig != null)
332 {
333 WebUtil.SerializeOSDRequestsPerEndpoint = networkConfig.GetBoolean("SerializeOSDRequests", false);
334 }
335
336 m_serverStatsCollector = new ServerStatsCollector(); 336 m_serverStatsCollector = new ServerStatsCollector();
337 m_serverStatsCollector.Initialise(configSource); 337 m_serverStatsCollector.Initialise(configSource);
338 m_serverStatsCollector.Start(); 338 m_serverStatsCollector.Start();
339 } 339 }
340 340
341 private void HandleDebugCommsStatus(string module, string[] args)
342 {
343 Notice("serialosdreq is {0}", WebUtil.SerializeOSDRequestsPerEndpoint);
344 }
345
346 private void HandleDebugCommsSet(string module, string[] args)
347 {
348 if (args.Length != 5)
349 {
350 Notice("Usage: debug comms set serialosdreq true|false");
351 return;
352 }
353
354 if (args[3] != "serialosdreq")
355 {
356 Notice("Usage: debug comms set serialosdreq true|false");
357 return;
358 }
359
360 bool setSerializeOsdRequests;
361
362 if (!ConsoleUtil.TryParseConsoleBool(m_console, args[4], out setSerializeOsdRequests))
363 return;
364
365 WebUtil.SerializeOSDRequestsPerEndpoint = setSerializeOsdRequests;
366
367 Notice("serialosdreq is now {0}", setSerializeOsdRequests);
368 }
369
370 private void HandleShowThreadpoolCallsActive(string module, string[] args) 341 private void HandleShowThreadpoolCallsActive(string module, string[] args)
371 { 342 {
372 List<KeyValuePair<string, int>> calls = Util.GetFireAndForgetCallsInProgress().ToList(); 343 List<KeyValuePair<string, int>> calls = Util.GetFireAndForgetCallsInProgress().ToList();
@@ -432,7 +403,7 @@ namespace OpenSim.Framework.Servers
432 403
433 ThreadPool.GetAvailableThreads(out workerThreads, out iocpThreads); 404 ThreadPool.GetAvailableThreads(out workerThreads, out iocpThreads);
434 Notice("Available worker threads: {0}", workerThreads); 405 Notice("Available worker threads: {0}", workerThreads);
435 Notice("Available IOCP threads: {0}", iocpThreads); 406 Notice("Available IOCP threads: {0}", iocpThreads);
436 } 407 }
437 408
438 private void HandleDebugThreadpoolSet(string module, string[] args) 409 private void HandleDebugThreadpoolSet(string module, string[] args)
@@ -488,7 +459,7 @@ namespace OpenSim.Framework.Servers
488 fail = true; 459 fail = true;
489 } 460 }
490 } 461 }
491 462
492 if (fail) 463 if (fail)
493 { 464 {
494 Notice("ERROR: Could not set {0} {1} threads to {2}", poolType, bound, newThreads); 465 Notice("ERROR: Could not set {0} {1} threads to {2}", poolType, bound, newThreads);
@@ -582,7 +553,7 @@ namespace OpenSim.Framework.Servers
582 if (cmdparams.Length > 0) 553 if (cmdparams.Length > 0)
583 { 554 {
584 string firstParam = cmdparams[0].ToLower(); 555 string firstParam = cmdparams[0].ToLower();
585 556
586 switch (firstParam) 557 switch (firstParam)
587 { 558 {
588 case "set": 559 case "set":
@@ -633,12 +604,12 @@ namespace OpenSim.Framework.Servers
633 { 604 {
634 Notice("[{0}]", config.Name); 605 Notice("[{0}]", config.Name);
635 foreach (string key in config.GetKeys()) 606 foreach (string key in config.GetKeys())
636 Notice(" {0} = {1}", key, config.GetString(key)); 607 Notice(" {0} = {1}", key, config.GetString(key));
637 } 608 }
638 else 609 else
639 { 610 {
640 Notice( 611 Notice(
641 "config get {0} {1} : {2}", 612 "config get {0} {1} : {2}",
642 cmdparams[1], cmdparams[2], config.GetString(cmdparams[2])); 613 cmdparams[1], cmdparams[2], config.GetString(cmdparams[2]));
643 } 614 }
644 } 615 }
@@ -692,10 +663,10 @@ namespace OpenSim.Framework.Servers
692 } 663 }
693 664
694 string rawLevel = cmd[3]; 665 string rawLevel = cmd[3];
695 666
696 ILoggerRepository repository = LogManager.GetRepository(); 667 ILoggerRepository repository = LogManager.GetRepository();
697 Level consoleLevel = repository.LevelMap[rawLevel]; 668 Level consoleLevel = repository.LevelMap[rawLevel];
698 669
699 if (consoleLevel != null) 670 if (consoleLevel != null)
700 m_consoleAppender.Threshold = consoleLevel; 671 m_consoleAppender.Threshold = consoleLevel;
701 else 672 else
@@ -770,9 +741,9 @@ namespace OpenSim.Framework.Servers
770 protected void ShowInfo() 741 protected void ShowInfo()
771 { 742 {
772 Notice(GetVersionText()); 743 Notice(GetVersionText());
773 Notice("Startup directory: " + m_startupDirectory); 744 Notice("Startup directory: " + m_startupDirectory);
774 if (null != m_consoleAppender) 745 if (null != m_consoleAppender)
775 Notice(String.Format("Console log level: {0}", m_consoleAppender.Threshold)); 746 Notice(String.Format("Console log level: {0}", m_consoleAppender.Threshold));
776 } 747 }
777 748
778 /// <summary> 749 /// <summary>
@@ -842,7 +813,7 @@ namespace OpenSim.Framework.Servers
842 { 813 {
843 StreamReader RevisionFile = File.OpenText(svnRevisionFileName); 814 StreamReader RevisionFile = File.OpenText(svnRevisionFileName);
844 buildVersion = RevisionFile.ReadLine(); 815 buildVersion = RevisionFile.ReadLine();
845 buildVersion.Trim(); 816 buildVersion = buildVersion.Trim();
846 RevisionFile.Close(); 817 RevisionFile.Close();
847 } 818 }
848 819
@@ -871,9 +842,9 @@ namespace OpenSim.Framework.Servers
871 } 842 }
872 } 843 }
873 844
874 protected string GetVersionText() 845 public string GetVersionText()
875 { 846 {
876 return String.Format("Version: {0} (SIMULATION/{1} - SIMULATION/{2})", 847 return String.Format("Version: {0} (SIMULATION/{1} - SIMULATION/{2})",
877 m_version, VersionInfo.SimulationServiceVersionSupportedMin, VersionInfo.SimulationServiceVersionSupportedMax); 848 m_version, VersionInfo.SimulationServiceVersionSupportedMin, VersionInfo.SimulationServiceVersionSupportedMax);
878 } 849 }
879 850
@@ -898,7 +869,7 @@ namespace OpenSim.Framework.Servers
898 foreach (Watchdog.ThreadWatchdogInfo twi in threads) 869 foreach (Watchdog.ThreadWatchdogInfo twi in threads)
899 { 870 {
900 Thread t = twi.Thread; 871 Thread t = twi.Thread;
901 872
902 sb.AppendFormat( 873 sb.AppendFormat(
903 reportFormat, 874 reportFormat,
904 t.ManagedThreadId, 875 t.ManagedThreadId,
@@ -911,16 +882,12 @@ namespace OpenSim.Framework.Servers
911 sb.Append("\n"); 882 sb.Append("\n");
912 } 883 }
913 884
914 sb.Append("\n"); 885 sb.Append(GetThreadPoolReport());
915 886
916 // For some reason mono 2.6.7 returns an empty threads set! Not going to confuse people by reporting 887 sb.Append("\n");
917 // zero active threads.
918 int totalThreads = Process.GetCurrentProcess().Threads.Count; 888 int totalThreads = Process.GetCurrentProcess().Threads.Count;
919 if (totalThreads > 0) 889 if (totalThreads > 0)
920 sb.AppendFormat("Total threads active: {0}\n\n", totalThreads); 890 sb.AppendFormat("Total process threads active: {0}\n\n", totalThreads);
921
922 sb.Append("Main threadpool (excluding script engine pools)\n");
923 sb.Append(GetThreadPoolReport());
924 891
925 return sb.ToString(); 892 return sb.ToString();
926 } 893 }
@@ -931,15 +898,46 @@ namespace OpenSim.Framework.Servers
931 /// <returns></returns> 898 /// <returns></returns>
932 public static string GetThreadPoolReport() 899 public static string GetThreadPoolReport()
933 { 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
934 string threadPoolUsed = null; 934 string threadPoolUsed = null;
935 int maxThreads = 0; 935 int maxThreads = 0;
936 int minThreads = 0; 936 int minThreads = 0;
937 int allocatedThreads = 0; 937 int allocatedThreads = 0;
938 int inUseThreads = 0; 938 int inUseThreads = 0;
939 int waitingCallbacks = 0; 939 int waitingCallbacks = 0;
940 int completionPortThreads = 0;
941 940
942 StringBuilder sb = new StringBuilder();
943 if (Util.FireAndForgetMethod == FireAndForgetMethod.SmartThreadPool) 941 if (Util.FireAndForgetMethod == FireAndForgetMethod.SmartThreadPool)
944 { 942 {
945 STPInfo stpi = Util.GetSmartThreadPoolInfo(); 943 STPInfo stpi = Util.GetSmartThreadPoolInfo();
@@ -955,22 +953,10 @@ namespace OpenSim.Framework.Servers
955 waitingCallbacks = stpi.WaitingCallbacks; 953 waitingCallbacks = stpi.WaitingCallbacks;
956 } 954 }
957 } 955 }
958 else if ( 956
959 Util.FireAndForgetMethod == FireAndForgetMethod.QueueUserWorkItem
960 || Util.FireAndForgetMethod == FireAndForgetMethod.UnsafeQueueUserWorkItem)
961 {
962 threadPoolUsed = "BuiltInThreadPool";
963 ThreadPool.GetMaxThreads(out maxThreads, out completionPortThreads);
964 ThreadPool.GetMinThreads(out minThreads, out completionPortThreads);
965 int availableThreads;
966 ThreadPool.GetAvailableThreads(out availableThreads, out completionPortThreads);
967 inUseThreads = maxThreads - availableThreads;
968 allocatedThreads = -1;
969 waitingCallbacks = -1;
970 }
971
972 if (threadPoolUsed != null) 957 if (threadPoolUsed != null)
973 { 958 {
959 sb.Append("\nThreadpool (excluding script engine pools)\n");
974 sb.AppendFormat("Thread pool used : {0}\n", threadPoolUsed); 960 sb.AppendFormat("Thread pool used : {0}\n", threadPoolUsed);
975 sb.AppendFormat("Max threads : {0}\n", maxThreads); 961 sb.AppendFormat("Max threads : {0}\n", maxThreads);
976 sb.AppendFormat("Min threads : {0}\n", minThreads); 962 sb.AppendFormat("Min threads : {0}\n", minThreads);
@@ -1005,7 +991,7 @@ namespace OpenSim.Framework.Servers
1005 MainConsole.Instance.OutputFormat("Aborted thread with id {0}", threadId); 991 MainConsole.Instance.OutputFormat("Aborted thread with id {0}", threadId);
1006 else 992 else
1007 MainConsole.Instance.OutputFormat("ERROR - Thread with id {0} not found in managed threads", threadId); 993 MainConsole.Instance.OutputFormat("ERROR - Thread with id {0} not found in managed threads", threadId);
1008 } 994 }
1009 995
1010 /// <summary> 996 /// <summary>
1011 /// Console output is only possible if a console has been established. 997 /// Console output is only possible if a console has been established.
@@ -1020,13 +1006,13 @@ namespace OpenSim.Framework.Servers
1020 m_console.Output(msg); 1006 m_console.Output(msg);
1021 } 1007 }
1022 } 1008 }
1023 1009
1024 /// <summary> 1010 /// <summary>
1025 /// Console output is only possible if a console has been established. 1011 /// Console output is only possible if a console has been established.
1026 /// That is something that cannot be determined within this class. So 1012 /// That is something that cannot be determined within this class. So
1027 /// all attempts to use the console MUST be verified. 1013 /// all attempts to use the console MUST be verified.
1028 /// </summary> 1014 /// </summary>
1029 /// <param name="format"></param> 1015 /// <param name="format"></param>
1030 /// <param name="components"></param> 1016 /// <param name="components"></param>
1031 protected void Notice(string format, params object[] components) 1017 protected void Notice(string format, params object[] components)
1032 { 1018 {
diff --git a/OpenSim/Framework/Servers/Tests/OSHttpTests.cs b/OpenSim/Framework/Servers/Tests/OSHttpTests.cs
index 5c0e0df..e5f7043 100644
--- a/OpenSim/Framework/Servers/Tests/OSHttpTests.cs
+++ b/OpenSim/Framework/Servers/Tests/OSHttpTests.cs
@@ -39,9 +39,331 @@ using OpenSim.Tests.Common;
39 39
40namespace OpenSim.Framework.Servers.Tests 40namespace OpenSim.Framework.Servers.Tests
41{ 41{
42/*
43
42 [TestFixture] 44 [TestFixture]
43 public class OSHttpTests : OpenSimTestCase 45 public class OSHttpTests : OpenSimTestCase
44 { 46 {
47 // we need an IHttpClientContext for our tests
48 public class TestHttpClientContext: IHttpClientContext
49 {
50 private bool _secured;
51 public bool IsSecured
52 {
53 get { return _secured; }
54 }
55 public bool Secured
56 {
57 get { return _secured; }
58 }
59
60 public TestHttpClientContext(bool secured)
61 {
62 _secured = secured;
63 }
64
65 public void Disconnect(SocketError error) {}
66 public void Respond(string httpVersion, HttpStatusCode statusCode, string reason, string body) {}
67 public void Respond(string httpVersion, HttpStatusCode statusCode, string reason) {}
68 public void Respond(string body) {}
69 public void Send(byte[] buffer) {}
70 public void Send(byte[] buffer, int offset, int size) {}
71 public void Respond(string httpVersion, HttpStatusCode statusCode, string reason, string body, string contentType) {}
72 public void Close() { }
73 public bool EndWhenDone { get { return false;} set { return;}}
74
75 public HTTPNetworkContext GiveMeTheNetworkStreamIKnowWhatImDoing()
76 {
77 return new HTTPNetworkContext();
78 }
79
80 public event EventHandler<DisconnectedEventArgs> Disconnected = delegate { };
81 /// <summary>
82 /// A request have been received in the context.
83 /// </summary>
84 public event EventHandler<RequestEventArgs> RequestReceived = delegate { };
85
86 public bool CanSend { get { return true; } }
87 public string RemoteEndPoint { get { return ""; } }
88 public string RemoteEndPointAddress { get { return ""; } }
89 public string RemoteEndPointPort { get { return ""; } }
90 }
91
92 public class TestHttpRequest: IHttpRequest
93 {
94 private string _uriPath;
95 public bool BodyIsComplete
96 {
97 get { return true; }
98 }
99 public string[] AcceptTypes
100 {
101 get {return _acceptTypes; }
102 }
103 private string[] _acceptTypes;
104 public Stream Body
105 {
106 get { return _body; }
107 set { _body = value;}
108 }
109 private Stream _body;
110 public ConnectionType Connection
111 {
112 get { return _connection; }
113 set { _connection = value; }
114 }
115 private ConnectionType _connection;
116 public int ContentLength
117 {
118 get { return _contentLength; }
119 set { _contentLength = value; }
120 }
121 private int _contentLength;
122 public NameValueCollection Headers
123 {
124 get { return _headers; }
125 }
126 private NameValueCollection _headers = new NameValueCollection();
127 public string HttpVersion
128 {
129 get { return _httpVersion; }
130 set { _httpVersion = value; }
131 }
132 private string _httpVersion = null;
133 public string Method
134 {
135 get { return _method; }
136 set { _method = value; }
137 }
138 private string _method = null;
139 public HttpInput QueryString
140 {
141 get { return _queryString; }
142 }
143 private HttpInput _queryString = null;
144 public Uri Uri
145 {
146 get { return _uri; }
147 set { _uri = value; }
148 }
149 private Uri _uri = null;
150 public string[] UriParts
151 {
152 get { return _uri.Segments; }
153 }
154 public HttpParam Param
155 {
156 get { return null; }
157 }
158 public HttpForm Form
159 {
160 get { return null; }
161 }
162 public bool IsAjax
163 {
164 get { return false; }
165 }
166 public RequestCookies Cookies
167 {
168 get { return null; }
169 }
170
171 public TestHttpRequest() {}
172
173 public TestHttpRequest(string contentEncoding, string contentType, string userAgent,
174 string remoteAddr, string remotePort, string[] acceptTypes,
175 ConnectionType connectionType, int contentLength, Uri uri)
176 {
177 _headers["content-encoding"] = contentEncoding;
178 _headers["content-type"] = contentType;
179 _headers["user-agent"] = userAgent;
180 _headers["remote_addr"] = remoteAddr;
181 _headers["remote_port"] = remotePort;
182
183 _acceptTypes = acceptTypes;
184 _connection = connectionType;
185 _contentLength = contentLength;
186 _uri = uri;
187 }
188
189 public void DecodeBody(FormDecoderProvider providers) {}
190 public void SetCookies(RequestCookies cookies) {}
191 public void AddHeader(string name, string value)
192 {
193 _headers.Add(name, value);
194 }
195 public int AddToBody(byte[] bytes, int offset, int length)
196 {
197 return 0;
198 }
199 public void Clear() {}
200
201 public object Clone()
202 {
203 TestHttpRequest clone = new TestHttpRequest();
204 clone._acceptTypes = _acceptTypes;
205 clone._connection = _connection;
206 clone._contentLength = _contentLength;
207 clone._uri = _uri;
208 clone._headers = new NameValueCollection(_headers);
209
210 return clone;
211 }
212 public IHttpResponse CreateResponse(IHttpClientContext context)
213 {
214 return new HttpResponse(context, this);
215 }
216 /// <summary>
217 /// Path and query (will be merged with the host header) and put in Uri
218 /// </summary>
219 /// <see cref="Uri"/>
220 public string UriPath
221 {
222 get { return _uriPath; }
223 set
224 {
225 _uriPath = value;
226
227 }
228 }
229
230 }
231
232 public class TestHttpResponse: IHttpResponse
233 {
234 public Stream Body
235 {
236 get { return _body; }
237
238 set { _body = value; }
239 }
240 private Stream _body;
241
242 public string ProtocolVersion
243 {
244 get { return _protocolVersion; }
245 set { _protocolVersion = value; }
246 }
247 private string _protocolVersion;
248
249 public bool Chunked
250 {
251 get { return _chunked; }
252
253 set { _chunked = value; }
254 }
255 private bool _chunked;
256
257 public ConnectionType Connection
258 {
259 get { return _connection; }
260
261 set { _connection = value; }
262 }
263 private ConnectionType _connection;
264
265 public Encoding Encoding
266 {
267 get { return _encoding; }
268
269 set { _encoding = value; }
270 }
271 private Encoding _encoding;
272
273 public int KeepAlive
274 {
275 get { return _keepAlive; }
276
277 set { _keepAlive = value; }
278 }
279 private int _keepAlive;
280
281 public HttpStatusCode Status
282 {
283 get { return _status; }
284
285 set { _status = value; }
286 }
287 private HttpStatusCode _status;
288
289 public string Reason
290 {
291 get { return _reason; }
292
293 set { _reason = value; }
294 }
295 private string _reason;
296
297 public long ContentLength
298 {
299 get { return _contentLength; }
300
301 set { _contentLength = value; }
302 }
303 private long _contentLength;
304
305 public string ContentType
306 {
307 get { return _contentType; }
308
309 set { _contentType = value; }
310 }
311 private string _contentType;
312
313 public bool HeadersSent
314 {
315 get { return _headersSent; }
316 }
317 private bool _headersSent;
318
319 public bool Sent
320 {
321 get { return _sent; }
322 }
323 private bool _sent;
324
325 public ResponseCookies Cookies
326 {
327 get { return _cookies; }
328 }
329 private ResponseCookies _cookies = null;
330
331 public TestHttpResponse()
332 {
333 _headersSent = false;
334 _sent = false;
335 }
336
337 public void AddHeader(string name, string value) {}
338 public void Send()
339 {
340 if (!_headersSent) SendHeaders();
341 if (_sent) throw new InvalidOperationException("stuff already sent");
342 _sent = true;
343 }
344
345 public void SendBody(byte[] buffer, int offset, int count)
346 {
347 if (!_headersSent) SendHeaders();
348 _sent = true;
349 }
350 public void SendBody(byte[] buffer)
351 {
352 if (!_headersSent) SendHeaders();
353 _sent = true;
354 }
355
356 public void SendHeaders()
357 {
358 if (_headersSent) throw new InvalidOperationException("headers already sent");
359 _headersSent = true;
360 }
361
362 public void Redirect(Uri uri) {}
363 public void Redirect(string url) {}
364 }
365
366
45 public OSHttpRequest req0; 367 public OSHttpRequest req0;
46 public OSHttpRequest req1; 368 public OSHttpRequest req1;
47 369
@@ -52,22 +374,22 @@ namespace OpenSim.Framework.Servers.Tests
52 [TestFixtureSetUp] 374 [TestFixtureSetUp]
53 public void Init() 375 public void Init()
54 { 376 {
55 TestHttpRequest threq0 = new TestHttpRequest("utf-8", "text/xml", "OpenSim Test Agent", "192.168.0.1", "4711", 377 TestHttpRequest threq0 = new TestHttpRequest("utf-8", "text/xml", "OpenSim Test Agent", "192.168.0.1", "4711",
56 new string[] {"text/xml"}, 378 new string[] {"text/xml"},
57 ConnectionType.KeepAlive, 4711, 379 ConnectionType.KeepAlive, 4711,
58 new Uri("http://127.0.0.1/admin/inventory/Dr+Who/Tardis")); 380 new Uri("http://127.0.0.1/admin/inventory/Dr+Who/Tardis"));
59 threq0.Method = "GET"; 381 threq0.Method = "GET";
60 threq0.HttpVersion = HttpHelper.HTTP10; 382 threq0.HttpVersion = HttpHelper.HTTP10;
61 383
62 TestHttpRequest threq1 = new TestHttpRequest("utf-8", "text/xml", "OpenSim Test Agent", "192.168.0.1", "4711", 384 TestHttpRequest threq1 = new TestHttpRequest("utf-8", "text/xml", "OpenSim Test Agent", "192.168.0.1", "4711",
63 new string[] {"text/xml"}, 385 new string[] {"text/xml"},
64 ConnectionType.KeepAlive, 4711, 386 ConnectionType.KeepAlive, 4711,
65 new Uri("http://127.0.0.1/admin/inventory/Dr+Who/Tardis?a=0&b=1&c=2")); 387 new Uri("http://127.0.0.1/admin/inventory/Dr+Who/Tardis?a=0&b=1&c=2"));
66 threq1.Method = "POST"; 388 threq1.Method = "POST";
67 threq1.HttpVersion = HttpHelper.HTTP11; 389 threq1.HttpVersion = HttpHelper.HTTP11;
68 threq1.Headers["x-wuff"] = "wuffwuff"; 390 threq1.Headers["x-wuff"] = "wuffwuff";
69 threq1.Headers["www-authenticate"] = "go away"; 391 threq1.Headers["www-authenticate"] = "go away";
70 392
71 req0 = new OSHttpRequest(new TestHttpClientContext(false), threq0); 393 req0 = new OSHttpRequest(new TestHttpClientContext(false), threq0);
72 req1 = new OSHttpRequest(new TestHttpClientContext(false), threq1); 394 req1 = new OSHttpRequest(new TestHttpClientContext(false), threq1);
73 395
@@ -113,4 +435,5 @@ namespace OpenSim.Framework.Servers.Tests
113 Assert.That(rsp0.ContentType, Is.EqualTo("text/xml")); 435 Assert.That(rsp0.ContentType, Is.EqualTo("text/xml"));
114 } 436 }
115 } 437 }
116} \ No newline at end of file 438*/
439}
diff --git a/OpenSim/Framework/Servers/Tests/VersionInfoTests.cs b/OpenSim/Framework/Servers/Tests/VersionInfoTests.cs
index 2d72cb8..480f2bb 100644
--- a/OpenSim/Framework/Servers/Tests/VersionInfoTests.cs
+++ b/OpenSim/Framework/Servers/Tests/VersionInfoTests.cs
@@ -47,7 +47,7 @@ namespace OpenSim.Framework.Servers.Tests
47 { 47 {
48 foreach (VersionInfo.Flavour flavour in Enum.GetValues(typeof(VersionInfo.Flavour))) 48 foreach (VersionInfo.Flavour flavour in Enum.GetValues(typeof(VersionInfo.Flavour)))
49 { 49 {
50 Assert.AreEqual(VersionInfo.VERSIONINFO_VERSION_LENGTH, VersionInfo.GetVersionString("0.0.0", "0", flavour).Length, "0.0.0/" + flavour + " failed"); 50 Assert.AreEqual(VersionInfo.VERSIONINFO_VERSION_LENGTH, VersionInfo.GetVersionString("0.0.0", flavour).Length, "0.0.0/" + flavour + " failed");
51 } 51 }
52 } 52 }
53 } 53 }