예제 #1
0
        /// <summary>
        /// Handle the request.
        /// </summary>
        /// <param name="context">HTTP context</param>
        /// <returns><see cref="ModuleResult.Stop"/> will stop all processing except <see cref="IHttpModule.EndRequest"/>.</returns>
        /// <remarks>Invoked in turn for all modules unless you return <see cref="ModuleResult.Stop"/>.</remarks>
        public ModuleResult HandleRequest(IHttpContext context)
        {
            // only handle GET and HEAD
            if (!context.Request.HttpMethod.ToUpper().Equals("GET")
                && !context.Request.HttpMethod.ToUpper().Equals("HEAD"))
                return ModuleResult.Continue;

            // serve a directory
            if (AllowListing)
            {
                if (TryGenerateDirectoryPage(context))
                    return ModuleResult.Stop;
            }

            var header = context.Request.Headers["If-Modified-Since"];

            var time = header != null
                           ? DateUtility.Parse(header)
                           : DateTime.MinValue;

            var fileContext = new FileContext(context.Request, time);
            _fileService.GetFile(fileContext);
            if (!fileContext.IsFound)
                return ModuleResult.Continue;

            if (!fileContext.IsModified)
            {
                context.Response.StatusCode = (int)HttpStatusCode.NotModified;
                context.Response.StatusDescription = "Was last modified " + fileContext.LastModifiedAtUtc.ToString("R");
                return ModuleResult.Stop;
            }

            string mimeType = MimeTypeProvider.Instance.Get(fileContext.Filename);
            if (mimeType == null)
            {
                context.Response.StatusCode = (int)HttpStatusCode.UnsupportedMediaType;
                context.Response.StatusDescription = string.Concat("File type '", Path.GetExtension(fileContext.Filename),"' is not supported.");
                return ModuleResult.Stop;
            }

            context.Response.AddHeader("Last-Modified", fileContext.LastModifiedAtUtc.ToString("R"));
            context.Response.AddHeader("Accept-Ranges", "bytes");
            context.Response.AddHeader("Content-Disposition", "inline;filename=\"" + Path.GetFileName(fileContext.Filename) + "\"");
            context.Response.ContentType = mimeType;
            context.Response.ContentLength = (int)fileContext.FileStream.Length;
            context.Response.Body = fileContext.FileStream;

            Logger.WriteDebug(this, "Sent File: " + fileContext.Filename);

            // Do not include a body when the client only want's to get content information.
            if (context.Request.HttpMethod.ToUpper().Equals("HEAD") && context.Response.Body != null)
            {
                context.Response.Body.Dispose();
                context.Response.Body = null;
            }
            return ModuleResult.Stop;
        }
예제 #2
0
        /// <summary>
        /// Execute the response result.
        /// </summary>
        /// <param name="context">HTTP controller context</param>
        /// <remarks>Invoked by <see cref="ControllerFactory"/> to process the response.</remarks>
        public override void ExecuteResult(IControllerContext context)
        {
            //Logger.WriteDebug(this, "Pipeline => ExecuteResult");

            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            // only handle GET and HEAD
            if (!context.HttpContext.Request.HttpMethod.ToUpper().Equals("GET")
                && !context.HttpContext.Request.HttpMethod.ToUpper().Equals("HEAD"))
                return;

            var header = context.HttpContext.Request.Headers["If-Modified-Since"];

            // TODO: Build reliable date parser
            var time = DateTime.MinValue;
            //var time = header != null
            //               ? ParseUtility.TryParseDateTime(header)
            //               : DateTime.MinValue;

            var fileContext = new FileContext(context.HttpContext.Request, time);
            _fileService.GetFile(fileContext,_fullFilePath);
            if (!fileContext.IsFound)
                return;

            if (!fileContext.IsModified)
            {
                context.HttpContext.Response.StatusCode = (int)HttpStatusCode.NotModified;
                context.HttpContext.Response.StatusDescription = "Was last modified " + fileContext.LastModifiedAtUtc.ToString("R");
                return;
            }

            var mimeType = MimeTypeProvider.Instance.Get(fileContext.Filename);
            if (mimeType == null)
            {
                context.HttpContext.Response.StatusCode = (int)HttpStatusCode.UnsupportedMediaType;
                context.HttpContext.Response.StatusDescription = string.Concat("File type '", Path.GetExtension(fileContext.Filename), "' is not supported.");
                return;
            }

            context.HttpContext.Response.AddHeader("Last-Modified", fileContext.LastModifiedAtUtc.ToString("R"));
            context.HttpContext.Response.AddHeader("Accept-Ranges", "bytes");
            context.HttpContext.Response.AddHeader("Content-Disposition", "inline;filename=\"" + Path.GetFileName(fileContext.Filename) + "\"");
            context.HttpContext.Response.ContentType = mimeType;
            context.HttpContext.Response.ContentLength = (int)fileContext.FileStream.Length;
            context.HttpContext.Response.Body = fileContext.FileStream;

            // Do not include a body when the client only want's to get content information.
            if (context.HttpContext.Request.HttpMethod.ToUpper().Equals("HEAD") && context.HttpContext.Response.Body != null)
            {
                context.HttpContext.Response.Body.Dispose();
                context.HttpContext.Response.Body = null;
            }
        }
