avoid a data copy

0.9.1.0-post-fixes
UbitUmarov 2018-12-02 16:17:23 +00:00
parent 7a4d8017d7
commit ca754b0156
2 changed files with 69 additions and 68 deletions

View File

@ -139,22 +139,21 @@ namespace OpenSim.Capabilities.Handlers
// if(type != AssetType.Mesh && type != AssetType.Texture) // if(type != AssetType.Mesh && type != AssetType.Texture)
// m_log.Warn("[GETASSETS]: type: " + query); // m_log.Warn("[GETASSETS]: type: " + query);
responsedata["content_type"] = asset.Metadata.ContentType;
responsedata["bin_response_data"] = asset.Data;
responsedata["int_bytes"] = asset.Data.Length;
responsedata["int_response_code"] = (int)System.Net.HttpStatusCode.OK;
string range = String.Empty; string range = String.Empty;
if (((Hashtable)request["headers"])["range"] != null) if (((Hashtable)request["headers"])["range"] != null)
range = (string)((Hashtable)request["headers"])["range"]; range = (string)((Hashtable)request["headers"])["range"];
else if (((Hashtable)request["headers"])["Range"] != null) else if (((Hashtable)request["headers"])["Range"] != null)
range = (string)((Hashtable)request["headers"])["Range"]; range = (string)((Hashtable)request["headers"])["Range"];
else
responsedata["content_type"] = asset.Metadata.ContentType; return responsedata; // full asset
if (String.IsNullOrEmpty(range)) if (String.IsNullOrEmpty(range))
{ return responsedata; // full asset
// full asset
responsedata["bin_response_data"] = asset.Data;
responsedata["int_bytes"] = asset.Data.Length;
responsedata["int_response_code"] = (int)System.Net.HttpStatusCode.OK;
return responsedata;
}
// range request // range request
int start, end; int start, end;
@ -181,18 +180,12 @@ namespace OpenSim.Capabilities.Handlers
headers["Content-Range"] = String.Format("bytes {0}-{1}/{2}", start, end, asset.Data.Length); headers["Content-Range"] = String.Format("bytes {0}-{1}/{2}", start, end, asset.Data.Length);
responsedata["headers"] = headers; responsedata["headers"] = headers;
responsedata["int_response_code"] = (int)System.Net.HttpStatusCode.PartialContent; responsedata["int_response_code"] = (int)System.Net.HttpStatusCode.PartialContent;
responsedata["bin_start"] = start;
byte[] d = new byte[len];
Array.Copy(asset.Data, start, d, 0, len);
responsedata["bin_response_data"] = d;
responsedata["int_bytes"] = len; responsedata["int_bytes"] = len;
return responsedata; return responsedata;
} }
m_log.Warn("[GETASSETS]: Failed to parse a range, sending full asset: " + assetStr); m_log.Warn("[GETASSETS]: Failed to parse a range, sending full asset: " + assetStr);
responsedata["bin_response_data"] = asset.Data;
responsedata["int_bytes"] = asset.Data.Length;
responsedata["int_response_code"] = (int)System.Net.HttpStatusCode.OK;
return responsedata; return responsedata;
} }
} }

View File

