recover GetMesh2 cap
parent
cc7a241cbc
commit
0ba13b9b00
|
@ -41,9 +41,6 @@ using OpenSim.Framework.Servers.HttpServer;
|
||||||
using OpenSim.Services.Interfaces;
|
using OpenSim.Services.Interfaces;
|
||||||
using Caps = OpenSim.Framework.Capabilities.Caps;
|
using Caps = OpenSim.Framework.Capabilities.Caps;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
namespace OpenSim.Capabilities.Handlers
|
namespace OpenSim.Capabilities.Handlers
|
||||||
{
|
{
|
||||||
public class GetMeshHandler
|
public class GetMeshHandler
|
||||||
|
@ -61,145 +58,99 @@ namespace OpenSim.Capabilities.Handlers
|
||||||
}
|
}
|
||||||
public Hashtable Handle(Hashtable request)
|
public Hashtable Handle(Hashtable request)
|
||||||
{
|
{
|
||||||
Hashtable ret = new Hashtable();
|
return ProcessGetMesh(request, UUID.Zero, null); ;
|
||||||
ret["int_response_code"] = (int)System.Net.HttpStatusCode.NotFound;
|
|
||||||
ret["content_type"] = "text/plain";
|
|
||||||
ret["int_bytes"] = 0;
|
|
||||||
string MeshStr = (string)request["mesh_id"];
|
|
||||||
|
|
||||||
|
|
||||||
//m_log.DebugFormat("[GETMESH]: called {0}", MeshStr);
|
|
||||||
|
|
||||||
if (m_assetService == null)
|
|
||||||
{
|
|
||||||
m_log.Error("[GETMESH]: Cannot fetch mesh " + MeshStr + " without an asset service");
|
|
||||||
ret["keepalive"] = false;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
UUID meshID;
|
|
||||||
if (!String.IsNullOrEmpty(MeshStr) && UUID.TryParse(MeshStr, out meshID))
|
|
||||||
{
|
|
||||||
// m_log.DebugFormat("[GETMESH]: Received request for mesh id {0}", meshID);
|
|
||||||
|
|
||||||
|
|
||||||
ret = ProcessGetMesh(request, UUID.Zero, null);
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_log.Warn("[GETMESH]: Failed to parse a mesh_id from GetMesh request: " + (string)request["uri"]);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Hashtable ProcessGetMesh(Hashtable request, UUID AgentId, Caps cap)
|
public Hashtable ProcessGetMesh(Hashtable request, UUID AgentId, Caps cap)
|
||||||
{
|
{
|
||||||
Hashtable responsedata = new Hashtable();
|
Hashtable responsedata = new Hashtable();
|
||||||
responsedata["int_response_code"] = 400; //501; //410; //404;
|
if (m_assetService == null)
|
||||||
|
{
|
||||||
|
responsedata["int_response_code"] = (int)System.Net.HttpStatusCode.ServiceUnavailable;
|
||||||
|
responsedata["str_response_string"] = "The asset service is unavailable";
|
||||||
|
responsedata["keepalive"] = false;
|
||||||
|
return responsedata;
|
||||||
|
}
|
||||||
|
|
||||||
|
responsedata["int_response_code"] = (int)System.Net.HttpStatusCode.BadRequest;
|
||||||
responsedata["content_type"] = "text/plain";
|
responsedata["content_type"] = "text/plain";
|
||||||
responsedata["int_bytes"] = 0;
|
responsedata["int_bytes"] = 0;
|
||||||
|
|
||||||
string meshStr = string.Empty;
|
string meshStr = string.Empty;
|
||||||
|
|
||||||
if (request.ContainsKey("mesh_id"))
|
if (request.ContainsKey("mesh_id"))
|
||||||
meshStr = request["mesh_id"].ToString();
|
meshStr = request["mesh_id"].ToString();
|
||||||
|
|
||||||
|
if (String.IsNullOrEmpty(meshStr))
|
||||||
|
return responsedata;
|
||||||
|
|
||||||
UUID meshID = UUID.Zero;
|
UUID meshID = UUID.Zero;
|
||||||
if (!String.IsNullOrEmpty(meshStr) && UUID.TryParse(meshStr, out meshID))
|
if(!UUID.TryParse(meshStr, out meshID))
|
||||||
|
return responsedata;
|
||||||
|
|
||||||
|
AssetBase mesh = m_assetService.Get(meshID.ToString());
|
||||||
|
if(mesh == null)
|
||||||
{
|
{
|
||||||
if (m_assetService == null)
|
responsedata["int_response_code"] = (int)System.Net.HttpStatusCode.NotFound;
|
||||||
{
|
responsedata["str_response_string"] = "Mesh not found.";
|
||||||
responsedata["int_response_code"] = 404; //501; //410; //404;
|
return responsedata;
|
||||||
responsedata["keepalive"] = false;
|
|
||||||
responsedata["str_response_string"] = "The asset service is unavailable. So is your mesh.";
|
|
||||||
return responsedata;
|
|
||||||
}
|
|
||||||
|
|
||||||
AssetBase mesh = m_assetService.Get(meshID.ToString());
|
|
||||||
|
|
||||||
if (mesh != null)
|
|
||||||
{
|
|
||||||
if (mesh.Type == (SByte)AssetType.Mesh)
|
|
||||||
{
|
|
||||||
Hashtable headers = new Hashtable();
|
|
||||||
responsedata["headers"] = headers;
|
|
||||||
|
|
||||||
string range = String.Empty;
|
|
||||||
|
|
||||||
if (((Hashtable)request["headers"])["range"] != null)
|
|
||||||
range = (string)((Hashtable)request["headers"])["range"];
|
|
||||||
|
|
||||||
else if (((Hashtable)request["headers"])["Range"] != null)
|
|
||||||
range = (string)((Hashtable)request["headers"])["Range"];
|
|
||||||
|
|
||||||
if (!String.IsNullOrEmpty(range)) // Mesh Asset LOD // Physics
|
|
||||||
{
|
|
||||||
// Range request
|
|
||||||
int start, end;
|
|
||||||
if (TryParseRange(range, out start, out end))
|
|
||||||
{
|
|
||||||
// Before clamping start make sure we can satisfy it in order to avoid
|
|
||||||
// sending back the last byte instead of an error status
|
|
||||||
if (start >= mesh.Data.Length)
|
|
||||||
{
|
|
||||||
responsedata["int_response_code"] = 404; //501; //410; //404;
|
|
||||||
responsedata["content_type"] = "text/plain";
|
|
||||||
responsedata["str_response_string"] = "This range doesnt exist.";
|
|
||||||
return responsedata;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
end = Utils.Clamp(end, 0, mesh.Data.Length - 1);
|
|
||||||
start = Utils.Clamp(start, 0, end);
|
|
||||||
int len = end - start + 1;
|
|
||||||
|
|
||||||
//m_log.Debug("Serving " + start + " to " + end + " of " + texture.Data.Length + " bytes for texture " + texture.ID);
|
|
||||||
responsedata["int_response_code"] =
|
|
||||||
(int)System.Net.HttpStatusCode.PartialContent;
|
|
||||||
headers["Content-Range"] = String.Format("bytes {0}-{1}/{2}", start, end, mesh.Data.Length);
|
|
||||||
|
|
||||||
byte[] d = new byte[len];
|
|
||||||
Array.Copy(mesh.Data, start, d, 0, len);
|
|
||||||
responsedata["bin_response_data"] = d;
|
|
||||||
responsedata["int_bytes"] = len;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_log.Warn("[GETMESH]: Failed to parse a range from GetMesh request, sending full asset: " + (string)request["uri"]);
|
|
||||||
responsedata["str_response_string"] = Convert.ToBase64String(mesh.Data);
|
|
||||||
responsedata["content_type"] = "application/vnd.ll.mesh";
|
|
||||||
responsedata["int_response_code"] = 200;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
responsedata["str_response_string"] = Convert.ToBase64String(mesh.Data);
|
|
||||||
responsedata["content_type"] = "application/vnd.ll.mesh";
|
|
||||||
responsedata["int_response_code"] = 200;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Optionally add additional mesh types here
|
|
||||||
else
|
|
||||||
{
|
|
||||||
responsedata["int_response_code"] = 404; //501; //410; //404;
|
|
||||||
responsedata["content_type"] = "text/plain";
|
|
||||||
responsedata["str_response_string"] = "Unfortunately, this asset isn't a mesh.";
|
|
||||||
return responsedata;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
responsedata["int_response_code"] = 404; //501; //410; //404;
|
|
||||||
responsedata["content_type"] = "text/plain";
|
|
||||||
responsedata["str_response_string"] = "Your Mesh wasn't found. Sorry!";
|
|
||||||
return responsedata;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mesh.Type != (SByte)AssetType.Mesh)
|
||||||
|
{
|
||||||
|
responsedata["str_response_string"] = "Asset isn't a mesh.";
|
||||||
|
return responsedata;
|
||||||
|
}
|
||||||
|
|
||||||
|
Hashtable headers = new Hashtable();
|
||||||
|
responsedata["headers"] = headers;
|
||||||
|
|
||||||
|
string range = String.Empty;
|
||||||
|
|
||||||
|
if (((Hashtable)request["headers"])["range"] != null)
|
||||||
|
range = (string)((Hashtable)request["headers"])["range"];
|
||||||
|
else if (((Hashtable)request["headers"])["Range"] != null)
|
||||||
|
range = (string)((Hashtable)request["headers"])["Range"];
|
||||||
|
|
||||||
|
if (String.IsNullOrEmpty(range))
|
||||||
|
{
|
||||||
|
// full mesh
|
||||||
|
responsedata["str_response_string"] = Convert.ToBase64String(mesh.Data);
|
||||||
|
responsedata["content_type"] = "application/vnd.ll.mesh";
|
||||||
|
responsedata["int_response_code"] = (int)System.Net.HttpStatusCode.OK;
|
||||||
|
return responsedata;
|
||||||
|
}
|
||||||
|
|
||||||
|
// range request
|
||||||
|
int start, end;
|
||||||
|
if (TryParseRange(range, out start, out end))
|
||||||
|
{
|
||||||
|
// Before clamping start make sure we can satisfy it in order to avoid
|
||||||
|
// sending back the last byte instead of an error status
|
||||||
|
if (start >= mesh.Data.Length)
|
||||||
|
{
|
||||||
|
responsedata["str_response_string"] = "This range doesnt exist.";
|
||||||
|
return responsedata;
|
||||||
|
}
|
||||||
|
|
||||||
|
end = Utils.Clamp(end, 0, mesh.Data.Length - 1);
|
||||||
|
start = Utils.Clamp(start, 0, end);
|
||||||
|
int len = end - start + 1;
|
||||||
|
|
||||||
|
//m_log.Debug("Serving " + start + " to " + end + " of " + texture.Data.Length + " bytes for texture " + texture.ID);
|
||||||
|
responsedata["int_response_code"] = (int)System.Net.HttpStatusCode.PartialContent;
|
||||||
|
headers["Content-Range"] = String.Format("bytes {0}-{1}/{2}", start, end, mesh.Data.Length);
|
||||||
|
|
||||||
|
byte[] d = new byte[len];
|
||||||
|
Array.Copy(mesh.Data, start, d, 0, len);
|
||||||
|
responsedata["bin_response_data"] = d;
|
||||||
|
responsedata["int_bytes"] = len;
|
||||||
|
return responsedata;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_log.Warn("[GETMESH]: Failed to parse a range from GetMesh request, sending full asset: " + (string)request["uri"]);
|
||||||
|
responsedata["str_response_string"] = Convert.ToBase64String(mesh.Data);
|
||||||
|
responsedata["content_type"] = "application/vnd.ll.mesh";
|
||||||
|
responsedata["int_response_code"] = (int)System.Net.HttpStatusCode.OK;
|
||||||
return responsedata;
|
return responsedata;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -56,10 +56,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
private Scene m_scene;
|
private Scene m_scene;
|
||||||
private bool m_Enabled = true;
|
private bool m_Enabled = true;
|
||||||
private string m_URL;
|
private string m_URL;
|
||||||
|
|
||||||
private string m_URL2;
|
private string m_URL2;
|
||||||
private string m_RedirectURL = null;
|
|
||||||
private string m_RedirectURL2 = null;
|
|
||||||
|
|
||||||
class APollRequest
|
class APollRequest
|
||||||
{
|
{
|
||||||
|
@ -81,12 +78,11 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
private IAssetService m_assetService = null;
|
private IAssetService m_assetService = null;
|
||||||
|
|
||||||
private Dictionary<UUID, string> m_capsDict = new Dictionary<UUID, string>();
|
private Dictionary<UUID, string> m_capsDict = new Dictionary<UUID, string>();
|
||||||
|
private Dictionary<UUID, string> m_capsDict2 = new Dictionary<UUID, string>();
|
||||||
private static Thread[] m_workerThreads = null;
|
private static Thread[] m_workerThreads = null;
|
||||||
private static int m_NumberScenes = 0;
|
private static int m_NumberScenes = 0;
|
||||||
private static BlockingCollection<APollRequest> m_queue = new BlockingCollection<APollRequest>();
|
private static BlockingCollection<APollRequest> m_queue = new BlockingCollection<APollRequest>();
|
||||||
|
|
||||||
private Dictionary<UUID, PollServiceMeshEventArgs> m_pollservices = new Dictionary<UUID, PollServiceMeshEventArgs>();
|
|
||||||
|
|
||||||
#region Region Module interfaceBase Members
|
#region Region Module interfaceBase Members
|
||||||
|
|
||||||
public Type ReplaceableInterface
|
public Type ReplaceableInterface
|
||||||
|
@ -103,19 +99,12 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
m_URL = config.GetString("Cap_GetMesh", string.Empty);
|
m_URL = config.GetString("Cap_GetMesh", string.Empty);
|
||||||
// Cap doesn't exist
|
// Cap doesn't exist
|
||||||
if (m_URL != string.Empty)
|
if (m_URL != string.Empty)
|
||||||
{
|
|
||||||
m_Enabled = true;
|
m_Enabled = true;
|
||||||
m_RedirectURL = config.GetString("GetMeshRedirectURL");
|
|
||||||
}
|
|
||||||
|
|
||||||
m_URL2 = config.GetString("Cap_GetMesh2", string.Empty);
|
m_URL2 = config.GetString("Cap_GetMesh2", string.Empty);
|
||||||
// Cap doesn't exist
|
// Cap doesn't exist
|
||||||
if (m_URL2 != string.Empty)
|
if (m_URL2 != string.Empty)
|
||||||
{
|
|
||||||
m_Enabled = true;
|
m_Enabled = true;
|
||||||
|
|
||||||
m_RedirectURL2 = config.GetString("GetMesh2RedirectURL");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddRegion(Scene pScene)
|
public void AddRegion(Scene pScene)
|
||||||
|
@ -146,6 +135,12 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
{
|
{
|
||||||
m_assetService = m_scene.RequestModuleInterface<IAssetService>();
|
m_assetService = m_scene.RequestModuleInterface<IAssetService>();
|
||||||
// We'll reuse the same handler for all requests.
|
// We'll reuse the same handler for all requests.
|
||||||
|
if(m_assetService == null)
|
||||||
|
{
|
||||||
|
m_Enabled = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
m_getMeshHandler = new GetMeshHandler(m_assetService);
|
m_getMeshHandler = new GetMeshHandler(m_assetService);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -355,49 +350,58 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
|
|
||||||
public void RegisterCaps(UUID agentID, Caps caps)
|
public void RegisterCaps(UUID agentID, Caps caps)
|
||||||
{
|
{
|
||||||
// UUID capID = UUID.Random();
|
string hostName = m_scene.RegionInfo.ExternalHostName;
|
||||||
|
uint port = (MainServer.Instance == null) ? 0 : MainServer.Instance.Port;
|
||||||
|
string protocol = "http";
|
||||||
|
if (MainServer.Instance.UseSSL)
|
||||||
|
{
|
||||||
|
hostName = MainServer.Instance.SSLCommonName;
|
||||||
|
port = MainServer.Instance.SSLPort;
|
||||||
|
protocol = "https";
|
||||||
|
}
|
||||||
|
|
||||||
if (m_URL == "localhost")
|
if (m_URL == "localhost")
|
||||||
{
|
{
|
||||||
string capUrl = "/CAPS/" + UUID.Random() + "/";
|
string capUrl = "/CAPS/" + UUID.Random() + "/";
|
||||||
|
|
||||||
// Register this as a poll service
|
// Register this as a poll service
|
||||||
PollServiceMeshEventArgs args = new PollServiceMeshEventArgs(capUrl, agentID, m_scene);
|
PollServiceMeshEventArgs args = new PollServiceMeshEventArgs(capUrl, agentID, m_scene);
|
||||||
|
|
||||||
args.Type = PollServiceEventArgs.EventType.Mesh;
|
args.Type = PollServiceEventArgs.EventType.Mesh;
|
||||||
MainServer.Instance.AddPollServiceHTTPHandler(capUrl, args);
|
MainServer.Instance.AddPollServiceHTTPHandler(capUrl, args);
|
||||||
|
|
||||||
string hostName = m_scene.RegionInfo.ExternalHostName;
|
|
||||||
uint port = (MainServer.Instance == null) ? 0 : MainServer.Instance.Port;
|
|
||||||
string protocol = "http";
|
|
||||||
|
|
||||||
if (MainServer.Instance.UseSSL)
|
|
||||||
{
|
|
||||||
hostName = MainServer.Instance.SSLCommonName;
|
|
||||||
port = MainServer.Instance.SSLPort;
|
|
||||||
protocol = "https";
|
|
||||||
}
|
|
||||||
caps.RegisterHandler("GetMesh", String.Format("{0}://{1}:{2}{3}", protocol, hostName, port, capUrl));
|
caps.RegisterHandler("GetMesh", String.Format("{0}://{1}:{2}{3}", protocol, hostName, port, capUrl));
|
||||||
m_pollservices[agentID] = args;
|
|
||||||
m_capsDict[agentID] = capUrl;
|
m_capsDict[agentID] = capUrl;
|
||||||
}
|
}
|
||||||
else
|
else if (m_URL != string.Empty)
|
||||||
{
|
|
||||||
caps.RegisterHandler("GetMesh", m_URL);
|
caps.RegisterHandler("GetMesh", m_URL);
|
||||||
|
|
||||||
|
if (m_URL2 == "localhost")
|
||||||
|
{
|
||||||
|
string capUrl = "/CAPS/" + UUID.Random() + "/";
|
||||||
|
|
||||||
|
// Register this as a poll service
|
||||||
|
PollServiceMeshEventArgs args = new PollServiceMeshEventArgs(capUrl, agentID, m_scene);
|
||||||
|
args.Type = PollServiceEventArgs.EventType.Mesh;
|
||||||
|
MainServer.Instance.AddPollServiceHTTPHandler(capUrl, args);
|
||||||
|
caps.RegisterHandler("GetMesh2", String.Format("{0}://{1}:{2}{3}", protocol, hostName, port, capUrl));
|
||||||
|
m_capsDict2[agentID] = capUrl;
|
||||||
}
|
}
|
||||||
|
else if(m_URL2 != string.Empty)
|
||||||
|
caps.RegisterHandler("GetMesh2", m_URL2);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DeregisterCaps(UUID agentID, Caps caps)
|
private void DeregisterCaps(UUID agentID, Caps caps)
|
||||||
{
|
{
|
||||||
string capUrl;
|
string capUrl;
|
||||||
PollServiceMeshEventArgs args;
|
|
||||||
if (m_capsDict.TryGetValue(agentID, out capUrl))
|
if (m_capsDict.TryGetValue(agentID, out capUrl))
|
||||||
{
|
{
|
||||||
MainServer.Instance.RemoveHTTPHandler("", capUrl);
|
MainServer.Instance.RemovePollServiceHTTPHandler("", capUrl);
|
||||||
m_capsDict.Remove(agentID);
|
m_capsDict.Remove(agentID);
|
||||||
}
|
}
|
||||||
if (m_pollservices.TryGetValue(agentID, out args))
|
if (m_capsDict2.TryGetValue(agentID, out capUrl))
|
||||||
{
|
{
|
||||||
m_pollservices.Remove(agentID);
|
MainServer.Instance.RemovePollServiceHTTPHandler("", capUrl);
|
||||||
|
m_capsDict2.Remove(agentID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -791,6 +791,7 @@
|
||||||
Cap_GetDisplayNames = "localhost"
|
Cap_GetDisplayNames = "localhost"
|
||||||
Cap_GetTexture = "localhost"
|
Cap_GetTexture = "localhost"
|
||||||
Cap_GetMesh = "localhost"
|
Cap_GetMesh = "localhost"
|
||||||
|
Cap_GetMesh2 = "localhost"
|
||||||
Cap_GetObjectCost = ""
|
Cap_GetObjectCost = ""
|
||||||
Cap_GetObjectPhysicsData = ""
|
Cap_GetObjectPhysicsData = ""
|
||||||
Cap_GroupProposalBallot = ""
|
Cap_GroupProposalBallot = ""
|
||||||
|
|
Loading…
Reference in New Issue