예제 #3
0
 /// <summary>
 /// Get a file
 /// </summary>
 /// <param name="context">Context used to locate and return files</param>
 public virtual bool GetFile(FileContext context)
 {
     var fullPath = GetFullPath(context.Request.UriRewrite);
     return GetFile(context, fullPath);
 }
예제 #4
0
        /// <summary>
        /// Get a file
        /// </summary>
        /// <param name="context">Context used to locate and return files</param>
        /// <param name="fullPath">Full path used to locate files</param>
        public virtual bool GetFile(FileContext context, string fullPath)
        {
            if (fullPath == null || !File.Exists(fullPath))
                return false;

            FileInfo fi = new FileInfo(fullPath);
            var date = fi.LastWriteTimeUtc;

            // browser ignores second fractions
            date = date.AddTicks(-(date.Ticks % TimeSpan.TicksPerSecond));

            if (date <= context.BrowserCacheDate)
            {
                context.SetNotModified(fullPath, date);
                return true;
            }

            try
            {
                var stream = new FileStream(fullPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                context.SetFile(fullPath, stream, date);
                return true;
            }
            catch
            {
                return false;
            }
        }
예제 #5
0
        /// <summary>
        /// Execute the response result.
        /// </summary>
        /// <param name="context">HTTP controller context</param>
        /// <remarks>Invoked by <see cref="ControllerFactory"/> to process the response.</remarks>
        public override void ExecuteResult(IControllerContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            // only handle GET and HEAD
            if (!context.HttpContext.Request.HttpMethod.ToUpper().Equals("GET")
                && !context.HttpContext.Request.HttpMethod.ToUpper().Equals("HEAD"))
                return;

            var header = context.HttpContext.Request.Headers["If-Modified-Since"];

            // TODO: Build reliable date parser
            var time = DateTime.MinValue;
            //var time = header != null
            //               ? ParseUtility.TryParseDateTime(header)
            //               : DateTime.MinValue;

            var fileContext = new FileContext(context.HttpContext.Request, time);
            string fileNamePath = string.Concat(@"\winfs\",
                                    Constants.HTTP_WEB_ROOT_FOLDER, @"\",
                                    Constants.HTTP_WEB_VIEWS_FOLDER, @"\",
                                    context.ControllerName.Replace("Controller", String.Empty), @"\",
                                    context.ActionName, @".html");

            _fileService.GetFile(fileContext, fileNamePath);
            if (!fileContext.IsFound)
            {
                context.HttpContext.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
                context.HttpContext.Response.StatusDescription = string.Concat("Failed to find view '", fileContext.Filename, ".");
                return;
            }

            var mimeType = MimeTypeProvider.Instance.Get(fileContext.Filename);
            if (mimeType == null || mimeType != "text/html")
            {
                context.HttpContext.Response.StatusCode = (int)HttpStatusCode.UnsupportedMediaType;
                context.HttpContext.Response.StatusDescription = string.Concat("File type '", Path.GetExtension(fileContext.Filename), "' is not supported.");
                return;
            }

            context.HttpContext.Response.AddHeader("Last-Modified", fileContext.LastModifiedAtUtc.ToString("R"));
            context.HttpContext.Response.AddHeader("Accept-Ranges", "bytes");
            context.HttpContext.Response.AddHeader("Content-Disposition", "inline;filename=\"" + Path.GetFileName(fileContext.Filename) + "\"");
            context.HttpContext.Response.ContentType = mimeType;

            //  Parse tokens from file content
            using (StreamReader sr = new StreamReader(fileContext.FileStream))
            {
                TokenEngine content = new TokenEngine(sr.ReadToEnd(), context.ViewData);
                MemoryStream body = new MemoryStream(Encoding.UTF8.GetBytes(content.ToString()));
                context.HttpContext.Response.Body = body;
                context.HttpContext.Response.ContentLength = (int)body.Length;
            }

            // Do not include a body when the client only want's to get content information.
            if (context.HttpContext.Request.HttpMethod.ToUpper().Equals("HEAD") && context.HttpContext.Response.Body != null)
            {
                context.HttpContext.Response.Body.Dispose();
                context.HttpContext.Response.Body = null;
            }
        }