@ -81,44 +81,18 @@ namespace OpenSim.Framework.Servers.HttpServer
internal void DoHTTPGruntWork(Hashtable responsedata) internal void DoHTTPGruntWork(Hashtable responsedata)
{ {
if (Request.Body.CanRead)
Request.Body.Dispose();
OSHttpResponse response OSHttpResponse response
= new OSHttpResponse(new HttpResponse(HttpContext, Request), HttpContext); = new OSHttpResponse(new HttpResponse(HttpContext, Request), HttpContext);
byte[] buffer = srvDoHTTPGruntWork(responsedata, response); int responsecode = 200;
if(Request.Body.CanRead)
Request.Body.Dispose();
response.SendChunked = false;
response.ContentLength64 = buffer.Length;
try
{
response.OutputStream.Write(buffer, 0, buffer.Length);
response.Send();
buffer = null;
}
catch (Exception ex)
{
if(ex is System.Net.Sockets.SocketException)
{
// only mute connection reset by peer so we are not totally blind for now
if(((System.Net.Sockets.SocketException)ex).SocketErrorCode != System.Net.Sockets.SocketError.ConnectionReset)
m_log.Warn("[POLL SERVICE WORKER THREAD]: Error ", ex);
}
else
m_log.Warn("[POLL SERVICE WORKER THREAD]: Error ", ex);
}
PollServiceArgs.RequestsHandled++;
}
internal byte[] srvDoHTTPGruntWork(Hashtable responsedata, OSHttpResponse response)
{
int responsecode;
string responseString = String.Empty; string responseString = String.Empty;
byte[] responseBytes = null;
string contentType; string contentType;
byte[] buffer = null;
int rangeStart = 0;
int rangeLen = -1;
if (responsedata == null) if (responsedata == null)
{ {
@ -132,12 +106,23 @@ namespace OpenSim.Framework.Servers.HttpServer
try try
{ {
//m_log.Info("[BASE HTTP SERVER]: Doing HTTP Grunt work with response"); //m_log.Info("[BASE HTTP SERVER]: Doing HTTP Grunt work with response");
responsecode = (int)responsedata["int_response_code"]; if(responsedata["int_response_code"] != null)
responsecode = (int)responsedata["int_response_code"];
if (responsedata["bin_response_data"] != null) if (responsedata["bin_response_data"] != null)
responseBytes = (byte[])responsedata["bin_response_data"]; {
buffer = (byte[])responsedata["bin_response_data"];
responsedata["bin_response_data"] = null;
if (responsedata["bin_start"] != null)
rangeStart = (int)responsedata["bin_start"];
if (responsedata["int_bytes"] != null)
rangeLen = (int)responsedata["int_bytes"];
}
else else
responseString = (string)responsedata["str_response_string"]; responseString = (string)responsedata["str_response_string"];
contentType = (string)responsedata["content_type"]; contentType = (string)responsedata["content_type"];
if (responseString == null) if (responseString == null)
responseString = String.Empty; responseString = String.Empty;
@ -159,7 +144,6 @@ namespace OpenSim.Framework.Servers.HttpServer
{ {
response.ProtocolVersion = (string)responsedata["http_protocol_version"]; response.ProtocolVersion = (string)responsedata["http_protocol_version"];
} }
if (responsedata.ContainsKey("keepalive")) if (responsedata.ContainsKey("keepalive"))
{ {
bool keepalive = (bool)responsedata["keepalive"]; bool keepalive = (bool)responsedata["keepalive"];
@ -170,13 +154,6 @@ namespace OpenSim.Framework.Servers.HttpServer
if (responsedata.ContainsKey("access_control_allow_origin")) if (responsedata.ContainsKey("access_control_allow_origin"))
response.AddHeader("Access-Control-Allow-Origin", (string)responsedata["access_control_allow_origin"]); response.AddHeader("Access-Control-Allow-Origin", (string)responsedata["access_control_allow_origin"]);
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; response.StatusCode = responsecode;
if (responsecode == (int)OSHttpStatusCode.RedirectMovedPermanently) if (responsecode == (int)OSHttpStatusCode.RedirectMovedPermanently)
@ -184,7 +161,11 @@ namespace OpenSim.Framework.Servers.HttpServer
response.RedirectLocation = (string)responsedata["str_redirect_location"]; response.RedirectLocation = (string)responsedata["str_redirect_location"];
} }
response.AddHeader("Content-Type", contentType); if (string.IsNullOrEmpty(contentType))
response.AddHeader("Content-Type", "text/html");
else
response.AddHeader("Content-Type", contentType);
if (responsedata.ContainsKey("headers")) if (responsedata.ContainsKey("headers"))
{ {
Hashtable headerdata = (Hashtable)responsedata["headers"]; Hashtable headerdata = (Hashtable)responsedata["headers"];
@ -193,13 +174,7 @@ namespace OpenSim.Framework.Servers.HttpServer
response.AddHeader(header, headerdata[header].ToString()); response.AddHeader(header, headerdata[header].ToString());
} }
byte[] buffer; if(buffer == null)
if (responseBytes != null)
{
buffer = responseBytes;
}
else
{ {
if (!(contentType.Contains("image") if (!(contentType.Contains("image")
|| contentType.Contains("x-shockwave-flash") || contentType.Contains("x-shockwave-flash")
@ -217,8 +192,41 @@ namespace OpenSim.Framework.Servers.HttpServer
response.ContentEncoding = Encoding.UTF8; response.ContentEncoding = Encoding.UTF8;
} }
return buffer; if (rangeStart < 0 || rangeStart > buffer.Length)
rangeStart = 0;
if (rangeLen < 0)
rangeLen = buffer.Length;
else if (rangeLen + rangeStart > buffer.Length)
rangeLen = buffer.Length - rangeStart;
response.SendChunked = false;
response.ContentLength64 = rangeLen;
try
{
if(rangeLen > 0)
response.OutputStream.Write(buffer, rangeStart, rangeLen);
buffer = null;
response.Send();
}
catch (Exception ex)
{
if(ex is System.Net.Sockets.SocketException)
{
// only mute connection reset by peer so we are not totally blind for now
if(((System.Net.Sockets.SocketException)ex).SocketErrorCode != System.Net.Sockets.SocketError.ConnectionReset)
m_log.Warn("[POLL SERVICE WORKER THREAD]: Error ", ex);
}
else
m_log.Warn("[POLL SERVICE WORKER THREAD]: Error ", ex);
}
PollServiceArgs.RequestsHandled++;
} }
internal void DoHTTPstop() internal void DoHTTPstop()
{ {
OSHttpResponse response OSHttpResponse response