PageRenderTime 53ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/Univar/StaticStorages/InFileCache.cs

#
C# | 309 lines | 215 code | 46 blank | 48 comment | 27 complexity | 1562b5c3d6fce9945a7c15710da510c5 MD5 | raw file
Possible License(s): CC-BY-SA-3.0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Configuration;
  4. using System.Diagnostics;
  5. using System.IO;
  6. using System.Linq;
  7. using System.Web;
  8. using System.Web.Hosting;
  9. using System.Web.Security;
  10. using System.Web.UI;
  11. using Univar.Helpers;
  12. namespace Univar
  13. {
  14. public static partial class Storage
  15. {
  16. /// <summary>
  17. /// A class that provides in file caching ability on the server.
  18. /// </summary>
  19. public static class InFileCache
  20. {
  21. static object _lockKey = new object();
  22. /// <summary>
  23. /// The upper size limit in bytes for each cache file.
  24. /// Default is 10MB.
  25. /// </summary>
  26. public static double MaximumFileSize = 10 * 1024 * 1024;
  27. public struct InFileCacheData
  28. {
  29. public DateTime? ExpiryDate;
  30. public string Data;
  31. }
  32. public static TimeSpan DefaultLifeTime = TimeSpan.FromDays(100);
  33. /// <summary>
  34. /// Returns the path for the session file. The value can be stored in the
  35. /// web.config. The keys InFileCacheFolderPath and InFileCacheDeployedFolderPath are used
  36. /// to specify the folder path used when running from the IDE or within IIS respectively.
  37. /// The default value for both are ~\UserInFileCaches and c:\UserInFileCaches respectively. Note that
  38. /// the default path used when running the website within IIS is located outside the IIS folder itself.
  39. /// This is to avoid it being overwritten on subsequent builds and to avoid access rights issues.
  40. /// Also when deployed on a server the specified folder needs to be given read/write access rights.
  41. /// </summary>
  42. public static string DefaultFolderPath
  43. {
  44. get
  45. {
  46. //if (SecurityManager.IsGranted( new AspNetHostingPermission(AspNetHostingPermissionLevel.Medium)))
  47. // Return a path depending on whether the website is running from the IDE or from within IIS
  48. if ((StorageUser.Context == null && Debugger.IsAttached)
  49. || (StorageUser.Context != null && string.IsNullOrEmpty(StorageUser.Context.Request.ServerVariables["SERVER_SOFTWARE"])))
  50. return ConfigurationManager.AppSettings.Get("InFileCacheDeployedFolderPath") ?? @"c:\InFileCache";
  51. else
  52. return ConfigurationManager.AppSettings.Get("InFileCacheFolderPath") ?? @"~\InFileCache";
  53. }
  54. }
  55. public static T Get<T>(string key)
  56. {
  57. return Serializer.Deserialize<T>(Get(null, key, false), JsonEncoding.None, true);
  58. }
  59. public static T Get<T>(string key, bool decrypt)
  60. {
  61. return Serializer.Deserialize<T>(Get(null, key, decrypt), JsonEncoding.None, true);
  62. }
  63. public static T Get<T>(string folderPath, string fileName, string key, bool decrypt)
  64. {
  65. return Serializer.Deserialize<T>(Get(folderPath, fileName, key, decrypt), JsonEncoding.None, true);
  66. }
  67. public static string Get(string key)
  68. {
  69. return Get(null, key, false);
  70. }
  71. public static string Get(string key, bool decrypt)
  72. {
  73. string filePath = GetFilePath(key);
  74. return Get(null, filePath, key, decrypt);
  75. }
  76. public static string Get(string folderPath, string key, bool decrypt)
  77. {
  78. string filePath = GetFilePath(folderPath, key);
  79. return Get(folderPath, filePath, key, decrypt);
  80. }
  81. public static string Get(string folderPath, string fileName, string key, bool decrypt)
  82. {
  83. fileName = GetFilePath(folderPath ?? DefaultFolderPath, fileName);
  84. if (!File.Exists(fileName))
  85. return null;
  86. Dictionary<string, InFileCacheData> dictionary;
  87. try
  88. {
  89. dictionary = Serializer.Deserialize<Dictionary<string, InFileCacheData>>(File.ReadAllText(fileName), true);
  90. if (dictionary != null && dictionary.Keys.Contains(key))
  91. {
  92. if (DateTime.Now > (dictionary[key].ExpiryDate ?? DateTime.MaxValue))
  93. Set<object>(folderPath, fileName, key, null, null, false, true);
  94. else
  95. return decrypt
  96. ? CookieEncryptor.Decrypt(dictionary[key].Data, true)
  97. : dictionary[key].Data;
  98. }
  99. }
  100. catch (Exception)
  101. {
  102. return null;
  103. }
  104. return null;
  105. }
  106. public static void Set<T>(string key, T value)
  107. {
  108. Set<T>(null, key, value, null, false, false);
  109. }
  110. public static void Set<T>(string key, T value, bool encrypt)
  111. {
  112. Set<T>(null, key, value, null, encrypt, false);
  113. }
  114. public static void Set<T>(string key, T value, TimeSpan? lifeTime, bool encrypt)
  115. {
  116. Set<T>(null, key, value, lifeTime, encrypt, false);
  117. }
  118. public static void Set<T>(string folderPath, string key, T value, TimeSpan? lifeTime, bool encrypt, bool throwExceptionOnSerializationError)
  119. {
  120. string filePath = GetFilePath(folderPath, key);//, useProfileNameIfAvailable);
  121. Set<T>(folderPath, filePath, value, lifeTime, encrypt, throwExceptionOnSerializationError);
  122. }
  123. public static void Set<T>(string folderPath, string fileName, string key, T value, TimeSpan? lifeTime, bool encrypt, bool throwExceptionOnSerializationError)
  124. {
  125. InFileCacheData InFileCacheData;
  126. string filePath = GetFilePath(folderPath, fileName);
  127. if (filePath == null)
  128. throw new FieldAccessException("session file could not be created under the path " + filePath);
  129. if (!File.Exists(filePath))
  130. {
  131. File.CreateText(filePath).Close();
  132. //AddAccessRights(filePath, "IIS_IUSRS", FileSystemRights.Modify);
  133. }
  134. else
  135. {
  136. if (GetSize(false, folderPath, key) > MaximumFileSize)
  137. Set<object>(folderPath, fileName, key, null, null, false, false);
  138. }
  139. try
  140. {
  141. Dictionary<string, InFileCacheData> dataDictionary =
  142. Serializer.Deserialize<Dictionary<string, InFileCacheData>>(File.ReadAllText(filePath), throwExceptionOnSerializationError);
  143. if (dataDictionary == null)
  144. dataDictionary = new Dictionary<string, InFileCacheData>();
  145. if (value == null)
  146. {
  147. dataDictionary.Remove(key);
  148. }
  149. else
  150. {
  151. InFileCacheData = new InFileCacheData();
  152. if (lifeTime.HasValue)
  153. InFileCacheData.ExpiryDate = DateTime.Now.Add(lifeTime.Value);
  154. InFileCacheData.Data = Serializer.Serialize<T>(value, JsonEncoding.None, throwExceptionOnSerializationError);
  155. if (encrypt)
  156. InFileCacheData.Data = CookieEncryptor.Encrypt(InFileCacheData.Data);
  157. if (dataDictionary.Keys.Contains(key))
  158. dataDictionary[key] = InFileCacheData;
  159. else
  160. dataDictionary.Add(key, InFileCacheData);
  161. }
  162. string strValue = Serializer.Serialize<Dictionary<string, InFileCacheData>>(dataDictionary, JsonEncoding.None, throwExceptionOnSerializationError);
  163. try
  164. {
  165. lock (_lockKey)
  166. {
  167. using (StreamWriter sw = new StreamWriter(filePath, false, System.Text.Encoding.UTF8))
  168. {
  169. sw.Write(strValue.Replace("\r\n", Environment.NewLine));
  170. }
  171. }
  172. }
  173. catch (FieldAccessException ex)
  174. {
  175. throw ex;
  176. }
  177. }
  178. catch (Exception ex)
  179. {
  180. //AddAccessRights(new FileInfo(filePath).Directory.FullName, "IIS_IUSRS", FileSystemRights.Modify);
  181. StorageUser.Context.Response.Write(ex.Message);
  182. throw ex;
  183. }
  184. }
  185. //private static void AddAccessRights(string folderPath, string user, FileSystemRights rights)
  186. //{
  187. // try
  188. // {
  189. // DirectoryInfo folder = new DirectoryInfo(folderPath);
  190. // DirectorySecurity dSecurity = folder.GetAccessControl();
  191. // FileSystemAccessRule fsar = new FileSystemAccessRule(user, rights, AccessControlType.Allow);
  192. // dSecurity.AddAccessRule(fsar);
  193. // folder.SetAccessControl(dSecurity);
  194. // }
  195. // catch (Exception ex)
  196. // {
  197. // //User.Context.Response.Write(ex.Message);
  198. // throw ex;
  199. // }
  200. //}
  201. public static void Remove(string key)
  202. {
  203. Set<object>(key, null);
  204. }
  205. public static void Remove(string key, Scopes scope)
  206. {
  207. key = StorageUser.GetUserKeyByScope(key, scope, null, null);
  208. Set<object>(key, null);
  209. }
  210. //public static string GetUserId(bool useProfileNameIfAvailable)
  211. //{ //page.Request.LogonUserIdentity
  212. // if (useProfileNameIfAvailable && !CacheUser.Context.Profile.IsAnonymous)
  213. // return Membership.GetUser(CacheUser.Context.Profile.UserName).ProviderUserKey.ToString();
  214. // // Get unique user id generated when no profile name was found.
  215. // string userId = Stores.Cookie.Get(CacheUser.DefaultUserNameKey, false, true);
  216. // if (userId != null)
  217. // return userId;
  218. // else // User has no associated record stored on the server.
  219. // return CacheUser.CreateIdentifierCookie();
  220. //}
  221. public static string GetFilePath(string userFileName)
  222. {
  223. return GetFilePath(null, userFileName);
  224. }
  225. public static string GetFilePath(string folderPath, string fileName)
  226. {
  227. folderPath = GetFolder(DefaultFolderPath, true);
  228. return Path.Combine(folderPath, HttpUtility.UrlEncode(fileName) + ".txt");
  229. }
  230. public static string GetFolder(bool createWhenNotFound)
  231. {
  232. return GetFolder(null, createWhenNotFound);
  233. }
  234. public static string GetFolder(string folderPath, bool createWhenNotFound)
  235. {
  236. if (string.IsNullOrEmpty(folderPath))
  237. folderPath = DefaultFolderPath;
  238. if (folderPath.StartsWith("~"))
  239. folderPath = HostingEnvironment.MapPath(folderPath);
  240. if (createWhenNotFound && !Directory.Exists(folderPath))
  241. {
  242. Directory.CreateDirectory(folderPath);
  243. //AddAccessRights(folderPath, "IIS_IUSRS", FileSystemRights.Modify);
  244. }
  245. return folderPath;
  246. }
  247. public static long GetSize(bool shared, string key)
  248. {
  249. return GetSize(shared, null, key);
  250. }
  251. public static long GetSize(bool shared, string folderPath, string key)
  252. {
  253. string userFileName = shared ? key : null;
  254. string filePath = GetFilePath(folderPath, userFileName);
  255. FileInfo file = new FileInfo(filePath);
  256. if (file.Exists)
  257. return file.Length;
  258. else
  259. return -1;
  260. }
  261. }
  262. }
  263. }