ReferenceFrontendPlugin.cs 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369
  1. /*
  2. * Copyright (c) Contributors, http://opensimulator.org/
  3. * See CONTRIBUTORS.TXT for a full list of copyright holders.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions are met:
  7. * * Redistributions of source code must retain the above copyright
  8. * notice, this list of conditions and the following disclaimer.
  9. * * Redistributions in binary form must reproduce the above copyright
  10. * notice, this list of conditions and the following disclaimer in the
  11. * documentation and/or other materials provided with the distribution.
  12. * * Neither the name of the OpenSimulator Project nor the
  13. * names of its contributors may be used to endorse or promote products
  14. * derived from this software without specific prior written permission.
  15. *
  16. * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
  17. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  18. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  19. * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
  20. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  21. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  22. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  23. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  24. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  25. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  26. */
  27. using System;
  28. using System.IO;
  29. using System.Reflection;
  30. using System.Net;
  31. using OpenMetaverse;
  32. using OpenMetaverse.StructuredData;
  33. using OpenSim.Framework;
  34. using OpenSim.Framework.Servers;
  35. using OpenSim.Framework.Servers.HttpServer;
  36. using log4net;
  37. namespace OpenSim.Grid.AssetInventoryServer.Plugins
  38. {
  39. public class ReferenceFrontendPlugin : IAssetInventoryServerPlugin
  40. {
  41. private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
  42. AssetInventoryServer m_server;
  43. public ReferenceFrontendPlugin()
  44. {
  45. }
  46. #region IPlugin implementation
  47. public void Initialise(AssetInventoryServer server)
  48. {
  49. m_server = server;
  50. // Asset metadata request
  51. //m_server.HttpServer.AddStreamHandler(new MetadataRequestHandler(server));
  52. // Asset data request
  53. m_server.HttpServer.AddStreamHandler(new DataRequestHandler(server));
  54. // Asset creation
  55. //m_server.HttpServer.AddStreamHandler(new CreateRequestHandler(server));
  56. m_log.Info("[REFERENCEFRONTEND]: Reference Frontend loaded.");
  57. }
  58. /// <summary>
  59. /// <para>Initialises asset interface</para>
  60. /// </summary>
  61. public void Initialise()
  62. {
  63. m_log.InfoFormat("[REFERENCEFRONTEND]: {0} cannot be default-initialized!", Name);
  64. throw new PluginNotInitialisedException(Name);
  65. }
  66. public void Dispose()
  67. {
  68. }
  69. public string Version
  70. {
  71. // TODO: this should be something meaningful and not hardcoded?
  72. get { return "0.1"; }
  73. }
  74. public string Name
  75. {
  76. get { return "ReferenceFrontend"; }
  77. }
  78. #endregion IPlugin implementation
  79. //public class MetadataRequestHandler : IStreamedRequestHandler
  80. //{
  81. // AssetInventoryServer m_server;
  82. // string m_contentType;
  83. // string m_httpMethod;
  84. // string m_path;
  85. // public MetadataRequestHandler(AssetInventoryServer server)
  86. // {
  87. // m_server = server;
  88. // m_contentType = null;
  89. // m_httpMethod = "GET";
  90. // m_path = @"^/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/metadata";
  91. // }
  92. // #region IStreamedRequestHandler implementation
  93. // public string ContentType
  94. // {
  95. // get { return m_contentType; }
  96. // }
  97. // public string HttpMethod
  98. // {
  99. // get { return m_httpMethod; }
  100. // }
  101. // public string Path
  102. // {
  103. // get { return m_path; }
  104. // }
  105. // public byte[] Handle(string path, Stream request, OSHttpRequest httpRequest, OSHttpResponse httpResponse)
  106. // {
  107. // byte[] serializedData = null;
  108. // UUID assetID;
  109. // // Split the URL up into an AssetID and a method
  110. // string[] rawUrl = httpRequest.Url.PathAndQuery.Split('/');
  111. // if (rawUrl.Length >= 3 && UUID.TryParse(rawUrl[1], out assetID))
  112. // {
  113. // UUID authToken = Utils.GetAuthToken(httpRequest);
  114. // if (m_server.AuthorizationProvider.IsMetadataAuthorized(authToken, assetID))
  115. // {
  116. // AssetMetadata metadata;
  117. // BackendResponse storageResponse = m_server.StorageProvider.TryFetchMetadata(assetID, out metadata);
  118. // if (storageResponse == BackendResponse.Success)
  119. // {
  120. // // If the asset data location wasn't specified in the metadata, specify it
  121. // // manually here by pointing back to this asset server
  122. // if (!metadata.Methods.ContainsKey("data"))
  123. // {
  124. // metadata.Methods["data"] = new Uri(String.Format("{0}://{1}/{2}/data",
  125. // httpRequest.Url.Scheme, httpRequest.Url.Authority, assetID));
  126. // }
  127. // serializedData = metadata.SerializeToBytes();
  128. // httpResponse.StatusCode = (int) HttpStatusCode.OK;
  129. // httpResponse.ContentType = "application/json";
  130. // httpResponse.ContentLength = serializedData.Length;
  131. // httpResponse.Body.Write(serializedData, 0, serializedData.Length);
  132. // }
  133. // else if (storageResponse == BackendResponse.NotFound)
  134. // {
  135. // m_log.Warn("[REFERENCEFRONTEND]: Could not find metadata for asset " + assetID.ToString());
  136. // httpResponse.StatusCode = (int) HttpStatusCode.NotFound;
  137. // }
  138. // else
  139. // {
  140. // httpResponse.StatusCode = (int) HttpStatusCode.InternalServerError;
  141. // }
  142. // }
  143. // else
  144. // {
  145. // httpResponse.StatusCode = (int) HttpStatusCode.Forbidden;
  146. // }
  147. // return serializedData;
  148. // }
  149. // httpResponse.StatusCode = (int) HttpStatusCode.NotFound;
  150. // return serializedData;
  151. // }
  152. // #endregion IStreamedRequestHandler implementation
  153. //}
  154. public class DataRequestHandler : IStreamedRequestHandler
  155. {
  156. AssetInventoryServer m_server;
  157. string m_contentType;
  158. string m_httpMethod;
  159. string m_path;
  160. public DataRequestHandler(AssetInventoryServer server)
  161. {
  162. m_server = server;
  163. m_contentType = null;
  164. m_httpMethod = "GET";
  165. m_path = @"^/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/data";
  166. }
  167. #region IStreamedRequestHandler implementation
  168. public string ContentType
  169. {
  170. get { return m_contentType; }
  171. }
  172. public string HttpMethod
  173. {
  174. get { return m_httpMethod; }
  175. }
  176. public string Path
  177. {
  178. get { return m_path; }
  179. }
  180. public byte[] Handle(string path, Stream request, OSHttpRequest httpRequest, OSHttpResponse httpResponse)
  181. {
  182. byte[] assetData = null;
  183. UUID assetID;
  184. // Split the URL up into an AssetID and a method
  185. string[] rawUrl = httpRequest.Url.PathAndQuery.Split('/');
  186. if (rawUrl.Length >= 3 && UUID.TryParse(rawUrl[1], out assetID))
  187. {
  188. UUID authToken = Utils.GetAuthToken(httpRequest);
  189. if (m_server.AuthorizationProvider.IsDataAuthorized(authToken, assetID))
  190. {
  191. BackendResponse storageResponse = m_server.StorageProvider.TryFetchData(assetID, out assetData);
  192. if (storageResponse == BackendResponse.Success)
  193. {
  194. httpResponse.StatusCode = (int) HttpStatusCode.OK;
  195. httpResponse.ContentType = "application/octet-stream";
  196. httpResponse.AddHeader("Content-Disposition", "attachment; filename=" + assetID.ToString());
  197. httpResponse.ContentLength = assetData.Length;
  198. httpResponse.Body.Write(assetData, 0, assetData.Length);
  199. }
  200. else if (storageResponse == BackendResponse.NotFound)
  201. {
  202. httpResponse.StatusCode = (int) HttpStatusCode.NotFound;
  203. }
  204. else
  205. {
  206. httpResponse.StatusCode = (int) HttpStatusCode.InternalServerError;
  207. }
  208. }
  209. else
  210. {
  211. httpResponse.StatusCode = (int) HttpStatusCode.Forbidden;
  212. }
  213. return assetData;
  214. }
  215. httpResponse.StatusCode = (int) HttpStatusCode.BadRequest;
  216. return assetData;
  217. }
  218. #endregion IStreamedRequestHandler implementation
  219. }
  220. //public class CreateRequestHandler : IStreamedRequestHandler
  221. //{
  222. // AssetInventoryServer m_server;
  223. // string m_contentType;
  224. // string m_httpMethod;
  225. // string m_path;
  226. // public CreateRequestHandler(AssetInventoryServer server)
  227. // {
  228. // m_server = server;
  229. // m_contentType = null;
  230. // m_httpMethod = "POST";
  231. // m_path = "^/createasset";
  232. // }
  233. // #region IStreamedRequestHandler implementation
  234. // public string ContentType
  235. // {
  236. // get { return m_contentType; }
  237. // }
  238. // public string HttpMethod
  239. // {
  240. // get { return m_httpMethod; }
  241. // }
  242. // public string Path
  243. // {
  244. // get { return m_path; }
  245. // }
  246. // public byte[] Handle(string path, Stream request, OSHttpRequest httpRequest, OSHttpResponse httpResponse)
  247. // {
  248. // byte[] responseData = null;
  249. // UUID authToken = Utils.GetAuthToken(httpRequest);
  250. // if (m_server.AuthorizationProvider.IsCreateAuthorized(authToken))
  251. // {
  252. // try
  253. // {
  254. // OSD osdata = OSDParser.DeserializeJson(new StreamReader(httpRequest.InputStream).ReadToEnd());
  255. // if (osdata.Type == OSDType.Map)
  256. // {
  257. // OSDMap map = (OSDMap)osdata;
  258. // Metadata metadata = new Metadata();
  259. // metadata.Deserialize(map);
  260. // byte[] assetData = map["data"].AsBinary();
  261. // if (assetData != null && assetData.Length > 0)
  262. // {
  263. // BackendResponse storageResponse;
  264. // if (metadata.ID != UUID.Zero)
  265. // storageResponse = m_server.StorageProvider.TryCreateAsset(metadata, assetData);
  266. // else
  267. // storageResponse = m_server.StorageProvider.TryCreateAsset(metadata, assetData, out metadata.ID);
  268. // if (storageResponse == BackendResponse.Success)
  269. // {
  270. // httpResponse.StatusCode = (int) HttpStatusCode.Created;
  271. // OSDMap responseMap = new OSDMap(1);
  272. // responseMap["id"] = OSD.FromUUID(metadata.ID);
  273. // LitJson.JsonData jsonData = OSDParser.SerializeJson(responseMap);
  274. // responseData = System.Text.Encoding.UTF8.GetBytes(jsonData.ToJson());
  275. // httpResponse.Body.Write(responseData, 0, responseData.Length);
  276. // httpResponse.Body.Flush();
  277. // }
  278. // else if (storageResponse == BackendResponse.NotFound)
  279. // {
  280. // httpResponse.StatusCode = (int) HttpStatusCode.NotFound;
  281. // }
  282. // else
  283. // {
  284. // httpResponse.StatusCode = (int) HttpStatusCode.InternalServerError;
  285. // }
  286. // }
  287. // else
  288. // {
  289. // httpResponse.StatusCode = (int) HttpStatusCode.BadRequest;
  290. // }
  291. // }
  292. // else
  293. // {
  294. // httpResponse.StatusCode = (int) HttpStatusCode.BadRequest;
  295. // }
  296. // }
  297. // catch (Exception ex)
  298. // {
  299. // httpResponse.StatusCode = (int) HttpStatusCode.InternalServerError;
  300. // httpResponse.StatusDescription = ex.Message;
  301. // }
  302. // }
  303. // else
  304. // {
  305. // httpResponse.StatusCode = (int) HttpStatusCode.Forbidden;
  306. // }
  307. // return responseData;
  308. // }
  309. // #endregion IStreamedRequestHandler implementation
  310. //}
  311. }
  312. }