PageRenderTime 16ms CodeModel.GetById 8ms app.highlight 4ms RepoModel.GetById 1ms app.codeStats 1ms

/BlogEngine/DotNetSlave.BusinessLogic/Web/HttpHandlers/FileHandler.cs

#
C# | 162 lines | 88 code | 21 blank | 53 comment | 10 complexity | fa50ea20385162526a2fcb1b687b9c5a MD5 | raw file
  1namespace BlogEngine.Core.Web.HttpHandlers
  2{
  3    using System;
  4    using System.IO;
  5    using System.Web;
  6    using BlogEngine.Core.Providers;
  7
  8    /// <summary>
  9    /// The FileHandler serves all files that is uploaded from
 10    ///     the admin pages except for images.
 11    /// </summary>
 12    /// <remarks>
 13    /// By using a HttpHandler to serve files, it is very easy
 14    ///     to add the capability to stop bandwidth leeching or
 15    ///     to create a statistics analysis feature upon it.
 16    /// </remarks>
 17    public class FileHandler : IHttpHandler
 18    {
 19        #region Events
 20
 21        /// <summary>
 22        ///     Occurs when the requested file does not exist;
 23        /// </summary>
 24        public static event EventHandler<EventArgs> BadRequest;
 25
 26        /// <summary>
 27        ///     Occurs when a file is served;
 28        /// </summary>
 29        public static event EventHandler<EventArgs> Served;
 30
 31        /// <summary>
 32        ///     Occurs when the requested file does not exist;
 33        /// </summary>
 34        public static event EventHandler<EventArgs> Serving;
 35
 36        #endregion
 37
 38        #region Properties
 39
 40        /// <summary>
 41        ///     Gets a value indicating whether another request can use the <see cref = "T:System.Web.IHttpHandler"></see> instance.
 42        /// </summary>
 43        /// <value></value>
 44        /// <returns>true if the <see cref = "T:System.Web.IHttpHandler"></see> instance is reusable; otherwise, false.</returns>
 45        public bool IsReusable
 46        {
 47            get
 48            {
 49                return false;
 50            }
 51        }
 52
 53        #endregion
 54
 55        #region Implemented Interfaces
 56
 57        #region IHttpHandler
 58
 59        /// <summary>
 60        /// Enables processing of HTTP Web requests by a custom HttpHandler that 
 61        ///     implements the <see cref="T:System.Web.IHttpHandler"></see> interface.
 62        /// </summary>
 63        /// <param name="context">
 64        /// An <see cref="T:System.Web.HttpContext"></see> 
 65        ///     object that provides references to the intrinsic server objects 
 66        ///     (for example, Request, Response, Session, and Server) used to service HTTP requests.
 67        /// </param>
 68        public void ProcessRequest(HttpContext context)
 69        {
 70            if (!string.IsNullOrEmpty(context.Request.QueryString["file"]))
 71            {
 72                var fileName = context.Request.QueryString["file"];
 73                OnServing(fileName);
 74                fileName = !fileName.StartsWith("/") ? string.Format("/{0}", fileName) : fileName;
 75                try
 76                {
 77
 78                    var file = BlogService.GetFile(string.Format("{0}files{1}",Blog.CurrentInstance.StorageLocation, fileName));
 79                    if (file != null)
 80                    {
 81                        context.Response.AppendHeader("Content-Disposition", string.Format("inline; filename=\"{0}\"", file.Name));
 82                        SetContentType(context, file.Name);
 83                        if (Utils.SetConditionalGetHeaders(file.DateCreated.ToUniversalTime()))
 84                            return;
 85
 86                        context.Response.BinaryWrite(file.FileContents);
 87                        OnServed(fileName);
 88                    }
 89                    else
 90                    {
 91                        OnBadRequest(fileName);
 92                        context.Response.Redirect(string.Format("{0}error404.aspx", Utils.AbsoluteWebRoot));
 93                    }
 94                }
 95                catch (Exception)
 96                {
 97                    OnBadRequest(fileName);
 98                    context.Response.Redirect(string.Format("{0}error404.aspx", Utils.AbsoluteWebRoot));
 99                }
100            }
101        }
102
103        #endregion
104
105        #endregion
106
107        #region Methods
108
109        /// <summary>
110        /// Called when [bad request].
111        /// </summary>
112        /// <param name="file">The file name.</param>
113        private static void OnBadRequest(string file)
114        {
115            if (BadRequest != null)
116            {
117                BadRequest(file, EventArgs.Empty);
118            }
119        }
120
121        /// <summary>
122        /// Called when [served].
123        /// </summary>
124        /// <param name="file">The file name.</param>
125        private static void OnServed(string file)
126        {
127            if (Served != null)
128            {
129                Served(file, EventArgs.Empty);
130            }
131        }
132
133        /// <summary>
134        /// Called when [serving].
135        /// </summary>
136        /// <param name="file">The file name.</param>
137        private static void OnServing(string file)
138        {
139            if (Serving != null)
140            {
141                Serving(file, EventArgs.Empty);
142            }
143        }
144
145        /// <summary>
146        /// Sets the content type depending on the filename's extension.
147        /// </summary>
148        /// <param name="context">
149        /// The context.
150        /// </param>
151        /// <param name="fileName">
152        /// The file Name.
153        /// </param>
154        private static void SetContentType(HttpContext context, string fileName)
155        {
156            context.Response.AddHeader(
157                "Content-Type", fileName.EndsWith(".pdf") ? "application/pdf" : "application/octet-stream");
158        }
159
160        #endregion
161    }
162}