bad merge?

This commit is contained in:
UbitUmarov
2015-09-01 14:54:35 +01:00
406 changed files with 62562 additions and 8067 deletions

View File

@@ -403,6 +403,7 @@ namespace OpenSim.Framework.Servers.HttpServer
StreamReader reader = new StreamReader(requestStream, encoding);
string requestBody = reader.ReadToEnd();
reader.Close();
Hashtable keysvals = new Hashtable();
Hashtable headervals = new Hashtable();
@@ -460,7 +461,7 @@ namespace OpenSim.Framework.Servers.HttpServer
}
OSHttpResponse resp = new OSHttpResponse(new HttpResponse(context, request),context);
resp.ReuseContext = true;
resp.ReuseContext = false;
HandleRequest(req, resp);
// !!!HACK ALERT!!!
@@ -759,7 +760,7 @@ namespace OpenSim.Framework.Servers.HttpServer
// Every month or so this will wrap and give bad numbers, not really a problem
// since its just for reporting
int tickdiff = requestEndTick - requestStartTick;
if (tickdiff > 3000 && requestHandler != null && requestHandler.Name != "GetTexture")
if (tickdiff > 3000 && (requestHandler == null || requestHandler.Name == null || requestHandler.Name != "GetTexture"))
{
m_log.InfoFormat(
"[LOGHTTP] Slow handling of {0} {1} {2} {3} {4} from {5} took {6}ms",
@@ -1024,6 +1025,19 @@ namespace OpenSim.Framework.Servers.HttpServer
string responseString = String.Empty;
XmlRpcRequest xmlRprcRequest = null;
bool gridproxy = false;
if (requestBody.Contains("encoding=\"utf-8"))
{
int channelindx = -1;
int optionsindx = requestBody.IndexOf(">options<");
if(optionsindx >0)
{
channelindx = requestBody.IndexOf(">channel<");
if (optionsindx < channelindx)
gridproxy = true;
}
}
try
{
xmlRprcRequest = (XmlRpcRequest) (new XmlRpcRequestDeserializer()).Deserialize(requestBody);
@@ -1081,6 +1095,8 @@ namespace OpenSim.Framework.Servers.HttpServer
}
xmlRprcRequest.Params.Add(request.Headers.Get(xff)); // Param[3]
if (gridproxy)
xmlRprcRequest.Params.Add("gridproxy"); // Param[4]
try
{
xmlRpcResponse = method(xmlRprcRequest, request.RemoteIPEndPoint);
@@ -1732,10 +1748,40 @@ namespace OpenSim.Framework.Servers.HttpServer
internal byte[] DoHTTPGruntWork(Hashtable responsedata, OSHttpResponse response)
{
//m_log.Info("[BASE HTTP SERVER]: Doing HTTP Grunt work with response");
int responsecode = (int)responsedata["int_response_code"];
string responseString = (string)responsedata["str_response_string"];
string contentType = (string)responsedata["content_type"];
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"))
{
@@ -1780,25 +1826,40 @@ namespace OpenSim.Framework.Servers.HttpServer
response.AddHeader("Content-Type", contentType);
if (responsedata.ContainsKey("headers"))
{
Hashtable headerdata = (Hashtable)responsedata["headers"];
foreach (string header in headerdata.Keys)
response.AddHeader(header, (string)headerdata[header]);
}
byte[] buffer;
if (!(contentType.Contains("image")
|| contentType.Contains("x-shockwave-flash")
|| contentType.Contains("application/x-oar")
|| contentType.Contains("application/vnd.ll.mesh")))
if (responseData != null)
{
// Text
buffer = Encoding.UTF8.GetBytes(responseString);
buffer = responseData;
}
else
{
// Binary!
buffer = Convert.FromBase64String(responseString);
}
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;
response.SendChunked = false;
response.ContentLength64 = buffer.Length;
response.ContentEncoding = Encoding.UTF8;
}
return buffer;
}
@@ -1886,9 +1947,14 @@ namespace OpenSim.Framework.Servers.HttpServer
m_httpListener2.Start(64);
// Long Poll Service Manager with 3 worker threads a 25 second timeout for no events
<<<<<<< HEAD
PollServiceRequestManager = new PollServiceRequestManager(this, performPollResponsesAsync, 3, 25000);
PollServiceRequestManager.Start();
=======
m_PollServiceManager = new PollServiceRequestManager(this, 4, 25000);
m_PollServiceManager.Start();
>>>>>>> avn/ubitvar
HTTPDRunning = true;
//HttpListenerContext context;
@@ -1937,7 +2003,9 @@ namespace OpenSim.Framework.Servers.HttpServer
public void httpServerException(object source, Exception exception)
{
m_log.Error(String.Format("[BASE HTTP SERVER]: {0} had an exception: {1} ", source.ToString(), exception.Message), exception);
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)
{
@@ -1984,6 +2052,7 @@ namespace OpenSim.Framework.Servers.HttpServer
public void RemoveHTTPHandler(string httpMethod, string path)
{
if (path == null) return; // Caps module isn't loaded, tries to remove handler where path = null
lock (m_HTTPHandlers)
{
if (httpMethod != null && httpMethod.Length == 0)

View File

@@ -52,7 +52,9 @@ namespace OpenSim.Framework.Servers.HttpServer
{
LongPoll = 0,
LslHttp = 1,
Inventory = 2
Inventory = 2,
Texture = 3,
Mesh = 4
}
public string Url { get; set; }

View File

@@ -27,6 +27,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
using HttpServer;
@@ -44,6 +45,24 @@ namespace OpenSim.Framework.Servers.HttpServer
public readonly IHttpRequest Request;
public readonly int RequestTime;
public readonly UUID RequestID;
public int contextHash;
private void GenContextHash()
{
Random rnd = new Random();
contextHash = 0;
if (Request.Headers["remote_addr"] != null)
contextHash = (Request.Headers["remote_addr"]).GetHashCode() << 16;
else
contextHash = rnd.Next() << 16;
if (Request.Headers["remote_port"] != null)
{
string[] strPorts = Request.Headers["remote_port"].Split(new char[] { ',' });
contextHash += Int32.Parse(strPorts[0]);
}
else
contextHash += rnd.Next() & 0xffff;
}
public PollServiceHttpRequest(
PollServiceEventArgs pPollServiceArgs, IHttpClientContext pHttpContext, IHttpRequest pRequest)
@@ -53,6 +72,7 @@ namespace OpenSim.Framework.Servers.HttpServer
Request = pRequest;
RequestTime = System.Environment.TickCount;
RequestID = UUID.Random();
GenContextHash();
}
internal void DoHTTPGruntWork(BaseHttpServer server, Hashtable responsedata)
@@ -65,6 +85,7 @@ namespace OpenSim.Framework.Servers.HttpServer
response.SendChunked = false;
response.ContentLength64 = buffer.Length;
response.ContentEncoding = Encoding.UTF8;
response.ReuseContext = false;
try
{
@@ -93,5 +114,44 @@ namespace OpenSim.Framework.Servers.HttpServer
PollServiceArgs.RequestsHandled++;
}
}
internal void DoHTTPstop(BaseHttpServer server)
{
OSHttpResponse response
= new OSHttpResponse(new HttpResponse(HttpContext, Request), HttpContext);
response.SendChunked = false;
response.ContentLength64 = 0;
response.ContentEncoding = Encoding.UTF8;
response.ReuseContext = false;
response.KeepAlive = false;
response.SendChunked = false;
response.StatusCode = 503;
try
{
response.OutputStream.Flush();
response.Send();
}
catch (Exception e)
{
}
}
}
class PollServiceHttpRequestComparer : IEqualityComparer<PollServiceHttpRequest>
{
public bool Equals(PollServiceHttpRequest b1, PollServiceHttpRequest b2)
{
if (b1.contextHash != b2.contextHash)
return false;
bool b = Object.ReferenceEquals(b1.HttpContext, b2.HttpContext);
return b;
}
public int GetHashCode(PollServiceHttpRequest b2)
{
return (int)b2.contextHash;
}
}
}

View File

@@ -65,15 +65,25 @@ namespace OpenSim.Framework.Servers.HttpServer
private readonly BaseHttpServer m_server;
private Dictionary<PollServiceHttpRequest, Queue<PollServiceHttpRequest>> m_bycontext;
private BlockingQueue<PollServiceHttpRequest> m_requests = new BlockingQueue<PollServiceHttpRequest>();
private static List<PollServiceHttpRequest> m_longPollRequests = new List<PollServiceHttpRequest>();
private static Queue<PollServiceHttpRequest> m_slowRequests = new Queue<PollServiceHttpRequest>();
private static Queue<PollServiceHttpRequest> m_retryRequests = new Queue<PollServiceHttpRequest>();
private uint m_WorkerThreadCount = 0;
private Thread[] m_workerThreads;
private Thread m_retrysThread;
<<<<<<< HEAD
private SmartThreadPool m_threadPool = new SmartThreadPool(20000, 12, 2);
// private int m_timeout = 1000; // increase timeout 250; now use the event one
=======
private bool m_running = true;
private int slowCount = 0;
private SmartThreadPool m_threadPool;
>>>>>>> avn/ubitvar
public PollServiceRequestManager(
BaseHttpServer pSrv, bool performResponsesAsync, uint pWorkerThreadCount, int pTimeout)
@@ -83,6 +93,7 @@ namespace OpenSim.Framework.Servers.HttpServer
m_WorkerThreadCount = pWorkerThreadCount;
m_workerThreads = new Thread[m_WorkerThreadCount];
<<<<<<< HEAD
StatsManager.RegisterStat(
new Stat(
"QueuedPollResponses",
@@ -108,10 +119,25 @@ namespace OpenSim.Framework.Servers.HttpServer
MeasuresOfInterest.AverageChangeOverTime,
stat => stat.Value = ResponsesProcessed,
StatVerbosity.Debug));
=======
PollServiceHttpRequestComparer preqCp = new PollServiceHttpRequestComparer();
m_bycontext = new Dictionary<PollServiceHttpRequest, Queue<PollServiceHttpRequest>>(preqCp);
STPStartInfo startInfo = new STPStartInfo();
startInfo.IdleTimeout = 30000;
startInfo.MaxWorkerThreads = 15;
startInfo.MinWorkerThreads = 1;
startInfo.ThreadPriority = ThreadPriority.Normal;
startInfo.StartSuspended = true;
startInfo.ThreadPoolName = "PoolService";
m_threadPool = new SmartThreadPool(startInfo);
>>>>>>> avn/ubitvar
}
public void Start()
{
<<<<<<< HEAD
IsRunning = true;
if (PerformResponsesAsync)
@@ -139,40 +165,100 @@ namespace OpenSim.Framework.Servers.HttpServer
null,
1000 * 60 * 10);
}
=======
m_threadPool.Start();
//startup worker threads
for (uint i = 0; i < m_WorkerThreadCount; i++)
{
m_workerThreads[i]
= Watchdog.StartThread(
PoolWorkerJob,
string.Format("PollServiceWorkerThread {0}:{1}", i, m_server.Port),
ThreadPriority.Normal,
false,
false,
null,
int.MaxValue);
}
m_retrysThread = Watchdog.StartThread(
this.CheckRetries,
string.Format("PollServiceWatcherThread:{0}", m_server.Port),
ThreadPriority.Normal,
false,
true,
null,
1000 * 60 * 10);
>>>>>>> avn/ubitvar
}
private void ReQueueEvent(PollServiceHttpRequest req)
{
if (IsRunning)
{
// delay the enqueueing for 100ms. There's no need to have the event
// actively on the queue
Timer t = new Timer(self => {
((Timer)self).Dispose();
m_requests.Enqueue(req);
});
t.Change(100, Timeout.Infinite);
lock (m_retryRequests)
m_retryRequests.Enqueue(req);
}
}
public void Enqueue(PollServiceHttpRequest req)
{
if (IsRunning)
lock (m_bycontext)
{
if (req.PollServiceArgs.Type == PollServiceEventArgs.EventType.LongPoll)
Queue<PollServiceHttpRequest> ctxQeueue;
if (m_bycontext.TryGetValue(req, out ctxQeueue))
{
lock (m_longPollRequests)
m_longPollRequests.Add(req);
ctxQeueue.Enqueue(req);
}
else
m_requests.Enqueue(req);
{
ctxQeueue = new Queue<PollServiceHttpRequest>();
m_bycontext[req] = ctxQeueue;
EnqueueInt(req);
}
}
}
private void CheckLongPollThreads()
public void byContextDequeue(PollServiceHttpRequest req)
{
Queue<PollServiceHttpRequest> ctxQeueue;
lock (m_bycontext)
{
if (m_bycontext.TryGetValue(req, out ctxQeueue))
{
if (ctxQeueue.Count > 0)
{
PollServiceHttpRequest newreq = ctxQeueue.Dequeue();
EnqueueInt(newreq);
}
else
{
m_bycontext.Remove(req);
}
}
}
}
public void EnqueueInt(PollServiceHttpRequest req)
{
if (IsRunning)
{
if (req.PollServiceArgs.Type != PollServiceEventArgs.EventType.LongPoll)
{
m_requests.Enqueue(req);
}
else
{
lock (m_slowRequests)
m_slowRequests.Enqueue(req);
}
}
}
private void CheckRetries()
{
<<<<<<< HEAD
// The only purpose of this thread is to check the EQs for events.
// If there are events, that thread will be placed in the "ready-to-serve" queue, m_requests.
// If there are no events, that thread will be back to its "waiting" queue, m_longPollRequests.
@@ -180,13 +266,15 @@ namespace OpenSim.Framework.Servers.HttpServer
// so if they aren't ready to be served by a worker thread (no events), they are placed
// directly back in the "ready-to-serve" queue by the worker thread.
while (IsRunning)
=======
while (m_running)
>>>>>>> avn/ubitvar
{
Thread.Sleep(500);
Thread.Sleep(100); // let the world move .. back to faster rate
Watchdog.UpdateThread();
// List<PollServiceHttpRequest> not_ready = new List<PollServiceHttpRequest>();
lock (m_longPollRequests)
lock (m_retryRequests)
{
<<<<<<< HEAD
if (m_longPollRequests.Count > 0 && IsRunning)
{
List<PollServiceHttpRequest> ready = m_longPollRequests.FindAll(req =>
@@ -199,28 +287,67 @@ namespace OpenSim.Framework.Servers.HttpServer
m_requests.Enqueue(req);
m_longPollRequests.Remove(req);
});
=======
while (m_retryRequests.Count > 0 && m_running)
m_requests.Enqueue(m_retryRequests.Dequeue());
}
slowCount++;
if (slowCount >= 10)
{
slowCount = 0;
>>>>>>> avn/ubitvar
lock (m_slowRequests)
{
while (m_slowRequests.Count > 0 && m_running)
m_requests.Enqueue(m_slowRequests.Dequeue());
}
}
}
}
public void Stop()
{
<<<<<<< HEAD
IsRunning = false;
// m_timeout = -10000; // cause all to expire
=======
m_running = false;
>>>>>>> avn/ubitvar
Thread.Sleep(1000); // let the world move
foreach (Thread t in m_workerThreads)
Watchdog.AbortThread(t.ManagedThreadId);
PollServiceHttpRequest wreq;
// any entry in m_bycontext should have a active request on the other queues
// so just delete contents to easy GC
foreach (Queue<PollServiceHttpRequest> qu in m_bycontext.Values)
qu.Clear();
m_bycontext.Clear();
lock (m_longPollRequests)
try
{
foreach (PollServiceHttpRequest req in m_retryRequests)
{
req.DoHTTPstop(m_server);
}
}
catch
{
}
PollServiceHttpRequest wreq;
m_retryRequests.Clear();
lock (m_slowRequests)
{
<<<<<<< HEAD
if (m_longPollRequests.Count > 0 && IsRunning)
m_longPollRequests.ForEach(req => m_requests.Enqueue(req));
=======
while (m_slowRequests.Count > 0)
m_requests.Enqueue(m_slowRequests.Dequeue());
>>>>>>> avn/ubitvar
}
while (m_requests.Count() > 0)
@@ -228,16 +355,19 @@ namespace OpenSim.Framework.Servers.HttpServer
try
{
wreq = m_requests.Dequeue(0);
<<<<<<< HEAD
ResponsesProcessed++;
wreq.DoHTTPGruntWork(
m_server, wreq.PollServiceArgs.NoEvents(wreq.RequestID, wreq.PollServiceArgs.Id));
=======
wreq.DoHTTPstop(m_server);
>>>>>>> avn/ubitvar
}
catch
{
}
}
m_longPollRequests.Clear();
m_requests.Clear();
}
@@ -247,6 +377,11 @@ namespace OpenSim.Framework.Servers.HttpServer
{
while (IsRunning)
{
<<<<<<< HEAD
=======
PollServiceHttpRequest req = m_requests.Dequeue(5000);
>>>>>>> avn/ubitvar
Watchdog.UpdateThread();
WaitPerformResponse();
}
@@ -265,6 +400,7 @@ namespace OpenSim.Framework.Servers.HttpServer
{
Hashtable responsedata = req.PollServiceArgs.GetEvents(req.RequestID, req.PollServiceArgs.Id);
<<<<<<< HEAD
if (responsedata == null)
return;
@@ -287,11 +423,15 @@ namespace OpenSim.Framework.Servers.HttpServer
else
{
m_threadPool.QueueWorkItem(x =>
=======
if (req.PollServiceArgs.Type == PollServiceEventArgs.EventType.LongPoll) // This is the event queue
>>>>>>> avn/ubitvar
{
try
{
ResponsesProcessed++;
req.DoHTTPGruntWork(m_server, responsedata);
byContextDequeue(req);
}
catch (ObjectDisposedException e) // Browser aborted before we could read body, server closed the stream
{
@@ -300,6 +440,7 @@ namespace OpenSim.Framework.Servers.HttpServer
}
catch (Exception e)
{
<<<<<<< HEAD
m_log.Error(e);
}
@@ -318,6 +459,34 @@ namespace OpenSim.Framework.Servers.HttpServer
else
{
ReQueueEvent(req);
=======
try
{
req.DoHTTPGruntWork(m_server, responsedata);
byContextDequeue(req);
}
catch (ObjectDisposedException) // Browser aborted before we could read body, server closed the stream
{
// Ignore it, no need to reply
}
return null;
}, null);
}
}
else
{
if ((Environment.TickCount - req.RequestTime) > req.PollServiceArgs.TimeOutms)
{
req.DoHTTPGruntWork(m_server,
req.PollServiceArgs.NoEvents(req.RequestID, req.PollServiceArgs.Id));
byContextDequeue(req);
}
else
{
ReQueueEvent(req);
}
>>>>>>> avn/ubitvar
}
}
}
@@ -327,5 +496,7 @@ namespace OpenSim.Framework.Servers.HttpServer
}
}
}
}
}
}