using System;
using System.Data;
using System.Collections;
using System.Web;
using System.Web.Caching;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using CMS.GlobalHelper;
using CMS.PortalEngine;
using CMS.SettingsProvider;
using CMS.SiteProvider;
using CMS.DocumentEngine;
using CMS.UIControls;
using CMS.IO;
public partial class CMSPages_GetMetaFile : GetFilePage
{
#region "Advanced settings"
///
/// Sets to false to disable the client caching.
///
protected bool useClientCache = true;
///
/// Sets to 0 if you do not wish to cache large files.
///
protected int largeFilesCacheMinutes = 1;
#endregion
#region "Variables"
protected CMSOutputMetaFile outputFile = null;
protected Guid fileGuid = Guid.Empty;
#endregion
#region "Properties"
///
/// Returns true if the process allows cache.
///
public override bool AllowCache
{
get
{
if (mAllowCache == null)
{
// By default, cache for the metafiles is always enabled (even outside of the live site)
if (ValidationHelper.GetBoolean(SettingsHelper.AppSettings["CMSAlwaysCacheMetaFiles"], true))
{
mAllowCache = true;
}
else
{
mAllowCache = (ViewMode == ViewModeEnum.LiveSite);
}
}
return mAllowCache.Value;
}
set
{
mAllowCache = value;
}
}
#endregion
protected void Page_Load(object sender, EventArgs e)
{
DebugHelper.SetContext("GetMetaFile");
// Load the site name
LoadSiteName();
int cacheMinutes = CacheMinutes;
// Try to get data from cache
using (CachedSection cs = new CachedSection(ref outputFile, cacheMinutes, true, null, "getmetafile", CurrentSiteName, GetBaseCacheKey(), Request.QueryString))
{
if (cs.LoadData)
{
// Process the file
ProcessFile();
if (cs.Cached)
{
// Do not cache if too big file which would be stored in memory
if ((outputFile != null) &&
(outputFile.MetaFile != null) &&
!CacheHelper.CacheImageAllowed(CurrentSiteName, outputFile.MetaFile.MetaFileSize) &&
!AttachmentInfoProvider.StoreFilesInFileSystem(CurrentSiteName))
{
cacheMinutes = largeFilesCacheMinutes;
}
if (cacheMinutes > 0)
{
// Prepare the cache dependency
CacheDependency cd = null;
if (outputFile != null)
{
if (outputFile.MetaFile != null)
{
// Add dependency on this particular meta file
cd = GetCacheDependency(outputFile.MetaFile.GetDependencyCacheKeys());
}
}
if (cd == null)
{
// Set default dependency based on GUID
cd = CacheHelper.GetCacheDependency(new string[] { "metafile|" + fileGuid.ToString().ToLowerCSafe() });
}
cs.CacheDependency = cd;
}
// Cache the data
cs.CacheMinutes = cacheMinutes;
}
cs.Data = outputFile;
}
}
// Send the data
SendFile(outputFile);
DebugHelper.ReleaseContext();
}
///
/// Processes the file.
///
protected void ProcessFile()
{
outputFile = null;
// Get file GUID from querystring
fileGuid = QueryHelper.GetGuid("fileguid", Guid.Empty);
if (fileGuid == Guid.Empty)
{
// Get file GUID from context
fileGuid = ValidationHelper.GetGuid(Context.Items["fileguid"], Guid.Empty);
}
if (fileGuid != Guid.Empty)
{
ProcessFile(fileGuid);
}
}
///
/// Processes the specified file.
///
/// File guid
protected void ProcessFile(Guid fileGuid)
{
// Get the file
MetaFileInfo fileInfo = MetaFileInfoProvider.GetMetaFileInfoWithoutBinary(fileGuid, CurrentSiteName, true);
if (fileInfo != null)
{
bool resizeImage = (ImageHelper.IsImage(fileInfo.MetaFileExtension) && MetaFileInfoProvider.CanResizeImage(fileInfo, Width, Height, MaxSideSize));
// Get the data
if ((outputFile == null) || (outputFile.MetaFile == null))
{
outputFile = NewOutputFile(fileInfo, null);
outputFile.Width = Width;
outputFile.Height = Height;
outputFile.MaxSideSize = MaxSideSize;
outputFile.Resized = resizeImage;
}
}
}
///
/// Sends the given file within response.
///
/// File to send
protected void SendFile(CMSOutputMetaFile file)
{
// Clear response.
CookieHelper.ClearResponseCookies();
Response.Clear();
// Set the revalidation
SetRevalidation();
// Send the file
if (file != null)
{
// Redirect if the file should be redirected
if (file.RedirectTo != "")
{
URLHelper.Redirect(file.RedirectTo, true, CurrentSiteName);
}
string etag = GetFileETag(file);
// Client caching - only on the live site
if (useClientCache && AllowCache && AllowClientCache && ETagsMatch(etag, file.LastModified))
{
// Set the file time stamps to allow client caching
SetTimeStamps(file);
// Ensure correct content type
if (file.MetaFile != null)
{
Response.ContentType = GetResponseContentType(file.MimeType, file.MetaFile.MetaFileExtension);
}
RespondNotModified(etag, true);
return;
}
// If physical file not present, try to load
if (file.PhysicalFile == null)
{
EnsurePhysicalFile(outputFile);
}
// If the output data should be cached, return the output data
bool cacheOutputData = false;
if ((CacheMinutes > 0) && (file.MetaFile != null))
{
cacheOutputData = CacheHelper.CacheImageAllowed(CurrentSiteName, file.MetaFile.MetaFileSize);
}
// Ensure the file data if physical file not present
if (!file.DataLoaded && (file.PhysicalFile == ""))
{
byte[] cachedData = GetCachedOutputData();
if (file.EnsureData(cachedData))
{
if ((cachedData == null) && cacheOutputData)
{
SaveOutputDataToCache(file.OutputData, GetOutputDataDependency(file.MetaFile));
}
}
}
// Send the file
if ((file.OutputData != null) || (file.PhysicalFile != ""))
{
// Setup the mime type - Fix the special types
string mimetype = file.MimeType;
string extension = file.MetaFile.MetaFileExtension;
switch (extension.ToLowerCSafe())
{
case ".flv":
mimetype = "video/x-flv";
break;
}
// Prepare response
Response.ContentType = mimetype;
SetDisposition(file.MetaFile.MetaFileName, extension);
// Setup Etag property
ETag = etag;
// Set if resumable downloads should be supported
AcceptRange = !IsExtensionExcludedFromRanges(extension);
if (useClientCache && AllowCache)
{
// Set the file time stamps to allow client caching
SetTimeStamps(file);
Response.Cache.SetETag(etag);
}
else
{
SetCacheability();
}
// Add the file data
if ((file.PhysicalFile != "") && (file.OutputData == null))
{
if (!File.Exists(file.PhysicalFile))
{
// File doesn't exist
NotFound();
}
else
{
// Stream the file from the file system
file.OutputData = WriteFile(file.PhysicalFile, cacheOutputData);
}
}
else
{
// Use output data of the file in memory if present
WriteBytes(file.OutputData);
}
}
else
{
NotFound();
}
}
else
{
NotFound();
}
CompleteRequest();
}
///
/// Gets the ETag for the given file
///
/// File
private static string GetFileETag(CMSOutputMetaFile file)
{
// Prepare etag
string etag = null;
if (file.MetaFile != null)
{
etag += file.MetaFile.MetaFileID;
}
etag += "|" + file.LastModified;
// Put etag into ""
etag = "\"" + etag + "\"";
return etag;
}
///
/// Sets the last modified and expires header to the response
///
/// Output file data
private void SetTimeStamps(CMSOutputMetaFile file)
{
DateTime expires = DateTime.Now;
// Send last modified header to allow client caching
Response.Cache.SetLastModified(file.LastModified);
Response.Cache.SetCacheability(HttpCacheability.Public);
if (AllowClientCache)
{
expires = DateTime.Now.AddMinutes(ClientCacheMinutes);
}
Response.Cache.SetExpires(expires);
}
///
/// Returns the output data dependency based on the given attachment record.
///
/// Metafile object
protected CacheDependency GetOutputDataDependency(MetaFileInfo mi)
{
if (mi == null)
{
return null;
}
return CacheHelper.GetCacheDependency(mi.GetDependencyCacheKeys());
}
///
/// Ensures the physical file.
///
/// Output file
public bool EnsurePhysicalFile(CMSOutputMetaFile file)
{
if (file == null)
{
return false;
}
// Try to link to file system
if (String.IsNullOrEmpty(file.Watermark) && (file.MetaFile != null) && (file.MetaFile.MetaFileID > 0) && MetaFileInfoProvider.StoreFilesInFileSystem(file.SiteName))
{
string filePath = MetaFileInfoProvider.EnsurePhysicalFile(file.MetaFile, file.SiteName);
if (filePath != null)
{
if (file.Resized)
{
// If resized, ensure the thumbnail file
if (MetaFileInfoProvider.GenerateThumbnails(file.SiteName))
{
filePath = MetaFileInfoProvider.EnsureThumbnailFile(file.MetaFile, file.SiteName, Width, Height, MaxSideSize);
if (filePath != null)
{
// Link to the physical file
file.PhysicalFile = filePath;
return true;
}
}
}
else
{
// Link to the physical file
file.PhysicalFile = filePath;
return false;
}
}
}
file.PhysicalFile = "";
return false;
}
///
/// Gets the new output MetaFile object.
///
public CMSOutputMetaFile NewOutputFile()
{
CMSOutputMetaFile mf = new CMSOutputMetaFile();
mf.Watermark = Watermark;
mf.WatermarkPosition = WatermarkPosition;
return mf;
}
///
/// Gets the new output MetaFile object.
///
/// Meta file info
/// Output MetaFile data
public CMSOutputMetaFile NewOutputFile(MetaFileInfo mfi, byte[] data)
{
CMSOutputMetaFile mf = new CMSOutputMetaFile(mfi, data);
mf.Watermark = Watermark;
mf.WatermarkPosition = WatermarkPosition;
return mf;
}
}