/*
*
* http://mvcresourceloader.codeplex.com/license
*
* */
using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using System.Text;
using Everest.Library.Providers.Caching;
using Yahoo.Yui.Compressor;
using Everest.Library.Mvc;
namespace InteSoft.Web.ExternalResourceLoader{
/// <summary>
/// changed by hjf.
/// Cache the section to avoid AppDomain restart when changed the file.
/// </summary>
public class ExternalResourceController : EverestControllerBase
{
volatile static object resourceLockHelper = new object();
public ExternalResourceController()
{
TempDataProvider = new NullTempDataProvider();
}
[NonAction]
public static void RegisterRoutes(RouteCollection routes)
{
routes.MapRoute(
"ExternalResource",
"ExternalResource/{name}/{version}/{display}/{condition}",
new { controller = "ExternalResource", action = "Index", condition = "" }
);
}
[NonAction]
public static void RegisterRoutes(RouteCollection routes, string rootFolder)
{
routes.MapRoute(
"ExternalResource",
rootFolder,
new { controller = "ExternalResource", action = "Index" }
);
}
public void Index(string name, string version, Action display, string condition)
{
HttpResponseBase response = Response;
LoaderConfigurationSection section = ConfigManager.GetSection();
if (section == null)
{
throw new HttpException(500, "Unable to find any external resource settings.");
//response.StatusCode = 500;
//response.StatusDescription = "Unable to find any external resource settings.";
//response.End();
//return;
}
ReferenceElement settings = section.References[name];
if (settings == null)
{
throw new HttpException(500, string.Format("Unable to find any matching external resource settings for {0}.", name));
}
Condition conditionInfo = new Condition
{
Action = display,
If = condition ?? string.Empty
};
// Ooutput Type
response.ContentType = settings.MimeType;
Stream output = response.OutputStream;
// Compress
if (section.Compress)
{
string acceptEncoding = Request.Headers["Accept-Encoding"];
if (!string.IsNullOrEmpty(acceptEncoding))
{
acceptEncoding = acceptEncoding.ToLowerInvariant();
if (acceptEncoding.Contains("gzip"))
{
response.AddHeader("Content-encoding", "gzip");
output = new GZipStream(output, CompressionMode.Compress);
}
else if (acceptEncoding.Contains("deflate"))
{
response.AddHeader("Content-encoding", "deflate");
output = new DeflateStream(output, CompressionMode.Compress);
}
}
}
// Combine
using (StreamWriter sw = new StreamWriter(output))
{
string content = GetContent(name, version, display, condition, section, settings, conditionInfo);
if (!string.IsNullOrEmpty(content))
{
sw.WriteLine(content.Trim());
}
}
// Cache
if (section.CacheDuration > 0)
{
DateTime timestamp = HttpContext.Timestamp;
HttpCachePolicyBase cache = response.Cache;
int duration = section.CacheDuration;
cache.SetCacheability(HttpCacheability.Public);
//add SetNoServerCaching by hjf.
cache.SetNoServerCaching();
cache.SetExpires(timestamp.AddSeconds(duration));
cache.SetMaxAge(new TimeSpan(0, 0, duration));
cache.SetValidUntilExpires(true);
cache.SetLastModified(timestamp);
cache.VaryByHeaders["Accept-Encoding"] = true;
cache.VaryByParams["name"] = true;
cache.VaryByParams["version"] = true;
cache.VaryByParams["display"] = true;
cache.VaryByParams["condition"] = true;
cache.SetOmitVaryStar(true);
}
}
private string GetContent(string name, string version, Action display, string condition, LoaderConfigurationSection section, ReferenceElement settings, Condition conditionInfo)
{
string cacheKey = string.Format("Resource_Name:{0}_Version:{1}_Display:{2}_Condition:{3}", name, version, display, condition);
if (CacheManager.Get(cacheKey) == null)
{
lock (resourceLockHelper)
{
if (CacheManager.Get(cacheKey) == null)
{
StringBuilder stringBuilder = new StringBuilder();
// filter the files based on the condition (Action / If) passed in
IList<FileInfo> files = new List<FileInfo>();
foreach (FileInfo fileInfo in settings.Files)
{
if (fileInfo.Action.Equals(conditionInfo.Action) && fileInfo.If.Equals(conditionInfo.If))
{
files.Add(fileInfo);
}
}
List<ICacheItemExpiration> dependencies = new List<ICacheItemExpiration>() {
new FileDependency(ConfigManager.ConfigFileName)
};
foreach (FileInfo fileInfo in files)
{
string fileName = Server.MapPath(fileInfo.Filename);
string content = System.IO.File.ReadAllText(fileName);
if (section.Compact)
{
switch (settings.MimeType)
{
case "text/css":
content = (CSSMinify.Minify(Url, fileInfo.Filename, Request.Url.AbsolutePath, content));
break;
case "text/x-javascript":
case "text/javascript":
case "text/ecmascript":
content = (JavaScriptCompressor.Compress(content));
break;
}
}
stringBuilder.Append(content);
dependencies.Add(new FileDependency(fileName));
}
CacheManager.Add(cacheKey, stringBuilder.ToString(), CacheItemPriority.None, null, dependencies.ToArray());
}
}
}
return (string)CacheManager.Get(cacheKey);
}
}
}
|