we should only have one http poll service manager per instance
parent
3e6342eb61
commit
5b5e53aa1d
|
@ -44,11 +44,11 @@ using log4net;
|
|||
using Nwc.XmlRpc;
|
||||
using OpenMetaverse.StructuredData;
|
||||
using CoolHTTPListener = HttpServer.HttpListener;
|
||||
using HttpListener = System.Net.HttpListener;
|
||||
using LogPrio = HttpServer.LogPrio;
|
||||
using OpenSim.Framework.Monitoring;
|
||||
using System.IO.Compression;
|
||||
using System.Security.Cryptography;
|
||||
using OpenSim.Framework.Servers;
|
||||
|
||||
namespace OpenSim.Framework.Servers.HttpServer
|
||||
{
|
||||
|
@ -57,6 +57,8 @@ namespace OpenSim.Framework.Servers.HttpServer
|
|||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
private HttpServerLogWriter httpserverlog = new HttpServerLogWriter();
|
||||
private static Encoding UTF8NoBOM = new System.Text.UTF8Encoding(false);
|
||||
public static PollServiceRequestManager m_pollServiceManager;
|
||||
private static object m_generalLock = new object();
|
||||
|
||||
/// <summary>
|
||||
/// This is a pending websocket request before it got an sucessful upgrade response.
|
||||
|
@ -119,7 +121,6 @@ namespace OpenSim.Framework.Servers.HttpServer
|
|||
|
||||
protected IPAddress m_listenIPAddress = IPAddress.Any;
|
||||
|
||||
public PollServiceRequestManager PollServiceRequestManager { get; private set; }
|
||||
|
||||
public string Protocol
|
||||
{
|
||||
|
@ -249,46 +250,46 @@ namespace OpenSim.Framework.Servers.HttpServer
|
|||
m_ssl = false;
|
||||
}
|
||||
|
||||
static bool MatchDNS (string hostname, string dns)
|
||||
{
|
||||
int indx = dns.IndexOf ('*');
|
||||
if (indx == -1)
|
||||
return (String.Compare(hostname, dns, true, CultureInfo.InvariantCulture) == 0);
|
||||
|
||||
static bool MatchDNS(string hostname, string dns)
|
||||
{
|
||||
int indx = dns.IndexOf('*');
|
||||
if (indx == -1)
|
||||
return (String.Compare(hostname, dns, true, CultureInfo.InvariantCulture) == 0);
|
||||
|
||||
int dnslen = dns.Length;
|
||||
dnslen--;
|
||||
if(indx == dnslen)
|
||||
if (indx == dnslen)
|
||||
return true; // just * ?
|
||||
|
||||
if(indx > dnslen - 2)
|
||||
if (indx > dnslen - 2)
|
||||
return false; // 2 short ?
|
||||
|
||||
if (dns[indx + 1] != '.')
|
||||
return false;
|
||||
|
||||
int indx2 = dns.IndexOf ('*', indx + 1);
|
||||
if (indx2 != -1)
|
||||
return false; // there can only be one;
|
||||
|
||||
string end = dns.Substring(indx + 1);
|
||||
if (dns[indx + 1] != '.')
|
||||
return false;
|
||||
|
||||
int indx2 = dns.IndexOf('*', indx + 1);
|
||||
if (indx2 != -1)
|
||||
return false; // there can only be one;
|
||||
|
||||
string end = dns.Substring(indx + 1);
|
||||
int hostlen = hostname.Length;
|
||||
int endlen = end.Length;
|
||||
int length = hostlen - endlen;
|
||||
if (length <= 0)
|
||||
return false;
|
||||
int length = hostlen - endlen;
|
||||
if (length <= 0)
|
||||
return false;
|
||||
|
||||
if (String.Compare(hostname, length, end, 0, endlen, true, CultureInfo.InvariantCulture) != 0)
|
||||
return false;
|
||||
|
||||
if (indx == 0)
|
||||
{
|
||||
indx2 = hostname.IndexOf ('.');
|
||||
return ((indx2 == -1) || (indx2 >= length));
|
||||
}
|
||||
|
||||
string start = dns.Substring (0, indx);
|
||||
return (String.Compare (hostname, 0, start, 0, start.Length, true, CultureInfo.InvariantCulture) == 0);
|
||||
}
|
||||
if (String.Compare(hostname, length, end, 0, endlen, true, CultureInfo.InvariantCulture) != 0)
|
||||
return false;
|
||||
|
||||
if (indx == 0)
|
||||
{
|
||||
indx2 = hostname.IndexOf('.');
|
||||
return ((indx2 == -1) || (indx2 >= length));
|
||||
}
|
||||
|
||||
string start = dns.Substring(0, indx);
|
||||
return (String.Compare(hostname, 0, start, 0, start.Length, true, CultureInfo.InvariantCulture) == 0);
|
||||
}
|
||||
|
||||
public bool CheckSSLCertHost(string hostname)
|
||||
{
|
||||
|
@ -527,7 +528,6 @@ namespace OpenSim.Framework.Servers.HttpServer
|
|||
public void OnRequest(object source, RequestEventArgs args)
|
||||
{
|
||||
RequestNumber++;
|
||||
|
||||
try
|
||||
{
|
||||
IHttpClientContext context = (IHttpClientContext)source;
|
||||
|
@ -576,7 +576,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
|||
psEvArgs.Request(psreq.RequestID, keysvals);
|
||||
}
|
||||
|
||||
PollServiceRequestManager.Enqueue(psreq);
|
||||
m_pollServiceManager.Enqueue(psreq);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -616,16 +616,6 @@ namespace OpenSim.Framework.Servers.HttpServer
|
|||
request.AcceptTypes[i] = string.Empty;
|
||||
}
|
||||
|
||||
// public void ConvertIHttpClientContextToOSHttp(object stateinfo)
|
||||
// {
|
||||
// HttpServerContextObj objstate = (HttpServerContextObj)stateinfo;
|
||||
|
||||
// OSHttpRequest request = objstate.oreq;
|
||||
// OSHttpResponse resp = objstate.oresp;
|
||||
|
||||
// HandleRequest(request,resp);
|
||||
// }
|
||||
|
||||
/// <summary>
|
||||
/// This methods is the start of incoming HTTP request handling.
|
||||
/// </summary>
|
||||
|
@ -2036,7 +2026,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
|||
|
||||
public void Start()
|
||||
{
|
||||
Start(true,true);
|
||||
Start(true, true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -2085,11 +2075,14 @@ namespace OpenSim.Framework.Servers.HttpServer
|
|||
//m_httpListener.Start();
|
||||
m_httpListener2.Start(64);
|
||||
|
||||
// Long Poll Service Manager with 3 worker threads a 25 second timeout for no events
|
||||
if(runPool)
|
||||
lock(m_generalLock)
|
||||
{
|
||||
PollServiceRequestManager = new PollServiceRequestManager(this, performPollResponsesAsync, 2, 25000);
|
||||
PollServiceRequestManager.Start();
|
||||
if (runPool)
|
||||
{
|
||||
if(m_pollServiceManager == null)
|
||||
m_pollServiceManager = new PollServiceRequestManager(performPollResponsesAsync, 2, 25000);
|
||||
m_pollServiceManager.Start();
|
||||
}
|
||||
}
|
||||
|
||||
HTTPDRunning = true;
|
||||
|
@ -2143,27 +2136,22 @@ namespace OpenSim.Framework.Servers.HttpServer
|
|||
if (source.ToString() == "HttpServer.HttpListener" && exception.ToString().StartsWith("Mono.Security.Protocol.Tls.TlsException"))
|
||||
return;
|
||||
m_log.ErrorFormat("[BASE HTTP SERVER]: {0} had an exception {1}", source.ToString(), exception.ToString());
|
||||
/*
|
||||
if (HTTPDRunning)// && NotSocketErrors > 5)
|
||||
{
|
||||
Stop();
|
||||
Thread.Sleep(200);
|
||||
StartHTTP();
|
||||
m_log.Warn("[HTTPSERVER]: Died. Trying to kick.....");
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
public void Stop(bool stopPool = false)
|
||||
{
|
||||
HTTPDRunning = false;
|
||||
|
||||
|
||||
StatsManager.DeregisterStat(m_requestsProcessedStat);
|
||||
|
||||
try
|
||||
{
|
||||
if(PollServiceRequestManager != null)
|
||||
PollServiceRequestManager.Stop();
|
||||
lock(m_generalLock)
|
||||
{
|
||||
if (stopPool && m_pollServiceManager != null)
|
||||
m_pollServiceManager.Stop();
|
||||
}
|
||||
|
||||
m_httpListener2.ExceptionThrown -= httpServerException;
|
||||
//m_httpListener2.DisconnectHandler = null;
|
||||
|
|
|
@ -79,12 +79,12 @@ namespace OpenSim.Framework.Servers.HttpServer
|
|||
contextHash = HttpContext.contextID;
|
||||
}
|
||||
|
||||
internal void DoHTTPGruntWork(BaseHttpServer server, Hashtable responsedata)
|
||||
internal void DoHTTPGruntWork(Hashtable responsedata)
|
||||
{
|
||||
OSHttpResponse response
|
||||
= new OSHttpResponse(new HttpResponse(HttpContext, Request), HttpContext);
|
||||
|
||||
byte[] buffer = server.DoHTTPGruntWork(responsedata, response);
|
||||
byte[] buffer = srvDoHTTPGruntWork(responsedata, response);
|
||||
|
||||
if(Request.Body.CanRead)
|
||||
Request.Body.Dispose();
|
||||
|
@ -114,7 +114,119 @@ namespace OpenSim.Framework.Servers.HttpServer
|
|||
PollServiceArgs.RequestsHandled++;
|
||||
}
|
||||
|
||||
internal void DoHTTPstop(BaseHttpServer server)
|
||||
internal byte[] srvDoHTTPGruntWork(Hashtable responsedata, OSHttpResponse response)
|
||||
{
|
||||
int responsecode;
|
||||
string responseString = String.Empty;
|
||||
byte[] responseData = null;
|
||||
string contentType;
|
||||
|
||||
if (responsedata == null)
|
||||
{
|
||||
responsecode = 500;
|
||||
responseString = "No response could be obtained";
|
||||
contentType = "text/plain";
|
||||
responsedata = new Hashtable();
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
//m_log.Info("[BASE HTTP SERVER]: Doing HTTP Grunt work with response");
|
||||
responsecode = (int)responsedata["int_response_code"];
|
||||
if (responsedata["bin_response_data"] != null)
|
||||
responseData = (byte[])responsedata["bin_response_data"];
|
||||
else
|
||||
responseString = (string)responsedata["str_response_string"];
|
||||
contentType = (string)responsedata["content_type"];
|
||||
if (responseString == null)
|
||||
responseString = String.Empty;
|
||||
}
|
||||
catch
|
||||
{
|
||||
responsecode = 500;
|
||||
responseString = "No response could be obtained";
|
||||
contentType = "text/plain";
|
||||
responsedata = new Hashtable();
|
||||
}
|
||||
}
|
||||
|
||||
if (responsedata.ContainsKey("error_status_text"))
|
||||
{
|
||||
response.StatusDescription = (string)responsedata["error_status_text"];
|
||||
}
|
||||
if (responsedata.ContainsKey("http_protocol_version"))
|
||||
{
|
||||
response.ProtocolVersion = (string)responsedata["http_protocol_version"];
|
||||
}
|
||||
|
||||
if (responsedata.ContainsKey("keepalive"))
|
||||
{
|
||||
bool keepalive = (bool)responsedata["keepalive"];
|
||||
response.KeepAlive = keepalive;
|
||||
}
|
||||
|
||||
// Cross-Origin Resource Sharing with simple requests
|
||||
if (responsedata.ContainsKey("access_control_allow_origin"))
|
||||
response.AddHeader("Access-Control-Allow-Origin", (string)responsedata["access_control_allow_origin"]);
|
||||
|
||||
//Even though only one other part of the entire code uses HTTPHandlers, we shouldn't expect this
|
||||
//and should check for NullReferenceExceptions
|
||||
|
||||
if (string.IsNullOrEmpty(contentType))
|
||||
{
|
||||
contentType = "text/html";
|
||||
}
|
||||
|
||||
// The client ignores anything but 200 here for web login, so ensure that this is 200 for that
|
||||
|
||||
response.StatusCode = responsecode;
|
||||
|
||||
if (responsecode == (int)OSHttpStatusCode.RedirectMovedPermanently)
|
||||
{
|
||||
response.RedirectLocation = (string)responsedata["str_redirect_location"];
|
||||
response.StatusCode = responsecode;
|
||||
}
|
||||
|
||||
response.AddHeader("Content-Type", contentType);
|
||||
if (responsedata.ContainsKey("headers"))
|
||||
{
|
||||
Hashtable headerdata = (Hashtable)responsedata["headers"];
|
||||
|
||||
foreach (string header in headerdata.Keys)
|
||||
response.AddHeader(header, headerdata[header].ToString());
|
||||
}
|
||||
|
||||
byte[] buffer;
|
||||
|
||||
if (responseData != null)
|
||||
{
|
||||
buffer = responseData;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!(contentType.Contains("image")
|
||||
|| contentType.Contains("x-shockwave-flash")
|
||||
|| contentType.Contains("application/x-oar")
|
||||
|| contentType.Contains("application/vnd.ll.mesh")))
|
||||
{
|
||||
// Text
|
||||
buffer = Encoding.UTF8.GetBytes(responseString);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Binary!
|
||||
buffer = Convert.FromBase64String(responseString);
|
||||
}
|
||||
|
||||
response.SendChunked = false;
|
||||
response.ContentLength64 = buffer.Length;
|
||||
response.ContentEncoding = Encoding.UTF8;
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
internal void DoHTTPstop()
|
||||
{
|
||||
OSHttpResponse response
|
||||
= new OSHttpResponse(new HttpResponse(HttpContext, Request), HttpContext);
|
||||
|
|
|
@ -41,8 +41,6 @@ namespace OpenSim.Framework.Servers.HttpServer
|
|||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private readonly BaseHttpServer m_server;
|
||||
|
||||
private Dictionary<int, Queue<PollServiceHttpRequest>> m_bycontext;
|
||||
private BlockingCollection<PollServiceHttpRequest> m_requests = new BlockingCollection<PollServiceHttpRequest>();
|
||||
private ConcurrentQueue<PollServiceHttpRequest> m_retryRequests = new ConcurrentQueue<PollServiceHttpRequest>();
|
||||
|
@ -56,9 +54,8 @@ namespace OpenSim.Framework.Servers.HttpServer
|
|||
private SmartThreadPool m_threadPool;
|
||||
|
||||
public PollServiceRequestManager(
|
||||
BaseHttpServer pSrv, bool performResponsesAsync, uint pWorkerThreadCount, int pTimeout)
|
||||
bool performResponsesAsync, uint pWorkerThreadCount, int pTimeout)
|
||||
{
|
||||
m_server = pSrv;
|
||||
m_WorkerThreadCount = pWorkerThreadCount;
|
||||
m_workerThreads = new Thread[m_WorkerThreadCount];
|
||||
|
||||
|
@ -77,6 +74,8 @@ namespace OpenSim.Framework.Servers.HttpServer
|
|||
|
||||
public void Start()
|
||||
{
|
||||
if(m_running)
|
||||
return;
|
||||
m_running = true;
|
||||
m_threadPool.Start();
|
||||
//startup worker threads
|
||||
|
@ -85,7 +84,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
|||
m_workerThreads[i]
|
||||
= WorkManager.StartThread(
|
||||
PoolWorkerJob,
|
||||
string.Format("PollServiceWorkerThread {0}:{1}", i, m_server.Port),
|
||||
string.Format("PollServiceWorkerThread {0}", i),
|
||||
ThreadPriority.Normal,
|
||||
true,
|
||||
false,
|
||||
|
@ -95,7 +94,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
|||
|
||||
m_retrysThread = WorkManager.StartThread(
|
||||
this.CheckRetries,
|
||||
string.Format("PollServiceWatcherThread:{0}", m_server.Port),
|
||||
string.Format("PollServiceWatcherThread"),
|
||||
ThreadPriority.Normal,
|
||||
true,
|
||||
true,
|
||||
|
@ -183,6 +182,9 @@ namespace OpenSim.Framework.Servers.HttpServer
|
|||
|
||||
public void Stop()
|
||||
{
|
||||
if(!m_running)
|
||||
return;
|
||||
|
||||
m_running = false;
|
||||
|
||||
Thread.Sleep(100); // let the world move
|
||||
|
@ -202,7 +204,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
|||
try
|
||||
{
|
||||
while(m_retryRequests.TryDequeue(out req))
|
||||
req.DoHTTPstop(m_server);
|
||||
req.DoHTTPstop();
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
@ -211,7 +213,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
|||
try
|
||||
{
|
||||
while(m_requests.TryTake(out req, 0))
|
||||
req.DoHTTPstop(m_server);
|
||||
req.DoHTTPstop();
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
@ -266,7 +268,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
|||
try
|
||||
{
|
||||
Hashtable responsedata = nreq.PollServiceArgs.GetEvents(nreq.RequestID, nreq.PollServiceArgs.Id);
|
||||
nreq.DoHTTPGruntWork(m_server, responsedata);
|
||||
nreq.DoHTTPGruntWork(responsedata);
|
||||
}
|
||||
catch (ObjectDisposedException) { }
|
||||
finally
|
||||
|
@ -286,8 +288,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
|||
{
|
||||
try
|
||||
{
|
||||
nreq.DoHTTPGruntWork(m_server,
|
||||
nreq.PollServiceArgs.NoEvents(nreq.RequestID, nreq.PollServiceArgs.Id));
|
||||
nreq.DoHTTPGruntWork(nreq.PollServiceArgs.NoEvents(nreq.RequestID, nreq.PollServiceArgs.Id));
|
||||
}
|
||||
catch (ObjectDisposedException) {}
|
||||
finally
|
||||
|
|
|
@ -87,14 +87,15 @@ namespace OpenSim.Framework.Servers
|
|||
set
|
||||
{
|
||||
lock (m_Servers)
|
||||
{
|
||||
if (!m_Servers.ContainsValue(value))
|
||||
throw new Exception("HTTP server must already have been registered to be set as the main instance");
|
||||
|
||||
instance = value;
|
||||
instance = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static BaseHttpServer UnSecureInstance
|
||||
{
|
||||
get { return unsecureinstance; }
|
||||
|
@ -372,14 +373,14 @@ namespace OpenSim.Framework.Servers
|
|||
|
||||
public static void Stop()
|
||||
{
|
||||
PollServiceRequestManager pool = null;
|
||||
lock (m_Servers)
|
||||
{
|
||||
foreach (BaseHttpServer httpServer in m_Servers.Values)
|
||||
{
|
||||
httpServer.Stop();
|
||||
httpServer.Stop(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue