123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437 |
- using System;
- using System.Collections;
- using System.IO;
- using System.Net;
- using System.Text;
- using System.Threading;
- using OpenMetaverse;
- using OpenMetaverse.StructuredData;
- using OpenSim.Framework;
- using OpenSim.Framework.Capabilities;
- using OpenSim.Region.Framework.Scenes;
- using OpenSim.Framework.Servers.HttpServer;
- using OSDMap = OpenMetaverse.StructuredData.OSDMap;
- namespace OpenSim.Region.ClientStack.Linden
- {
- public delegate UUID UpdateItem(UUID itemID, UUID objectID, byte[] data);
- public delegate UUID ItemUpdatedCallback(UUID userID, UUID itemID, UUID objectID, byte[] data);
- public partial class BunchOfCaps
- {
- public void UpdateNotecardItemAsset(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse, OSDMap map)
- {
- UpdateInventoryItemAsset(httpRequest, httpResponse, map, (byte)AssetType.Notecard);
- }
- public void UpdateAnimSetItemAsset(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse, OSDMap map)
- {
- //UpdateInventoryItemAsset(httpRequest, httpResponse, map, CustomInventoryType.AnimationSet);
- }
- public void UpdateScriptItemAsset(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse, OSDMap map)
- {
- UpdateInventoryItemAsset(httpRequest, httpResponse, map, (byte)AssetType.LSLText);
- }
- public void UpdateSettingsItemAsset(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse, OSDMap map)
- {
- UpdateInventoryItemAsset(httpRequest, httpResponse, map, (byte)AssetType.Settings);
- }
- public void UpdateMaterialItemAsset(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse, OSDMap map)
- {
- UpdateInventoryItemAsset(httpRequest, httpResponse, map, (byte)AssetType.Material);
- }
- public void UpdateGestureItemAsset(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse, OSDMap map)
- {
- UpdateInventoryItemAsset(httpRequest, httpResponse, map, (byte)AssetType.Gesture);
- }
- private void UpdateInventoryItemAsset(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse, OSDMap map, byte atype, bool taskSript = false)
- {
- m_log.Debug("[CAPS]: UpdateInventoryItemAsset Request in region: " + m_regionName + "\n");
- httpResponse.StatusCode = (int)HttpStatusCode.OK;
- UUID itemID = UUID.Zero;
- UUID objectID = UUID.Zero;
- try
- {
- if (map.TryGetValue("item_id", out OSD itmp))
- itemID = itmp;
- if (map.TryGetValue("task_id", out OSD tmp))
- objectID = tmp;
- }
- catch { }
- if (itemID.IsZero())
- {
- LLSDAssetUploadError error = new LLSDAssetUploadError();
- error.message = "failed to recode request";
- error.identifier = UUID.Zero;
- httpResponse.RawBuffer = Util.UTF8NBGetbytes(LLSDHelpers.SerialiseLLSDReply(error));
- return;
- }
- if (!objectID.IsZero())
- {
- SceneObjectPart sop = m_Scene.GetSceneObjectPart(objectID);
- if (sop == null)
- {
- LLSDAssetUploadError error = new LLSDAssetUploadError();
- error.message = "object not found";
- error.identifier = UUID.Zero;
- httpResponse.RawBuffer = Util.UTF8NBGetbytes(LLSDHelpers.SerialiseLLSDReply(error));
- return;
- }
- if (!m_Scene.Permissions.CanEditObjectInventory(objectID, m_AgentID))
- {
- LLSDAssetUploadError error = new LLSDAssetUploadError();
- error.message = "No permissions to edit objec";
- error.identifier = UUID.Zero;
- httpResponse.RawBuffer = Util.UTF8NBGetbytes(LLSDHelpers.SerialiseLLSDReply(error));
- return;
- }
- }
- string uploaderPath = GetNewCapPath();
- string protocol = m_HostCapsObj.SSLCaps ? "https://" : "http://";
- string uploaderURL = protocol + m_HostCapsObj.HostName + ":" + m_HostCapsObj.Port.ToString() + uploaderPath;
- LLSDAssetUploadResponse uploadResponse = new LLSDAssetUploadResponse();
- uploadResponse.uploader = uploaderURL;
- uploadResponse.state = "upload";
- ItemUpdater uploader = new ItemUpdater(itemID, objectID, atype, uploaderPath, m_HostCapsObj.HttpListener, m_dumpAssetsToFile);
- uploader.m_remoteAdress = httpRequest.RemoteIPEndPoint.Address;
- uploader.OnUpLoad += ItemUpdated;
- var uploaderHandler = new SimpleBinaryHandler("POST", uploaderPath, uploader.process);
- uploaderHandler.MaxDataSize = 10000000; // change per asset type?
-
- m_HostCapsObj.HttpListener.AddSimpleStreamHandler(uploaderHandler);
- // m_log.InfoFormat("[CAPS]: UpdateAgentInventoryAsset response: {0}",
- // LLSDHelpers.SerialiseLLSDReply(uploadResponse)));
- httpResponse.RawBuffer = Util.UTF8NBGetbytes(LLSDHelpers.SerialiseLLSDReply(uploadResponse));
- }
- /// <summary>
- /// Called when new asset data for an inventory item update has been uploaded.
- /// </summary>
- /// <param name="itemID">Item to update</param>
- /// <param name="data">New asset data</param>
- /// <returns></returns>
- public UUID ItemUpdated(UUID itemID, UUID objectID, byte[] data)
- {
- if (ItemUpdatedCall != null)
- {
- return ItemUpdatedCall(m_HostCapsObj.AgentID, itemID, objectID, data);
- }
- return UUID.Zero;
- }
- /// <summary>
- /// Called by the script task update handler. Provides a URL to which the client can upload a new asset.
- /// </summary>
- /// <param name="httpRequest">HTTP request header object</param>
- /// <param name="httpResponse">HTTP response header object</param>
- /// <returns></returns>
- public void UpdateScriptTaskInventory(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse, OSDMap map)
- {
- httpResponse.StatusCode = (int)HttpStatusCode.OK;
- try
- {
- //m_log.Debug("[CAPS]: ScriptTaskInventory Request in region: " + m_regionName);
- //m_log.DebugFormat("[CAPS]: request: {0}, path: {1}, param: {2}", request, path, param);
- UUID itemID = UUID.Zero;
- UUID objectID = UUID.Zero;
- bool is_script_running = false;
- OSD tmp;
- try
- {
- if (map.TryGetValue("item_id", out tmp))
- itemID = tmp;
- if (map.TryGetValue("task_id", out tmp))
- objectID = tmp;
- if (map.TryGetValue("is_script_running", out tmp))
- is_script_running = tmp;
- }
- catch { }
- if (itemID.IsZero() || objectID.IsZero())
- {
- LLSDAssetUploadError error = new LLSDAssetUploadError();
- error.message = "failed to recode request";
- error.identifier = UUID.Zero;
- httpResponse.RawBuffer = Util.UTF8NBGetbytes(LLSDHelpers.SerialiseLLSDReply(error));
- return;
- }
- SceneObjectPart sop = m_Scene.GetSceneObjectPart(objectID);
- if (sop == null)
- {
- LLSDAssetUploadError error = new LLSDAssetUploadError();
- error.message = "object not found";
- error.identifier = UUID.Zero;
- httpResponse.RawBuffer = Util.UTF8NBGetbytes(LLSDHelpers.SerialiseLLSDReply(error));
- return;
- }
- if (!m_Scene.Permissions.CanEditObjectInventory(objectID, m_AgentID))
- {
- LLSDAssetUploadError error = new LLSDAssetUploadError();
- error.message = "No permissions to edit objec";
- error.identifier = UUID.Zero;
- httpResponse.RawBuffer = Util.UTF8NBGetbytes(LLSDHelpers.SerialiseLLSDReply(error));
- return;
- }
- if (!m_Scene.Permissions.CanEditScript(itemID, objectID, m_AgentID))
- {
- LLSDAssetUploadError error = new LLSDAssetUploadError();
- error.message = "No permissions to edit script";
- error.identifier = UUID.Zero;
- httpResponse.RawBuffer = Util.UTF8NBGetbytes(LLSDHelpers.SerialiseLLSDReply(error));
- return;
- }
- string uploaderPath = GetNewCapPath();
- string protocol = m_HostCapsObj.SSLCaps ? "https://" : "http://";
- string uploaderURL = protocol + m_HostCapsObj.HostName + ":" + m_HostCapsObj.Port.ToString() + uploaderPath;
- LLSDAssetUploadResponse uploadResponse = new LLSDAssetUploadResponse();
- uploadResponse.uploader = uploaderURL;
- uploadResponse.state = "upload";
- TaskInventoryScriptUpdater uploader = new TaskInventoryScriptUpdater(itemID, objectID, is_script_running,
- uploaderPath, m_HostCapsObj.HttpListener, httpRequest.RemoteIPEndPoint.Address, m_dumpAssetsToFile);
- uploader.OnUpLoad += TaskScriptUpdated;
- var uploaderHandler = new SimpleBinaryHandler("POST", uploaderPath, uploader.process);
- uploaderHandler.MaxDataSize = 10000000; // change per asset type?
- m_HostCapsObj.HttpListener.AddSimpleStreamHandler(uploaderHandler);
- // m_log.InfoFormat("[CAPS]: " +
- // "ScriptTaskInventory response: {0}",
- // LLSDHelpers.SerialiseLLSDReply(uploadResponse)));
- httpResponse.RawBuffer = Util.UTF8NBGetbytes(LLSDHelpers.SerialiseLLSDReply(uploadResponse));
- }
- catch (Exception e)
- {
- m_log.Error("[UpdateScriptTaskInventory]: " + e.ToString());
- }
- }
- /// <summary>
- /// Called when new asset data for an agent inventory item update has been uploaded.
- /// </summary>
- /// <param name="itemID">Item to update</param>
- /// <param name="primID">Prim containing item to update</param>
- /// <param name="isScriptRunning">Signals whether the script to update is currently running</param>
- /// <param name="data">New asset data</param>
- public void TaskScriptUpdated(UUID itemID, UUID primID, bool isScriptRunning, byte[] data, ref ArrayList errors)
- {
- if (TaskScriptUpdatedCall != null)
- {
- ArrayList e = TaskScriptUpdatedCall(m_HostCapsObj.AgentID, itemID, primID, isScriptRunning, data);
- foreach (Object item in e)
- errors.Add(item);
- }
- }
- static public bool ValidateAssetData(byte assetType, byte[] data)
- {
- return true;
- }
- /// <summary>
- /// This class is a callback invoked when a client sends asset data to
- /// an agent inventory notecard update url
- /// </summary>
- public class ItemUpdater : ExpiringCapBase
- {
- public event UpdateItem OnUpLoad = null;
- private UUID m_inventoryItemID;
- private UUID m_objectID;
- private bool m_dumpAssetToFile;
- public IPAddress m_remoteAdress;
- private byte m_assetType;
- public ItemUpdater(UUID inventoryItem, UUID objectid, byte aType, string path, IHttpServer httpServer, bool dumpAssetToFile):
- base(httpServer, path)
- {
- m_dumpAssetToFile = dumpAssetToFile;
- m_inventoryItemID = inventoryItem;
- m_objectID = objectid;
- m_httpListener = httpServer;
- m_assetType = aType;
- Start(30000);
- }
- /// <summary>
- /// Handle raw uploaded asset data.
- /// </summary>
- /// <param name="data"></param>
- /// <param name="path"></param>
- /// <param name="param"></param>
- /// <returns></returns>
- public void process(IOSHttpRequest request, IOSHttpResponse response, byte[] data)
- {
- Stop();
- if (!request.RemoteIPEndPoint.Address.Equals(m_remoteAdress))
- {
- response.StatusCode = (int)HttpStatusCode.Unauthorized;
- return;
- }
- string res = String.Empty;
- if (OnUpLoad == null)
- {
- response.StatusCode = (int)HttpStatusCode.Gone;
- return;
- }
- if (!BunchOfCaps.ValidateAssetData(m_assetType, data))
- {
- response.StatusCode = (int)HttpStatusCode.BadRequest;
- return;
- }
- UUID assetID = OnUpLoad(m_inventoryItemID, m_objectID, data);
- if (assetID.IsZero())
- {
- LLSDAssetUploadError uperror = new LLSDAssetUploadError();
- uperror.message = "Failed to update inventory item asset";
- uperror.identifier = m_inventoryItemID;
- res = LLSDHelpers.SerialiseLLSDReply(uperror);
- }
- else
- {
- LLSDAssetUploadComplete uploadComplete = new LLSDAssetUploadComplete();
- uploadComplete.new_asset = assetID.ToString();
- uploadComplete.new_inventory_item = m_inventoryItemID;
- uploadComplete.state = "complete";
- res = LLSDHelpers.SerialiseLLSDReply(uploadComplete);
- }
- if (m_dumpAssetToFile)
- {
- Util.SaveAssetToFile("updateditem" + Random.Shared.Next(1, 1000) + ".dat", data);
- }
- response.StatusCode = (int)HttpStatusCode.OK;
- response.RawBuffer = Util.UTF8NBGetbytes(res);
- }
- }
- /// <summary>
- /// This class is a callback invoked when a client sends asset data to
- /// a task inventory script update url
- /// </summary>
- public class TaskInventoryScriptUpdater : ExpiringCapBase
- {
- public event UpdateTaskScript OnUpLoad;
- private UUID m_inventoryItemID;
- private UUID m_primID;
- private bool m_isScriptRunning;
- private bool m_dumpAssetToFile;
- public IPAddress m_remoteAddress;
- public TaskInventoryScriptUpdater(UUID inventoryItemID, UUID primID, bool isScriptRunning,
- string path, IHttpServer httpServer, IPAddress address,
- bool dumpAssetToFile) : base(httpServer, path)
- {
- m_dumpAssetToFile = dumpAssetToFile;
- m_inventoryItemID = inventoryItemID;
- m_primID = primID;
- m_isScriptRunning = isScriptRunning;
- m_remoteAddress = address;
- Start(30000);
- }
- /// <summary>
- ///
- /// </summary>
- /// <param name="data"></param>
- /// <param name="path"></param>
- /// <param name="param"></param>
- /// <returns></returns>
- public void process(IOSHttpRequest request, IOSHttpResponse response, byte[] data)
- {
- Stop();
- if (!request.RemoteIPEndPoint.Address.Equals(m_remoteAddress))
- {
- response.StatusCode = (int)HttpStatusCode.Unauthorized;
- return;
- }
- if (OnUpLoad == null)
- {
- response.StatusCode = (int)HttpStatusCode.Gone;
- return;
- }
- if (!BunchOfCaps.ValidateAssetData((byte)AssetType.LSLText, data))
- {
- response.StatusCode = (int)HttpStatusCode.BadRequest;
- return;
- }
- response.StatusCode = (int)HttpStatusCode.OK;
- try
- {
- string res = String.Empty;
- LLSDTaskScriptUploadComplete uploadComplete = new LLSDTaskScriptUploadComplete();
- ArrayList errors = new ArrayList();
- OnUpLoad?.Invoke(m_inventoryItemID, m_primID, m_isScriptRunning, data, ref errors);
- uploadComplete.new_asset = m_inventoryItemID;
- uploadComplete.compiled = errors.Count > 0 ? false : true;
- uploadComplete.state = "complete";
- uploadComplete.errors = new OpenSim.Framework.Capabilities.OSDArray();
- uploadComplete.errors.Array = errors;
- res = LLSDHelpers.SerialiseLLSDReply(uploadComplete);
- if (m_dumpAssetToFile)
- {
- Util.SaveAssetToFile("updatedtaskscript" + Random.Shared.Next(1, 1000) + ".dat", data);
- }
- // m_log.InfoFormat("[CAPS]: TaskInventoryScriptUpdater.uploaderCaps res: {0}", res);
- response.RawBuffer = Util.UTF8NBGetbytes(res);
- }
- catch
- {
- LLSDAssetUploadError error = new LLSDAssetUploadError();
- error.message = "could not compile script";
- error.identifier = UUID.Zero;
- response.RawBuffer = Util.UTF8NBGetbytes(LLSDHelpers.SerialiseLLSDReply(error));
- return;
- }
- }
- }
- }
- }
|