HEX
Server: Microsoft-IIS/8.5
System: Windows NT YDAWBH120 6.3 build 9600 (Windows Server 2012 R2 Standard Edition) AMD64
User: tentjecom_web (0)
PHP: 7.4.14
Disabled: NONE
Upload Files
File: D:/HostingSpaces/RMourik/bassol.nl/CMS/CMSPages/GetFile.aspx.cs
using System;
using System.Collections.Generic;
using System.Web;
using System.Data;

using CMS.DataEngine;
using CMS.Helpers;
using CMS.IO;
using CMS.Localization;
using CMS.PortalEngine;
using CMS.Base;
using CMS.SiteProvider;
using CMS.DocumentEngine;
using CMS.UIControls;
using CMS.WebAnalytics;

public partial class CMSPages_GetFile : GetFilePage
{
    #region "Advanced settings"

    /// <summary>
    /// Sets to false to disable the client caching.
    /// </summary>
    protected bool useClientCache = true;

    /// <summary>
    /// Sets to 0 if you do not wish to cache large files.
    /// </summary>
    protected int largeFilesCacheMinutes = 1;

    #endregion


    #region "Variables"

    protected CMSOutputAttachment outputAttachment = null;

    protected TreeProvider mTreeProvider = null;
    protected GeneralConnection mConnection = null;

    protected TreeNode node = null;
    protected PageInfo pi = null;

    protected int? mVersionHistoryID = null;
    protected bool mIsLatestVersion = false;
    protected bool? mIsLiveSite = null;
    protected Guid guid = Guid.Empty;
    protected string mCulture = null;
    protected Guid nodeGuid = Guid.Empty;

    protected string aliasPath = null;
    protected string fileName = null;

    protected int latestForDocumentId = 0;
    protected int latestForHistoryId = 0;

    protected bool allowLatestVersion = false;

    #endregion


    #region "Properties"

    /// <summary>
    /// Gets the language for current file.
    /// </summary>
    public override string CultureCode
    {
        get
        {
            if (mCulture == null)
            {
                string culture = QueryHelper.GetString(URLHelper.LanguageParameterName, LocalizationContext.PreferredCultureCode);
                if (!CultureSiteInfoProvider.IsCultureAllowed(culture, CurrentSiteName))
                {
                    culture = LocalizationContext.PreferredCultureCode;
                }
                mCulture = culture;
            }

            return mCulture;
        }
    }


    /// <summary>
    /// Tree provider.
    /// </summary>
    public TreeProvider TreeProvider
    {
        get
        {
            return mTreeProvider ?? (mTreeProvider = new TreeProvider());
        }
    }


    /// <summary>
    /// Document version history ID.
    /// </summary>
    public int VersionHistoryID
    {
        get
        {
            if (mVersionHistoryID == null)
            {
                mVersionHistoryID = QueryHelper.GetInteger("versionhistoryid", 0);
            }
            return mVersionHistoryID.Value;
        }
    }


    /// <summary>
    /// Indicates if the file is latest version or comes from version history.
    /// </summary>
    public bool LatestVersion
    {
        get
        {
            return mIsLatestVersion || (VersionHistoryID > 0);
        }
    }


    /// <summary>
    /// Returns true if the process allows cache.
    /// </summary>
    public override bool AllowCache
    {
        get
        {
            if (mAllowCache == null)
            {
                // By default, cache for the files is disabled outside of the live site
                mAllowCache = CacheHelper.AlwaysCacheFiles || IsLiveSite;
            }

            return mAllowCache.Value;
        }
        set
        {
            mAllowCache = value;
        }
    }


    /// <summary>
    /// Cache minutes.
    /// </summary>
    public override int CacheMinutes
    {
        get
        {
            // Use 304 revalidation for non-LiveSite mode, for live side mode keep original values
            if (AllowCache && (PortalContext.ViewMode != ViewModeEnum.LiveSite))
            {
                return 0;
            }
            return base.CacheMinutes;
        }
        set
        {
            base.CacheMinutes = value;
        }
    }

    #endregion


    protected void Page_Load(object sender, EventArgs e)
    {
        DebugHelper.SetContext("GetFile");

        // Load the site name
        LoadSiteName();

        // Check the site
        if (CurrentSiteName == "")
        {
            throw new Exception("[GetFile.aspx]: Site not running.");
        }

        ValidateCulture();

        // Set campaign
        if (IsLiveSite)
        {
            // Store campaign name if present
            string campaign = AnalyticsHelper.CurrentCampaign(CurrentSiteName);
            if (!String.IsNullOrEmpty(campaign) && DocumentContext.CurrentPageInfo != null)
            {
                AnalyticsHelper.SetCampaign(campaign, CurrentSiteName, DocumentContext.CurrentPageInfo.NodeAliasPath);
            }
        }


        int cacheMinutes = CacheMinutes;

        // Try to get data from cache
        using (var cs = new CachedSection<CMSOutputAttachment>(ref outputAttachment, cacheMinutes, true, null, "getfile", CurrentSiteName, GetBaseCacheKey(), Request.QueryString))
        {
            if (cs.LoadData)
            {
                // Store current value and temporary disable caching
                bool cached = cs.Cached;
                cs.Cached = false;

                // Process the file
                ProcessAttachment();

                // Restore cache settings - data were loaded
                cs.Cached = cached;

                if (cs.Cached)
                {
                    // Do not cache if too big file which would be stored in memory
                    if ((outputAttachment != null) &&
                        (outputAttachment.Attachment != null) &&
                        !CacheHelper.CacheImageAllowed(CurrentSiteName, outputAttachment.Attachment.AttachmentSize) &&
                        !AttachmentInfoProvider.StoreFilesInFileSystem(CurrentSiteName))
                    {
                        cacheMinutes = largeFilesCacheMinutes;
                    }

                    if (cacheMinutes > 0)
                    {
                        // Prepare the cache dependency
                        CMSCacheDependency cd = null;
                        if (outputAttachment != null)
                        {
                            List<string> dependencies = new List<string>
                            {
                                                            "node|" + CurrentSiteName.ToLowerCSafe() + "|" + outputAttachment.AliasPath.ToLowerCSafe(),
                                                            ""
                                                        };

                            // Do not cache if too big file which would be stored in memory
                            if (outputAttachment.Attachment != null)
                            {
                                if (!CacheHelper.CacheImageAllowed(CurrentSiteName, outputAttachment.Attachment.AttachmentSize) && !AttachmentInfoProvider.StoreFilesInFileSystem(CurrentSiteName))
                                {
                                    cacheMinutes = largeFilesCacheMinutes;
                                }

                                dependencies.Add("attachment|" + outputAttachment.Attachment.AttachmentGUID.ToString().ToLowerCSafe());
                            }

                            cd = GetCacheDependency(dependencies);
                        }

                        if (cd == null)
                        {
                            // Set default dependency
                            if (guid != Guid.Empty)
                            {
                                // By attachment GUID
                                cd = CacheHelper.GetCacheDependency(new[] { "attachment|" + guid.ToString().ToLowerCSafe() });
                            }
                            else if (nodeGuid != Guid.Empty)
                            {
                                // By node GUID
                                cd = CacheHelper.GetCacheDependency(new[] { "nodeguid|" + CurrentSiteName.ToLowerCSafe() + "|" + nodeGuid.ToString().ToLowerCSafe() });
                            }
                            else if (aliasPath != null)
                            {
                                // By node alias path
                                cd = CacheHelper.GetCacheDependency(new[] { "node|" + CurrentSiteName.ToLowerCSafe() + "|" + aliasPath.ToLowerCSafe() });
                            }
                        }

                        cs.CacheDependency = cd;
                    }

                    // Cache the data
                    cs.CacheMinutes = cacheMinutes;
                }

                cs.Data = outputAttachment;
            }
        }

        // Do not cache images in the browser if cache is not allowed
        if (LatestVersion)
        {
            useClientCache = false;
        }

        // Send the data
        SendFile(outputAttachment);

        DebugHelper.ReleaseContext();
    }


    /// <summary>
    /// Sends the given file within response.
    /// </summary>
    /// <param name="attachment">File to send</param>
    protected void SendFile(CMSOutputAttachment attachment)
    {
        // Clear response.
        CookieHelper.ClearResponseCookies();
        Response.Clear();

        // Set the revalidation
        SetRevalidation();

        // Send the file
        if ((attachment != null) && attachment.IsValid)
        {
            // Redirect if the file should be redirected
            if (attachment.RedirectTo != "")
            {
                // Log hit or activity before redirecting
                LogEvent(attachment);

                if (StorageHelper.IsExternalStorage(attachment.RedirectTo))
                {
                    string url = File.GetFileUrl(attachment.RedirectTo, CurrentSiteName);
                    if (!string.IsNullOrEmpty(url))
                    {
                        URLHelper.RedirectPermanent(url, CurrentSiteName);
                    }
                }

                URLHelper.RedirectPermanent(attachment.RedirectTo, CurrentSiteName);
                return;
            }

            // Check authentication if secured file
            var secured = attachment.IsSecured;
            if (secured)
            {
                PageSecurityHelper.CheckSecured(CurrentSiteName, ViewMode);
            }

            string etag = GetFileETag(attachment);

            // Client caching - only on the live site
            if (useClientCache && AllowCache && AllowClientCache && ETagsMatch(etag, attachment.LastModified))
            {
                // Set correct response content type
                SetResponseContentType(attachment);

                // Set the file time stamps to allow client caching
                SetTimeStamps(attachment.LastModified, !secured);

                RespondNotModified(etag, !secured);
                return;
            }

            // If physical file not present, try to load
            if (attachment.PhysicalFile == null)
            {
                EnsurePhysicalFile(outputAttachment);
            }

            // If the output data should be cached, return the output data
            bool cacheOutputData = false;
            if (attachment.Attachment != null)
            {
                // Cache data if allowed
                if (!LatestVersion && (CacheMinutes > 0))
                {
                    cacheOutputData = CacheHelper.CacheImageAllowed(CurrentSiteName, attachment.Attachment.AttachmentSize);
                }
            }

            // Ensure the file data if physical file not present
            if (!attachment.DataLoaded && (attachment.PhysicalFile == ""))
            {
                byte[] cachedData = GetCachedOutputData();
                if (attachment.EnsureData(cachedData))
                {
                    if ((cachedData == null) && cacheOutputData)
                    {
                        SaveOutputDataToCache(attachment.OutputData, GetOutputDataDependency(attachment.Attachment));
                    }
                }
            }

            // Send the file
            if ((attachment.OutputData != null) || (attachment.PhysicalFile != ""))
            {
                // Set correct response content type
                SetResponseContentType(attachment);

                if (attachment.Attachment != null)
                {
                    string extension = attachment.Attachment.AttachmentExtension;
                    SetDisposition(attachment.Attachment.AttachmentName, 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(attachment.LastModified);

                    Response.Cache.SetETag(etag);
                }
                else
                {
                    SetCacheability();
                }

                // Log hit or activity
                LogEvent(attachment);
                // Add the file data
                if ((attachment.PhysicalFile != "") && (attachment.OutputData == null))
                {
                    if (!File.Exists(attachment.PhysicalFile))
                    {
                        // File doesn't exist
                        NotFound();
                    }
                    else
                    {
                        // Stream the file from the file system
                        attachment.OutputData = WriteFile(attachment.PhysicalFile, cacheOutputData);
                    }
                }
                else
                {
                    // Use output data of the file in memory if present
                    WriteBytes(attachment.OutputData);
                }
            }
            else
            {
                NotFound();
            }
        }
        else
        {
            NotFound();
        }

        CompleteRequest();
    }


    /// <summary>
    /// Sets content type of the response based on file MIME type
    /// </summary>
    /// <param name="attachment">Output file</param>
    private void SetResponseContentType(CMSOutputAttachment attachment)
    {
        string mimeType = attachment.MimeType;
        if (attachment.Attachment != null)
        {
            string extension = attachment.Attachment.AttachmentExtension;
            switch (extension.ToLowerCSafe())
            {
                case ".flv":
                    // Correct MIME type
                    mimeType = "video/x-flv";
                    break;
            }
        }

        // Set content type
        Response.ContentType = mimeType;
    }


    /// <summary>
    /// Gets the file ETag
    /// </summary>
    /// <param name="attachment">File</param>
    private static string GetFileETag(CMSOutputAttachment attachment)
    {
        // Prepare etag
        string etag = attachment.CultureCode.ToLowerCSafe();
        if (attachment.Attachment != null)
        {
            etag += "|" + attachment.Attachment.AttachmentGUID + "|" + attachment.Attachment.AttachmentLastModified.ToUniversalTime();
        }

        if (attachment.IsSecured)
        {
            // For secured files, add user name to etag
            etag += "|" + RequestContext.UserName;
        }

        etag += "|" + PortalContext.ViewMode;

        // Put etag into ""
        etag = "\"" + etag + "\"";

        return etag;
    }


    /// <summary>
    /// Processes the attachment.
    /// </summary>
    protected void ProcessAttachment()
    {
        outputAttachment = null;

        // If guid given, process the attachment
        guid = QueryHelper.GetGuid("guid", Guid.Empty);
        allowLatestVersion = CheckAllowLatestVersion();

        if (guid != Guid.Empty)
        {
            // Check version
            if (VersionHistoryID > 0)
            {
                ProcessFile(guid, VersionHistoryID);
            }
            else
            {
                ProcessFile(guid);
            }
        }
        else
        {
            // Get by node GUID
            nodeGuid = QueryHelper.GetGuid("nodeguid", Guid.Empty);
            if (nodeGuid != Guid.Empty)
            {
                // If node GUID given, process the file
                ProcessNode(nodeGuid);
            }
            else
            {
                // Get by alias path and file name
                aliasPath = QueryHelper.GetString("aliaspath", null);
                fileName = QueryHelper.GetString("filename", null);
                if (aliasPath != null)
                {
                    ProcessNode(aliasPath, fileName);
                }
            }
        }

        // If chset specified, do not cache
        string chset = QueryHelper.GetString("chset", null);
        if (chset != null)
        {
            mIsLatestVersion = true;
        }
    }


    /// <summary>
    /// Processes the specified file and returns the data to the output stream.
    /// </summary>
    /// <param name="attachmentGuid">Attachment guid</param>
    protected void ProcessFile(Guid attachmentGuid)
    {
        AttachmentInfo atInfo;

        bool requiresData = true;

        // Check if it is necessary to load the file data
        if (useClientCache && IsLiveSite && AllowClientCache)
        {
            // If possibly cached by client, do not load data (may not be sent)
            string ifModifiedString = Request.Headers["If-Modified-Since"];
            if (ifModifiedString != null)
            {
                requiresData = false;
            }
        }

        // If output data available from cache, do not require loading the data
        byte[] cachedData = GetCachedOutputData();
        if (cachedData != null)
        {
            requiresData = false;
        }

        // Get AttachmentInfo object
        if (!IsLiveSite)
        {
            // Not livesite mode - get latest version
            if (node != null)
            {
                atInfo = DocumentHelper.GetAttachment(node, attachmentGuid, TreeProvider);
            }
            else
            {
                atInfo = DocumentHelper.GetAttachment(attachmentGuid, TreeProvider, CurrentSiteName);
            }
        }
        else
        {
            if (!requiresData || AttachmentInfoProvider.StoreFilesInFileSystem(CurrentSiteName))
            {
                // Do not require data from DB - Not necessary or available from file system
                atInfo = AttachmentInfoProvider.GetAttachmentInfoWithoutBinary(attachmentGuid, CurrentSiteName);
            }
            else
            {
                // Require data from DB - Stored in DB
                atInfo = AttachmentInfoProvider.GetAttachmentInfo(attachmentGuid, CurrentSiteName);
            }

            // If attachment not found, 
            if (allowLatestVersion && ((atInfo == null) || (latestForHistoryId > 0) || (atInfo.AttachmentDocumentID == latestForDocumentId)))
            {
                // Get latest version
                if (node != null)
                {
                    atInfo = DocumentHelper.GetAttachment(node, attachmentGuid, TreeProvider);
                }
                else
                {
                    atInfo = DocumentHelper.GetAttachment(attachmentGuid, TreeProvider, CurrentSiteName);
                }

                // If not attachment for the required document, do not return
                if ((atInfo.AttachmentDocumentID != latestForDocumentId) && (latestForHistoryId == 0))
                {
                    atInfo = null;
                }
                else
                {
                    mIsLatestVersion = true;
                }
            }
        }

        if (atInfo != null)
        {
            // Temporary attachment is always latest version
            if (atInfo.AttachmentFormGUID != Guid.Empty)
            {
                mIsLatestVersion = true;
            }

            // Check if current mimetype is allowed
            if (!CheckRequiredMimeType(atInfo))
            {
                return;
            }

            bool checkPublishedFiles = AttachmentInfoProvider.CheckPublishedFiles(CurrentSiteName);
            bool checkFilesPermissions = AttachmentInfoProvider.CheckFilesPermissions(CurrentSiteName);

            // Get the document node
            if ((node == null) && (checkPublishedFiles || checkFilesPermissions))
            {
                // Try to get data from cache
                using (var cs = new CachedSection<TreeNode>(ref node, CacheMinutes, !allowLatestVersion, null, "getfilenodebydocumentid", atInfo.AttachmentDocumentID))
                {
                    if (cs.LoadData)
                    {
                        // Get the document
                        node = TreeProvider.SelectSingleDocument(atInfo.AttachmentDocumentID, false);

                        // Cache the document
                        CacheNode(cs, node);
                    }
                }
            }

            bool secured = false;
            if ((node != null) && checkFilesPermissions)
            {
                secured = (node.IsSecuredNode == 1);

                // Check secured pages
                if (secured)
                {
                    PageSecurityHelper.CheckSecuredAreas(CurrentSiteName, false, ViewMode);
                }
                if (node.RequiresSSL == 1)
                {
                    PageSecurityHelper.RequestSecurePage(false, node.RequiresSSL, ViewMode, CurrentSiteName);
                }

                // Check permissions
                bool checkPermissions = false;
                switch (PageSecurityHelper.CheckPagePermissions(CurrentSiteName))
                {
                    case PageLocationEnum.All:
                        checkPermissions = true;
                        break;

                    case PageLocationEnum.SecuredAreas:
                        checkPermissions = secured;
                        break;
                }

                // Check the read permission for the page
                if (checkPermissions)
                {
                    if (CurrentUser.IsAuthorizedPerDocument(node, NodePermissionsEnum.Read) == AuthorizationResultEnum.Denied)
                    {
                        URLHelper.Redirect(PageSecurityHelper.AccessDeniedPageURL(CurrentSiteName));
                    }
                }
            }


            bool resizeImage = (ImageHelper.IsImage(atInfo.AttachmentExtension) && AttachmentInfoProvider.CanResizeImage(atInfo, Width, Height, MaxSideSize));

            // If the file should be redirected, redirect the file
            if (!mIsLatestVersion && IsLiveSite && SettingsKeyInfoProvider.GetBoolValue(CurrentSiteName + ".CMSRedirectFilesToDisk"))
            {
                if (AttachmentInfoProvider.StoreFilesInFileSystem(CurrentSiteName))
                {
                    string path;
                    if (!resizeImage)
                    {
                        path = AttachmentInfoProvider.GetFilePhysicalURL(CurrentSiteName, atInfo.AttachmentGUID.ToString(), atInfo.AttachmentExtension);
                    }
                    else
                    {
                        int[] newDim = ImageHelper.EnsureImageDimensions(Width, Height, MaxSideSize, atInfo.AttachmentImageWidth, atInfo.AttachmentImageHeight);
                        path = AttachmentInfoProvider.GetFilePhysicalURL(CurrentSiteName, atInfo.AttachmentGUID.ToString(), atInfo.AttachmentExtension, newDim[0], newDim[1]);
                    }

                    // If path is valid, redirect
                    if (path != null)
                    {
                        // Check if file exists
                        string filePath = Server.MapPath(path);
                        if (File.Exists(filePath))
                        {
                            outputAttachment = NewOutputFile();
                            outputAttachment.IsSecured = secured;
                            outputAttachment.RedirectTo = path;
                            outputAttachment.Attachment = atInfo;
                        }
                    }
                }
            }

            // Get the data
            if ((outputAttachment == null) || (outputAttachment.Attachment == null))
            {
                outputAttachment = NewOutputFile(atInfo, null);
                outputAttachment.Width = Width;
                outputAttachment.Height = Height;
                outputAttachment.MaxSideSize = MaxSideSize;
                outputAttachment.SiteName = CurrentSiteName;
                outputAttachment.Resized = resizeImage;

                // Load the data if required
                if (requiresData)
                {
                    // Try to get the physical file, if not latest version
                    if (!mIsLatestVersion)
                    {
                        EnsurePhysicalFile(outputAttachment);
                    }
                    bool loadData = string.IsNullOrEmpty(outputAttachment.PhysicalFile);

                    // Load data if necessary
                    if (loadData)
                    {
                        if (atInfo.AttachmentBinary != null)
                        {
                            // Load from the attachment
                            outputAttachment.LoadData(atInfo.AttachmentBinary);
                        }
                        else
                        {
                            // Load from the disk
                            byte[] data = AttachmentInfoProvider.GetFile(atInfo, CurrentSiteName);
                            outputAttachment.LoadData(data);
                        }

                        // Save data to the cache, if not latest version
                        if (!mIsLatestVersion && (CacheMinutes > 0))
                        {
                            SaveOutputDataToCache(outputAttachment.OutputData, GetOutputDataDependency(outputAttachment.Attachment));
                        }
                    }
                }
                else if (cachedData != null)
                {
                    // Load the cached data if available
                    outputAttachment.OutputData = cachedData;
                }
            }

            if (outputAttachment != null)
            {
                outputAttachment.IsSecured = secured;

                // Add node data
                if (node != null)
                {
                    outputAttachment.AliasPath = node.NodeAliasPath;
                    outputAttachment.CultureCode = node.DocumentCulture;
                    outputAttachment.FileNode = node;

                    // Set the file validity
                    if (IsLiveSite && !mIsLatestVersion && checkPublishedFiles)
                    {
                        outputAttachment.ValidFrom = ValidationHelper.GetDateTime(node.GetValue("DocumentPublishFrom"), DateTime.MinValue);
                        outputAttachment.ValidTo = ValidationHelper.GetDateTime(node.GetValue("DocumentPublishTo"), DateTime.MaxValue);

                        // Set the published flag                   
                        outputAttachment.IsPublished = node.IsPublished;
                    }
                }
            }
        }
    }


    /// <summary>
    /// Processes the specified document node.
    /// </summary>
    /// <param name="currentAliasPath">Alias path</param>
    /// <param name="currentFileName">File name</param>
    protected void ProcessNode(string currentAliasPath, string currentFileName)
    {
        // Load the document node
        if (node == null)
        {
            // Try to get data from cache
            using (var cs = new CachedSection<TreeNode>(ref node, CacheMinutes, !allowLatestVersion, null, "getfilenodebyaliaspath|", CurrentSiteName, CacheHelper.GetBaseCacheKey(false, true), currentAliasPath))
            {
                if (cs.LoadData)
                {
                    // Get the document
                    string className = null;
                    bool combineWithDefaultCulture = SettingsKeyInfoProvider.GetBoolValue(CurrentSiteName + ".CMSCombineImagesWithDefaultCulture");
                    string culture = CultureCode;

                    // Get the document
                    if (currentFileName == null)
                    {
                        // CMS.File
                        className = "CMS.File";
                    }

                    // Get the document data
                    if (!IsLiveSite)
                    {
                        node = DocumentHelper.GetDocument(CurrentSiteName, currentAliasPath, culture, combineWithDefaultCulture, className, null, null, -1, false, null, TreeProvider);
                    }
                    else
                    {
                        node = TreeProvider.SelectSingleNode(CurrentSiteName, currentAliasPath, culture, combineWithDefaultCulture, className, null, null, -1, false);

                        // Documents should be combined with default culture
                        if ((node != null) && combineWithDefaultCulture && !node.IsPublished)
                        {
                            // Try to find published document in default culture
                            string defaultCulture = CultureHelper.GetDefaultCultureCode(CurrentSiteName);
                            TreeNode cultureNode = TreeProvider.SelectSingleNode(CurrentSiteName, currentAliasPath, defaultCulture, false, className, null, null, -1, false);
                            if ((cultureNode != null) && cultureNode.IsPublished)
                            {
                                node = cultureNode;
                            }
                        }
                    }

                    // Try to find node using the document aliases
                    if (node == null)
                    {
                        DataSet ds = DocumentAliasInfoProvider.GetDocumentAliases()
                                                                .TopN(1)
                                                                .Columns("AliasNodeID", "AliasCulture")
                                                                .WhereEquals("AliasURLPath", currentAliasPath)
                                                                .OrderByDescending("AliasCulture");
                        if (!DataHelper.DataSourceIsEmpty(ds))
                        {
                            DataRow dr = ds.Tables[0].Rows[0];
                            int nodeId = (int)dr["AliasNodeID"];
                            string nodeCulture = ValidationHelper.GetString(DataHelper.GetDataRowValue(dr, "AliasCulture"), null);
                            if (!IsLiveSite)
                            {
                                node = DocumentHelper.GetDocument(nodeId, nodeCulture, combineWithDefaultCulture, TreeProvider);
                            }
                            else
                            {
                                node = TreeProvider.SelectSingleNode(nodeId, nodeCulture, combineWithDefaultCulture);

                                // Documents should be combined with default culture
                                if ((node != null) && combineWithDefaultCulture && !node.IsPublished)
                                {
                                    // Try to find published document in default culture
                                    string defaultCulture = CultureHelper.GetDefaultCultureCode(CurrentSiteName);
                                    TreeNode cultureNode = TreeProvider.SelectSingleNode(nodeId, defaultCulture, false);
                                    if ((cultureNode != null) && cultureNode.IsPublished)
                                    {
                                        node = cultureNode;
                                    }
                                }
                            }
                        }
                    }

                    // Cache the document
                    CacheNode(cs, node);
                }
            }
        }

        // Process the document
        ProcessNode(node, null, currentFileName);
    }


    /// <summary>
    /// Processes the specified document node.
    /// </summary>
    /// <param name="currentNodeGuid">Node GUID</param>
    protected void ProcessNode(Guid currentNodeGuid)
    {
        // Load the document node
        string columnName = QueryHelper.GetString("columnName", String.Empty);
        if (node == null)
        {
            // Try to get data from cache
            using (var cs = new CachedSection<TreeNode>(ref node, CacheMinutes, !allowLatestVersion, null, "getfilenodebyguid|", CurrentSiteName, CacheHelper.GetBaseCacheKey(false, true), currentNodeGuid))
            {
                if (cs.LoadData)
                {
                    // Get the document
                    bool combineWithDefaultCulture = SettingsKeyInfoProvider.GetBoolValue(CurrentSiteName + ".CMSCombineImagesWithDefaultCulture");
                    string culture = CultureCode;
                    string where = "NodeGUID = '" + currentNodeGuid + "'";

                    // Get the document
                    string className = null;
                    if (columnName == "")
                    {
                        // CMS.File
                        className = "CMS.File";
                    }
                    else
                    {
                        // Other document types
                        TreeNode srcNode = TreeProvider.SelectSingleNode(currentNodeGuid, CultureCode, CurrentSiteName);
                        if (srcNode != null)
                        {
                            className = srcNode.NodeClassName;
                        }
                    }

                    // Get the document data
                    if (!IsLiveSite || allowLatestVersion)
                    {
                        node = DocumentHelper.GetDocument(CurrentSiteName, null, culture, combineWithDefaultCulture, className, where, null, -1, false, null, TreeProvider);
                    }
                    else
                    {
                        node = TreeProvider.SelectSingleNode(CurrentSiteName, null, culture, combineWithDefaultCulture, className, where, null, -1, false);

                        // Documents should be combined with default culture
                        if ((node != null) && combineWithDefaultCulture && !node.IsPublished)
                        {
                            // Try to find published document in default culture
                            string defaultCulture = CultureHelper.GetDefaultCultureCode(CurrentSiteName);
                            TreeNode cultureNode = TreeProvider.SelectSingleNode(CurrentSiteName, null, defaultCulture, false, className, where, null, -1, false);
                            if ((cultureNode != null) && cultureNode.IsPublished)
                            {
                                node = cultureNode;
                            }
                        }
                    }

                    // Cache the document
                    CacheNode(cs, node);
                }
            }
        }

        // Process the document node
        ProcessNode(node, columnName, null);
    }


    /// <summary>
    /// Processes the specified document node.
    /// </summary>
    /// <param name="treeNode">Document node to process</param>
    /// <param name="columnName">Column name</param>
    /// <param name="processedFileName">File name</param>
    protected void ProcessNode(TreeNode treeNode, string columnName, string processedFileName)
    {
        if (treeNode != null)
        {
            // Check if latest or live site version is required
            bool latest = !IsLiveSite;
            if (allowLatestVersion && ((treeNode.DocumentID == latestForDocumentId) || (treeNode.DocumentCheckedOutVersionHistoryID == latestForHistoryId)))
            {
                latest = true;
            }

            // If not published, return no content
            if (!latest && !treeNode.IsPublished)
            {
                outputAttachment = NewOutputFile(null, null);
                outputAttachment.AliasPath = treeNode.NodeAliasPath;
                outputAttachment.CultureCode = treeNode.DocumentCulture;
                if (IsLiveSite && AttachmentInfoProvider.CheckPublishedFiles(CurrentSiteName))
                {
                    outputAttachment.IsPublished = treeNode.IsPublished;
                }
                outputAttachment.FileNode = treeNode;
                outputAttachment.Height = Height;
                outputAttachment.Width = Width;
                outputAttachment.MaxSideSize = MaxSideSize;
            }
            else
            {
                // Get valid site name if link
                if (treeNode.IsLink)
                {
                    TreeNode origNode = TreeProvider.GetOriginalNode(treeNode);
                    if (origNode != null)
                    {
                        SiteInfo si = SiteInfoProvider.GetSiteInfo(origNode.NodeSiteID);
                        if (si != null)
                        {
                            CurrentSiteName = si.SiteName;
                        }
                    }
                }

                // Process the node
                // Get from specific column
                if (String.IsNullOrEmpty(columnName) && String.IsNullOrEmpty(processedFileName) && treeNode.NodeClassName.EqualsCSafe("CMS.File", true))
                {
                    columnName = "FileAttachment";
                }
                if (!String.IsNullOrEmpty(columnName))
                {
                    // File document type or specified by column
                    Guid attachmentGuid = ValidationHelper.GetGuid(treeNode.GetValue(columnName), Guid.Empty);
                    if (attachmentGuid != Guid.Empty)
                    {
                        ProcessFile(attachmentGuid);
                    }
                }
                else
                {
                    // Get by file name
                    if (processedFileName == null)
                    {
                        // CMS.File - Get 
                        Guid attachmentGuid = ValidationHelper.GetGuid(treeNode.GetValue("FileAttachment"), Guid.Empty);
                        if (attachmentGuid != Guid.Empty)
                        {
                            ProcessFile(attachmentGuid);
                        }
                    }
                    else
                    {
                        // Other document types, get the attachment by file name
                        AttachmentInfo ai;
                        if (latest)
                        {
                            // Not livesite mode - get latest version
                            ai = DocumentHelper.GetAttachment(treeNode, processedFileName, TreeProvider, false);
                        }
                        else
                        {
                            // Live site mode, get directly from database
                            ai = AttachmentInfoProvider.GetAttachmentInfo(treeNode.DocumentID, processedFileName, false);
                        }

                        if (ai != null)
                        {
                            ProcessFile(ai.AttachmentGUID);
                        }
                    }
                }
            }
        }
    }


    /// <summary>
    /// Processes the specified version of the file and returns the data to the output stream.
    /// </summary>
    /// <param name="attachmentGuid">Attachment GUID</param>
    /// <param name="versionHistoryId">Document version history ID</param>
    protected void ProcessFile(Guid attachmentGuid, int versionHistoryId)
    {
        AttachmentInfo atInfo = GetFile(attachmentGuid, versionHistoryId);
        if (atInfo != null)
        {
            // If attachment is image, try resize
            byte[] mFile = atInfo.AttachmentBinary;
            if (mFile != null)
            {
                string mimetype = null;
                if (ImageHelper.IsImage(atInfo.AttachmentExtension))
                {
                    if (AttachmentInfoProvider.CanResizeImage(atInfo, Width, Height, MaxSideSize))
                    {
                        // Do not search thumbnail on the disk
                        mFile = AttachmentInfoProvider.GetImageThumbnail(atInfo, CurrentSiteName, Width, Height, MaxSideSize, false);
                        mimetype = "image/jpeg";
                    }
                }

                if (mFile != null)
                {
                    outputAttachment = NewOutputFile(atInfo, mFile);
                }
                else
                {
                    outputAttachment = NewOutputFile();
                }
                outputAttachment.Height = Height;
                outputAttachment.Width = Width;
                outputAttachment.MaxSideSize = MaxSideSize;
                outputAttachment.MimeType = mimetype;
            }

            // Get the file document
            if (node == null)
            {
                node = TreeProvider.SelectSingleDocument(atInfo.AttachmentDocumentID);
            }

            if (node != null)
            {
                // Check secured area
                SiteInfo si = SiteInfoProvider.GetSiteInfo(node.NodeSiteID);
                if (si != null)
                {
                    if (pi == null)
                    {
                        pi = PageInfoProvider.GetPageInfo(si.SiteName, node.NodeAliasPath, node.DocumentCulture, node.DocumentUrlPath, false);
                    }
                    if (pi != null)
                    {
                        PageSecurityHelper.RequestSecurePage(pi, false, ViewMode, CurrentSiteName);
                        PageSecurityHelper.CheckSecuredAreas(CurrentSiteName, pi, false, ViewMode);
                    }
                }

                // Check the permissions for the document
                if ((CurrentUser.IsAuthorizedPerDocument(node, NodePermissionsEnum.Read) == AuthorizationResultEnum.Allowed) || (node.NodeOwner == CurrentUser.UserID))
                {
                    if (outputAttachment == null)
                    {
                        outputAttachment = NewOutputFile();
                    }

                    outputAttachment.AliasPath = node.NodeAliasPath;
                    outputAttachment.CultureCode = node.DocumentCulture;
                    if (IsLiveSite && AttachmentInfoProvider.CheckPublishedFiles(CurrentSiteName))
                    {
                        outputAttachment.IsPublished = node.IsPublished;
                    }
                    outputAttachment.FileNode = node;
                }
                else
                {
                    outputAttachment = null;
                }
            }
        }
    }


    /// <summary>
    /// Gets the file from version history.
    /// </summary>
    /// <param name="attachmentGuid">Atachment GUID</param>
    /// <param name="versionHistoryId">Version history ID</param>
    protected AttachmentInfo GetFile(Guid attachmentGuid, int versionHistoryId)
    {
        VersionManager vm = VersionManager.GetInstance(TreeProvider);

        // Get the attachment version
        AttachmentHistoryInfo attachmentVersion = vm.GetAttachmentVersion(versionHistoryId, attachmentGuid);
        if (attachmentVersion == null)
        {
            return null;
        }
        else
        {
            // Create the attachment object from the version
            AttachmentInfo ai = new AttachmentInfo(attachmentVersion.Generalized.DataClass);
            ai.AttachmentVersionHistoryID = versionHistoryId;
            return ai;
        }
    }


    /// <summary>
    /// Returns the output data dependency based on the given attachment record.
    /// </summary>
    /// <param name="ai">Attachment object</param>
    protected CMSCacheDependency GetOutputDataDependency(AttachmentInfo ai)
    {
        return (ai == null) ? null : CacheHelper.GetCacheDependency(AttachmentInfoProvider.GetDependencyCacheKeys(ai));
    }


    /// <summary>
    /// Returns the cache dependency for the given document node.
    /// </summary>
    /// <param name="document">Document node</param>
    protected CMSCacheDependency GetNodeDependency(TreeNode document)
    {
        string siteName = CurrentSiteName.ToLowerCSafe();

        return CacheHelper.GetCacheDependency(new[]
                                                  {
                                                      CacheHelper.FILENODE_KEY,
                                                      CacheHelper.FILENODE_KEY + "|" + siteName,
                                                      "node|" + siteName + "|" + document.NodeAliasPath.ToLowerCSafe()
                                                  });
    }


    /// <summary>
    /// Ensures the security settings in the given document node.
    /// </summary>
    /// <param name="document">Document node</param>
    protected void EnsureSecuritySettings(TreeNode document)
    {
        if (AttachmentInfoProvider.CheckFilesPermissions(CurrentSiteName))
        {
            // Load secured values
            document.LoadInheritedValues(new[] { "IsSecuredNode", "RequiresSSL" });
        }
    }


    /// <summary>
    /// Handles the document caching actions.
    /// </summary>
    /// <param name="cs">Cached section</param>
    /// <param name="document">Document node</param>
    protected void CacheNode(CachedSection<TreeNode> cs, TreeNode document)
    {
        if (document != null)
        {
            // Load the security settings
            EnsureSecuritySettings(document);

            // Save to the cache
            if (cs.Cached)
            {
                cs.CacheDependency = GetNodeDependency(document);
            }
        }
        else
        {
            // Do not cache in case not cached
            cs.CacheMinutes = 0;
        }

        cs.Data = document;
    }


    /// <summary>
    /// Logs analytics and/or activity event.
    /// </summary>
    /// <param name="attachment">File to be sent</param>
    protected void LogEvent(CMSOutputAttachment attachment)
    {
        if (IsLiveSite && (attachment != null) && (attachment.FileNode != null) && (attachment.FileNode.NodeClassName.ToLowerCSafe() == "cms.file"))
        {
            // Check if request is multipart request and log event if not
            GetRange(100, HttpContext.Current);  // GetRange() parses request header and sets 'IsMultipart' and 'IsRangeRequest' properties
            if (IsMultipart || IsRangeRequest)
            {
                return;
            }

            if (attachment.Attachment == null)
            {
                return;
            }

            // Log analytics hit
            if (AnalyticsHelper.IsLoggingEnabled(CurrentSiteName, String.Empty, LogExcludingFlags.SkipFileExtensionCheck) && AnalyticsHelper.TrackFileDownloadsEnabled(CurrentSiteName) && !AnalyticsHelper.IsFileExtensionExcluded(CurrentSiteName, attachment.Attachment.AttachmentExtension))
            {
                HitLogProvider.LogHit(HitLogProvider.FILE_DOWNLOADS, CurrentSiteName, attachment.FileNode.DocumentCulture, attachment.FileNode.NodeAliasPath, attachment.FileNode.NodeID);
            }

            // Log download activity
            if (LoggingActivityEnabled(attachment) && LogFileDownload(attachment))
            {
                Activity activity = new ActivityPageVisit(attachment.FileNode, attachment.FileNode.GetDocumentName(), null, null, AnalyticsContext.ActivityEnvironmentVariables);
                if (activity.Data != null)
                {
                    activity.Data.Value = attachment.Attachment.AttachmentName;
                    activity.Data.Culture = attachment.FileNode.DocumentCulture;
                    activity.Data.NodeID = attachment.FileNode.NodeID;
                    activity.Data.SiteID = SiteInfoProvider.GetSiteID(CurrentSiteName);
                    activity.Log();
                }
            }
        }
    }


    /// <summary>
    /// Checks if page visit activity logging is enabled, if so returns contact ID.
    /// </summary>
    /// <param name="attachment">File to be sent</param>
    protected bool LoggingActivityEnabled(CMSOutputAttachment attachment)
    {
        if ((attachment == null) || (attachment.FileNode == null))
        {
            return false;
        }

        // Check if logging is enabled
        if (ActivitySettingsHelper.ActivitiesEnabledAndModuleLoaded(CurrentSiteName) && ActivitySettingsHelper.ActivitiesEnabledForThisUser(CurrentUser))
        {
            if (attachment.Attachment != null)
            {
                // Get allowed extensions (if not specified log everything)
                bool doLog = true;
                string tracked = SettingsKeyInfoProvider.GetValue(CurrentSiteName + ".CMSActivityTrackedExtensions");
                if (!String.IsNullOrEmpty(tracked))
                {
                    string extension = attachment.Attachment.AttachmentExtension;
                    if (extension != null)
                    {
                        string extensions = String.Format(";{0};", tracked.ToLowerCSafe().Trim().Trim(';'));
                        extension = extension.TrimStart('.').ToLowerCSafe();
                        doLog = extensions.Contains(String.Format(";{0};", extension));
                    }
                }

                return doLog;
            }
        }
        return false;
    }


    /// <summary>
    /// Check if logging is enabled for current document.
    /// </summary>
    private bool LogFileDownload(CMSOutputAttachment attachment)
    {
        if ((attachment == null) || (attachment.FileNode == null))
        {
            return false;
        }

        return (((attachment.FileNode.DocumentLogVisitActivity == true)
             || (attachment.FileNode.DocumentLogVisitActivity == null)
             && ValidationHelper.GetBoolean(attachment.FileNode.GetInheritedValue("DocumentLogVisitActivity", false), false)));
    }


    /// <summary>
    /// Ensures the physical file.
    /// </summary>
    /// <param name="attachment">Output file</param>
    public bool EnsurePhysicalFile(CMSOutputAttachment attachment)
    {
        if (attachment == null)
        {
            return false;
        }

        // Try to link to file system
        if (String.IsNullOrEmpty(attachment.Watermark) && (attachment.Attachment != null) && (attachment.Attachment.AttachmentVersionHistoryID == 0) && AttachmentInfoProvider.StoreFilesInFileSystem(attachment.SiteName))
        {
            string filePath = AttachmentInfoProvider.EnsurePhysicalFile(attachment.Attachment, attachment.SiteName);
            if (filePath != null)
            {
                if (attachment.Resized)
                {
                    // If resized, ensure the thumbnail file
                    if (AttachmentInfoProvider.GenerateThumbnails(attachment.SiteName))
                    {
                        filePath = AttachmentInfoProvider.EnsureThumbnailFile(attachment.Attachment, attachment.SiteName, Width, Height, MaxSideSize);
                        if (filePath != null)
                        {
                            // Link to the physical file
                            attachment.PhysicalFile = filePath;
                            return true;
                        }
                    }
                }
                else
                {
                    // Link to the physical file
                    attachment.PhysicalFile = filePath;
                    return false;
                }
            }
        }

        attachment.PhysicalFile = "";
        return false;
    }


    /// <summary>
    /// Returns true if latest version of the document is allowed.
    /// </summary>
    public bool CheckAllowLatestVersion()
    {
        // Check if latest version is required
        latestForDocumentId = QueryHelper.GetInteger("latestfordocid", 0);
        latestForHistoryId = QueryHelper.GetInteger("latestforhistoryid", 0);

        if ((latestForDocumentId > 0) || (latestForHistoryId > 0))
        {
            // Validate the hash
            string hash = QueryHelper.GetString("hash", "");
            string validate = (latestForDocumentId > 0) ? "d" + latestForDocumentId : "h" + latestForHistoryId;

            if (!String.IsNullOrEmpty(hash) && QueryHelper.ValidateHashString(validate, hash))
            {
                return true;
            }
        }

        return false;
    }


    /// <summary>
    /// Gets the new output file object.
    /// </summary>
    public CMSOutputAttachment NewOutputFile()
    {
        CMSOutputAttachment attachment = new CMSOutputAttachment();

        attachment.Watermark = Watermark;
        attachment.WatermarkPosition = WatermarkPosition;

        return attachment;
    }


    /// <summary>
    /// Gets the new output file object.
    /// </summary>
    /// <param name="ai">AttachmentInfo</param>
    /// <param name="data">Output file data</param>
    public CMSOutputAttachment NewOutputFile(AttachmentInfo ai, byte[] data)
    {
        CMSOutputAttachment attachment = new CMSOutputAttachment(ai, data);

        attachment.Watermark = Watermark;
        attachment.WatermarkPosition = WatermarkPosition;

        return attachment;
    }
}